github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/daemon/reload.go (about)

     1  package daemon // import "github.com/docker/docker/daemon"
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  
     7  	"github.com/docker/docker/daemon/config"
     8  	"github.com/docker/docker/daemon/discovery"
     9  	"github.com/sirupsen/logrus"
    10  )
    11  
    12  // Reload reads configuration changes and modifies the
    13  // daemon according to those changes.
    14  // These are the settings that Reload changes:
    15  // - Platform runtime
    16  // - Daemon debug log level
    17  // - Daemon max concurrent downloads
    18  // - Daemon max concurrent uploads
    19  // - Daemon max download attempts
    20  // - Daemon shutdown timeout (in seconds)
    21  // - Cluster discovery (reconfigure and restart)
    22  // - Daemon labels
    23  // - Insecure registries
    24  // - Registry mirrors
    25  // - Daemon live restore
    26  func (daemon *Daemon) Reload(conf *config.Config) (err error) {
    27  	daemon.configStore.Lock()
    28  	attributes := map[string]string{}
    29  
    30  	defer func() {
    31  		jsonString, _ := json.Marshal(daemon.configStore)
    32  
    33  		// we're unlocking here, because
    34  		// LogDaemonEventWithAttributes() -> SystemInfo() -> GetAllRuntimes()
    35  		// holds that lock too.
    36  		daemon.configStore.Unlock()
    37  		if err == nil {
    38  			logrus.Infof("Reloaded configuration: %s", jsonString)
    39  			daemon.LogDaemonEventWithAttributes("reload", attributes)
    40  		}
    41  	}()
    42  
    43  	if err := daemon.reloadPlatform(conf, attributes); err != nil {
    44  		return err
    45  	}
    46  	daemon.reloadDebug(conf, attributes)
    47  	daemon.reloadMaxConcurrentDownloadsAndUploads(conf, attributes)
    48  	if err := daemon.reloadMaxDownloadAttempts(conf, attributes); err != nil {
    49  		return err
    50  	}
    51  	daemon.reloadShutdownTimeout(conf, attributes)
    52  	daemon.reloadFeatures(conf, attributes)
    53  
    54  	if err := daemon.reloadClusterDiscovery(conf, attributes); err != nil {
    55  		return err
    56  	}
    57  	if err := daemon.reloadLabels(conf, attributes); err != nil {
    58  		return err
    59  	}
    60  	if err := daemon.reloadAllowNondistributableArtifacts(conf, attributes); err != nil {
    61  		return err
    62  	}
    63  	if err := daemon.reloadInsecureRegistries(conf, attributes); err != nil {
    64  		return err
    65  	}
    66  	if err := daemon.reloadRegistryMirrors(conf, attributes); err != nil {
    67  		return err
    68  	}
    69  	if err := daemon.reloadLiveRestore(conf, attributes); err != nil {
    70  		return err
    71  	}
    72  	return daemon.reloadNetworkDiagnosticPort(conf, attributes)
    73  }
    74  
    75  // reloadDebug updates configuration with Debug option
    76  // and updates the passed attributes
    77  func (daemon *Daemon) reloadDebug(conf *config.Config, attributes map[string]string) {
    78  	// update corresponding configuration
    79  	if conf.IsValueSet("debug") {
    80  		daemon.configStore.Debug = conf.Debug
    81  	}
    82  	// prepare reload event attributes with updatable configurations
    83  	attributes["debug"] = fmt.Sprintf("%t", daemon.configStore.Debug)
    84  }
    85  
    86  // reloadMaxConcurrentDownloadsAndUploads updates configuration with max concurrent
    87  // download and upload options and updates the passed attributes
    88  func (daemon *Daemon) reloadMaxConcurrentDownloadsAndUploads(conf *config.Config, attributes map[string]string) {
    89  	// If no value is set for max-concurrent-downloads we assume it is the default value
    90  	// We always "reset" as the cost is lightweight and easy to maintain.
    91  	maxConcurrentDownloads := config.DefaultMaxConcurrentDownloads
    92  	if conf.IsValueSet("max-concurrent-downloads") && conf.MaxConcurrentDownloads != nil {
    93  		maxConcurrentDownloads = *conf.MaxConcurrentDownloads
    94  	}
    95  	daemon.configStore.MaxConcurrentDownloads = &maxConcurrentDownloads
    96  	logrus.Debugf("Reset Max Concurrent Downloads: %d", *daemon.configStore.MaxConcurrentDownloads)
    97  
    98  	// If no value is set for max-concurrent-upload we assume it is the default value
    99  	// We always "reset" as the cost is lightweight and easy to maintain.
   100  	maxConcurrentUploads := config.DefaultMaxConcurrentUploads
   101  	if conf.IsValueSet("max-concurrent-uploads") && conf.MaxConcurrentUploads != nil {
   102  		maxConcurrentUploads = *conf.MaxConcurrentUploads
   103  	}
   104  	daemon.configStore.MaxConcurrentUploads = &maxConcurrentUploads
   105  	logrus.Debugf("Reset Max Concurrent Uploads: %d", *daemon.configStore.MaxConcurrentUploads)
   106  
   107  	if daemon.imageService != nil {
   108  		daemon.imageService.UpdateConfig(&maxConcurrentDownloads, &maxConcurrentUploads)
   109  	}
   110  
   111  	// prepare reload event attributes with updatable configurations
   112  	attributes["max-concurrent-downloads"] = fmt.Sprintf("%d", *daemon.configStore.MaxConcurrentDownloads)
   113  	// prepare reload event attributes with updatable configurations
   114  	attributes["max-concurrent-uploads"] = fmt.Sprintf("%d", *daemon.configStore.MaxConcurrentUploads)
   115  }
   116  
   117  // reloadMaxDownloadAttempts updates configuration with max concurrent
   118  // download attempts when a connection is lost and updates the passed attributes
   119  func (daemon *Daemon) reloadMaxDownloadAttempts(conf *config.Config, attributes map[string]string) error {
   120  	if err := config.ValidateMaxDownloadAttempts(conf); err != nil {
   121  		return err
   122  	}
   123  
   124  	// If no value is set for max-download-attempts we assume it is the default value
   125  	// We always "reset" as the cost is lightweight and easy to maintain.
   126  	maxDownloadAttempts := config.DefaultDownloadAttempts
   127  	if conf.IsValueSet("max-download-attempts") && conf.MaxDownloadAttempts != nil {
   128  		maxDownloadAttempts = *conf.MaxDownloadAttempts
   129  	}
   130  	daemon.configStore.MaxDownloadAttempts = &maxDownloadAttempts
   131  	logrus.Debugf("Reset Max Download Attempts: %d", *daemon.configStore.MaxDownloadAttempts)
   132  
   133  	// prepare reload event attributes with updatable configurations
   134  	attributes["max-download-attempts"] = fmt.Sprintf("%d", *daemon.configStore.MaxDownloadAttempts)
   135  	return nil
   136  }
   137  
   138  // reloadShutdownTimeout updates configuration with daemon shutdown timeout option
   139  // and updates the passed attributes
   140  func (daemon *Daemon) reloadShutdownTimeout(conf *config.Config, attributes map[string]string) {
   141  	// update corresponding configuration
   142  	if conf.IsValueSet("shutdown-timeout") {
   143  		daemon.configStore.ShutdownTimeout = conf.ShutdownTimeout
   144  		logrus.Debugf("Reset Shutdown Timeout: %d", daemon.configStore.ShutdownTimeout)
   145  	}
   146  
   147  	// prepare reload event attributes with updatable configurations
   148  	attributes["shutdown-timeout"] = fmt.Sprintf("%d", daemon.configStore.ShutdownTimeout)
   149  }
   150  
   151  // reloadClusterDiscovery updates configuration with cluster discovery options
   152  // and updates the passed attributes
   153  func (daemon *Daemon) reloadClusterDiscovery(conf *config.Config, attributes map[string]string) (err error) {
   154  	defer func() {
   155  		// prepare reload event attributes with updatable configurations
   156  		attributes["cluster-store"] = conf.ClusterStore
   157  		attributes["cluster-advertise"] = conf.ClusterAdvertise
   158  
   159  		attributes["cluster-store-opts"] = "{}"
   160  		if daemon.configStore.ClusterOpts != nil {
   161  			opts, err2 := json.Marshal(conf.ClusterOpts)
   162  			if err != nil {
   163  				err = err2
   164  			}
   165  			attributes["cluster-store-opts"] = string(opts)
   166  		}
   167  	}()
   168  
   169  	newAdvertise := conf.ClusterAdvertise
   170  	newClusterStore := daemon.configStore.ClusterStore
   171  	if conf.IsValueSet("cluster-advertise") {
   172  		if conf.IsValueSet("cluster-store") {
   173  			newClusterStore = conf.ClusterStore
   174  		}
   175  		newAdvertise, err = config.ParseClusterAdvertiseSettings(newClusterStore, conf.ClusterAdvertise)
   176  		if err != nil && err != discovery.ErrDiscoveryDisabled {
   177  			return err
   178  		}
   179  	}
   180  
   181  	if daemon.clusterProvider != nil {
   182  		if err := conf.IsSwarmCompatible(); err != nil {
   183  			return err
   184  		}
   185  	}
   186  
   187  	// check discovery modifications
   188  	if !config.ModifiedDiscoverySettings(daemon.configStore, newClusterStore, newAdvertise, conf.ClusterOpts) {
   189  		return nil
   190  	}
   191  
   192  	// enable discovery for the first time if it was not previously enabled
   193  	if daemon.discoveryWatcher == nil {
   194  		discoveryWatcher, err := discovery.Init(newClusterStore, newAdvertise, conf.ClusterOpts)
   195  		if err != nil {
   196  			return fmt.Errorf("failed to initialize discovery: %v", err)
   197  		}
   198  		daemon.discoveryWatcher = discoveryWatcher
   199  	} else if err == discovery.ErrDiscoveryDisabled {
   200  		// disable discovery if it was previously enabled and it's disabled now
   201  		daemon.discoveryWatcher.Stop()
   202  	} else if err = daemon.discoveryWatcher.Reload(conf.ClusterStore, newAdvertise, conf.ClusterOpts); err != nil {
   203  		// reload discovery
   204  		return err
   205  	}
   206  
   207  	daemon.configStore.ClusterStore = newClusterStore
   208  	daemon.configStore.ClusterOpts = conf.ClusterOpts
   209  	daemon.configStore.ClusterAdvertise = newAdvertise
   210  
   211  	if daemon.netController == nil {
   212  		return nil
   213  	}
   214  	netOptions, err := daemon.networkOptions(daemon.configStore, daemon.PluginStore, nil)
   215  	if err != nil {
   216  		logrus.WithError(err).Warn("failed to get options with network controller")
   217  		return nil
   218  	}
   219  	err = daemon.netController.ReloadConfiguration(netOptions...)
   220  	if err != nil {
   221  		logrus.Warnf("Failed to reload configuration with network controller: %v", err)
   222  	}
   223  	return nil
   224  }
   225  
   226  // reloadLabels updates configuration with engine labels
   227  // and updates the passed attributes
   228  func (daemon *Daemon) reloadLabels(conf *config.Config, attributes map[string]string) error {
   229  	// update corresponding configuration
   230  	if conf.IsValueSet("labels") {
   231  		daemon.configStore.Labels = conf.Labels
   232  	}
   233  
   234  	// prepare reload event attributes with updatable configurations
   235  	if daemon.configStore.Labels != nil {
   236  		labels, err := json.Marshal(daemon.configStore.Labels)
   237  		if err != nil {
   238  			return err
   239  		}
   240  		attributes["labels"] = string(labels)
   241  	} else {
   242  		attributes["labels"] = "[]"
   243  	}
   244  
   245  	return nil
   246  }
   247  
   248  // reloadAllowNondistributableArtifacts updates the configuration with allow-nondistributable-artifacts options
   249  // and updates the passed attributes.
   250  func (daemon *Daemon) reloadAllowNondistributableArtifacts(conf *config.Config, attributes map[string]string) error {
   251  	// Update corresponding configuration.
   252  	if conf.IsValueSet("allow-nondistributable-artifacts") {
   253  		daemon.configStore.AllowNondistributableArtifacts = conf.AllowNondistributableArtifacts
   254  		if err := daemon.RegistryService.LoadAllowNondistributableArtifacts(conf.AllowNondistributableArtifacts); err != nil {
   255  			return err
   256  		}
   257  	}
   258  
   259  	// Prepare reload event attributes with updatable configurations.
   260  	if daemon.configStore.AllowNondistributableArtifacts != nil {
   261  		v, err := json.Marshal(daemon.configStore.AllowNondistributableArtifacts)
   262  		if err != nil {
   263  			return err
   264  		}
   265  		attributes["allow-nondistributable-artifacts"] = string(v)
   266  	} else {
   267  		attributes["allow-nondistributable-artifacts"] = "[]"
   268  	}
   269  
   270  	return nil
   271  }
   272  
   273  // reloadInsecureRegistries updates configuration with insecure registry option
   274  // and updates the passed attributes
   275  func (daemon *Daemon) reloadInsecureRegistries(conf *config.Config, attributes map[string]string) error {
   276  	// update corresponding configuration
   277  	if conf.IsValueSet("insecure-registries") {
   278  		daemon.configStore.InsecureRegistries = conf.InsecureRegistries
   279  		if err := daemon.RegistryService.LoadInsecureRegistries(conf.InsecureRegistries); err != nil {
   280  			return err
   281  		}
   282  	}
   283  
   284  	// prepare reload event attributes with updatable configurations
   285  	if daemon.configStore.InsecureRegistries != nil {
   286  		insecureRegistries, err := json.Marshal(daemon.configStore.InsecureRegistries)
   287  		if err != nil {
   288  			return err
   289  		}
   290  		attributes["insecure-registries"] = string(insecureRegistries)
   291  	} else {
   292  		attributes["insecure-registries"] = "[]"
   293  	}
   294  
   295  	return nil
   296  }
   297  
   298  // reloadRegistryMirrors updates configuration with registry mirror options
   299  // and updates the passed attributes
   300  func (daemon *Daemon) reloadRegistryMirrors(conf *config.Config, attributes map[string]string) error {
   301  	// update corresponding configuration
   302  	if conf.IsValueSet("registry-mirrors") {
   303  		daemon.configStore.Mirrors = conf.Mirrors
   304  		if err := daemon.RegistryService.LoadMirrors(conf.Mirrors); err != nil {
   305  			return err
   306  		}
   307  	}
   308  
   309  	// prepare reload event attributes with updatable configurations
   310  	if daemon.configStore.Mirrors != nil {
   311  		mirrors, err := json.Marshal(daemon.configStore.Mirrors)
   312  		if err != nil {
   313  			return err
   314  		}
   315  		attributes["registry-mirrors"] = string(mirrors)
   316  	} else {
   317  		attributes["registry-mirrors"] = "[]"
   318  	}
   319  
   320  	return nil
   321  }
   322  
   323  // reloadLiveRestore updates configuration with live restore option
   324  // and updates the passed attributes
   325  func (daemon *Daemon) reloadLiveRestore(conf *config.Config, attributes map[string]string) error {
   326  	// update corresponding configuration
   327  	if conf.IsValueSet("live-restore") {
   328  		daemon.configStore.LiveRestoreEnabled = conf.LiveRestoreEnabled
   329  	}
   330  
   331  	// prepare reload event attributes with updatable configurations
   332  	attributes["live-restore"] = fmt.Sprintf("%t", daemon.configStore.LiveRestoreEnabled)
   333  	return nil
   334  }
   335  
   336  // reloadNetworkDiagnosticPort updates the network controller starting the diagnostic if the config is valid
   337  func (daemon *Daemon) reloadNetworkDiagnosticPort(conf *config.Config, attributes map[string]string) error {
   338  	if conf == nil || daemon.netController == nil || !conf.IsValueSet("network-diagnostic-port") ||
   339  		conf.NetworkDiagnosticPort < 1 || conf.NetworkDiagnosticPort > 65535 {
   340  		// If there is no config make sure that the diagnostic is off
   341  		if daemon.netController != nil {
   342  			daemon.netController.StopDiagnostic()
   343  		}
   344  		return nil
   345  	}
   346  	// Enable the network diagnostic if the flag is set with a valid port within the range
   347  	logrus.WithFields(logrus.Fields{"port": conf.NetworkDiagnosticPort, "ip": "127.0.0.1"}).Warn("Starting network diagnostic server")
   348  	daemon.netController.StartDiagnostic(conf.NetworkDiagnosticPort)
   349  
   350  	return nil
   351  }
   352  
   353  // reloadFeatures updates configuration with enabled/disabled features
   354  func (daemon *Daemon) reloadFeatures(conf *config.Config, attributes map[string]string) {
   355  	// update corresponding configuration
   356  	// note that we allow features option to be entirely unset
   357  	daemon.configStore.Features = conf.Features
   358  
   359  	// prepare reload event attributes with updatable configurations
   360  	attributes["features"] = fmt.Sprintf("%v", daemon.configStore.Features)
   361  }