github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/daemon/reload.go (about)

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