github.com/mforkel/docker-ce-i386@v17.12.1-ce-rc2+incompatible/components/engine/daemon/reload.go (about)

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