diff --git a/cmd/dockerd/config.go b/cmd/dockerd/config.go new file mode 100644 index 0000000000..e2c8a1b773 --- /dev/null +++ b/cmd/dockerd/config.go @@ -0,0 +1,52 @@ +package main + +import ( + "github.com/docker/docker/daemon/config" + "github.com/docker/docker/opts" + "github.com/spf13/pflag" +) + +const ( + // defaultShutdownTimeout is the default shutdown timeout for the daemon + defaultShutdownTimeout = 15 +) + +// installCommonConfigFlags adds flags to the pflag.FlagSet to configure the daemon +func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) { + var maxConcurrentDownloads, maxConcurrentUploads int + + conf.ServiceOptions.InstallCliFlags(flags) + + flags.Var(opts.NewNamedListOptsRef("storage-opts", &conf.GraphOptions, nil), "storage-opt", "Storage driver options") + flags.Var(opts.NewNamedListOptsRef("authorization-plugins", &conf.AuthorizationPlugins, nil), "authorization-plugin", "Authorization plugins to load") + flags.Var(opts.NewNamedListOptsRef("exec-opts", &conf.ExecOptions, nil), "exec-opt", "Runtime execution options") + flags.StringVarP(&conf.Pidfile, "pidfile", "p", defaultPidFile, "Path to use for daemon PID file") + flags.StringVarP(&conf.Root, "graph", "g", defaultGraph, "Root of the Docker runtime") + flags.BoolVarP(&conf.AutoRestart, "restart", "r", true, "--restart on the daemon has been deprecated in favor of --restart policies on docker run") + flags.MarkDeprecated("restart", "Please use a restart policy on docker run") + flags.StringVarP(&conf.GraphDriver, "storage-driver", "s", "", "Storage driver to use") + flags.IntVar(&conf.Mtu, "mtu", 0, "Set the containers network MTU") + flags.BoolVar(&conf.RawLogs, "raw-logs", false, "Full timestamps without ANSI coloring") + // FIXME: why the inconsistency between "hosts" and "sockets"? + flags.Var(opts.NewListOptsRef(&conf.DNS, opts.ValidateIPAddress), "dns", "DNS server to use") + flags.Var(opts.NewNamedListOptsRef("dns-opts", &conf.DNSOptions, nil), "dns-opt", "DNS options to use") + flags.Var(opts.NewListOptsRef(&conf.DNSSearch, opts.ValidateDNSSearch), "dns-search", "DNS search domains to use") + flags.Var(opts.NewNamedListOptsRef("labels", &conf.Labels, opts.ValidateLabel), "label", "Set key=value labels to the daemon") + flags.StringVar(&conf.LogConfig.Type, "log-driver", "json-file", "Default driver for container logs") + flags.Var(opts.NewNamedMapOpts("log-opts", conf.LogConfig.Config, nil), "log-opt", "Default log driver options for containers") + flags.StringVar(&conf.ClusterAdvertise, "cluster-advertise", "", "Address or interface name to advertise") + flags.StringVar(&conf.ClusterStore, "cluster-store", "", "URL of the distributed storage backend") + flags.Var(opts.NewNamedMapOpts("cluster-store-opts", conf.ClusterOpts, nil), "cluster-store-opt", "Set cluster store options") + flags.StringVar(&conf.CorsHeaders, "api-cors-header", "", "Set CORS headers in the Engine API") + flags.IntVar(&maxConcurrentDownloads, "max-concurrent-downloads", config.DefaultMaxConcurrentDownloads, "Set the max concurrent downloads for each pull") + flags.IntVar(&maxConcurrentUploads, "max-concurrent-uploads", config.DefaultMaxConcurrentUploads, "Set the max concurrent uploads for each push") + flags.IntVar(&conf.ShutdownTimeout, "shutdown-timeout", defaultShutdownTimeout, "Set the default shutdown timeout") + + flags.StringVar(&conf.SwarmDefaultAdvertiseAddr, "swarm-default-advertise-addr", "", "Set default address or interface for swarm advertised address") + flags.BoolVar(&conf.Experimental, "experimental", false, "Enable experimental features") + + flags.StringVar(&conf.MetricsAddress, "metrics-addr", "", "Set default address and port to serve the metrics api on") + + conf.MaxConcurrentDownloads = &maxConcurrentDownloads + conf.MaxConcurrentUploads = &maxConcurrentUploads +} diff --git a/cmd/dockerd/config_common_unix.go b/cmd/dockerd/config_common_unix.go new file mode 100644 index 0000000000..6a668a4f03 --- /dev/null +++ b/cmd/dockerd/config_common_unix.go @@ -0,0 +1,34 @@ +// +build solaris linux freebsd + +package main + +import ( + "github.com/docker/docker/api/types" + "github.com/docker/docker/daemon/config" + "github.com/docker/docker/opts" + "github.com/spf13/pflag" +) + +var ( + defaultPidFile = "/var/run/docker.pid" + defaultGraph = "/var/lib/docker" + defaultExecRoot = "/var/run/docker" +) + +// installUnixConfigFlags adds command-line options to the top-level flag parser for +// the current process that are common across Unix platforms. +func installUnixConfigFlags(conf *config.Config, flags *pflag.FlagSet) { + conf.Runtimes = make(map[string]types.Runtime) + + flags.StringVarP(&conf.SocketGroup, "group", "G", "docker", "Group for the unix socket") + flags.StringVar(&conf.BridgeConfig.IP, "bip", "", "Specify network bridge IP") + flags.StringVarP(&conf.BridgeConfig.Iface, "bridge", "b", "", "Attach containers to a network bridge") + flags.StringVar(&conf.BridgeConfig.FixedCIDR, "fixed-cidr", "", "IPv4 subnet for fixed IPs") + flags.Var(opts.NewIPOpt(&conf.BridgeConfig.DefaultGatewayIPv4, ""), "default-gateway", "Container default gateway IPv4 address") + flags.Var(opts.NewIPOpt(&conf.BridgeConfig.DefaultGatewayIPv6, ""), "default-gateway-v6", "Container default gateway IPv6 address") + flags.BoolVar(&conf.BridgeConfig.InterContainerCommunication, "icc", true, "Enable inter-container communication") + flags.Var(opts.NewIPOpt(&conf.BridgeConfig.DefaultIP, "0.0.0.0"), "ip", "Default IP when binding container ports") + flags.Var(opts.NewNamedRuntimeOpt("runtimes", &conf.Runtimes, config.StockRuntimeName), "add-runtime", "Register an additional OCI compatible runtime") + flags.StringVar(&conf.DefaultRuntime, "default-runtime", config.StockRuntimeName, "Default OCI runtime for containers") + +} diff --git a/cmd/dockerd/config_experimental.go b/cmd/dockerd/config_experimental.go new file mode 100644 index 0000000000..355a29e859 --- /dev/null +++ b/cmd/dockerd/config_experimental.go @@ -0,0 +1,9 @@ +package main + +import ( + "github.com/docker/docker/daemon/config" + "github.com/spf13/pflag" +) + +func attachExperimentalFlags(conf *config.Config, cmd *pflag.FlagSet) { +} diff --git a/cmd/dockerd/config_solaris.go b/cmd/dockerd/config_solaris.go new file mode 100644 index 0000000000..582211c6c8 --- /dev/null +++ b/cmd/dockerd/config_solaris.go @@ -0,0 +1,19 @@ +package main + +import ( + "github.com/docker/docker/daemon/config" + runconfigopts "github.com/docker/docker/runconfig/opts" + units "github.com/docker/go-units" + "github.com/spf13/pflag" +) + +// installConfigFlags adds flags to the pflag.FlagSet to configure the daemon +func installConfigFlags(conf *config.Config, flags *pflag.FlagSet) { + // First handle install flags which are consistent cross-platform + installCommonConfigFlags(conf, flags) + + // Then install flags common to unix platforms + installUnixConfigFlags(conf, flags) + + attachExperimentalFlags(conf, flags) +} diff --git a/cmd/dockerd/config_unix.go b/cmd/dockerd/config_unix.go new file mode 100644 index 0000000000..d79f0b5c9a --- /dev/null +++ b/cmd/dockerd/config_unix.go @@ -0,0 +1,51 @@ +// +build linux,!solaris freebsd,!solaris + +package main + +import ( + "github.com/docker/docker/daemon/config" + "github.com/docker/docker/opts" + units "github.com/docker/go-units" + "github.com/spf13/pflag" +) + +// installConfigFlags adds flags to the pflag.FlagSet to configure the daemon +func installConfigFlags(conf *config.Config, flags *pflag.FlagSet) { + // First handle install flags which are consistent cross-platform + installCommonConfigFlags(conf, flags) + + // Then install flags common to unix platforms + installUnixConfigFlags(conf, flags) + + conf.Ulimits = make(map[string]*units.Ulimit) + + // Set default value for `--default-shm-size` + conf.ShmSize = opts.MemBytes(config.DefaultShmSize) + + // Then platform-specific install flags + flags.BoolVar(&conf.EnableSelinuxSupport, "selinux-enabled", false, "Enable selinux support") + flags.Var(opts.NewUlimitOpt(&conf.Ulimits), "default-ulimit", "Default ulimits for containers") + flags.BoolVar(&conf.BridgeConfig.EnableIPTables, "iptables", true, "Enable addition of iptables rules") + flags.BoolVar(&conf.BridgeConfig.EnableIPForward, "ip-forward", true, "Enable net.ipv4.ip_forward") + flags.BoolVar(&conf.BridgeConfig.EnableIPMasq, "ip-masq", true, "Enable IP masquerading") + flags.BoolVar(&conf.BridgeConfig.EnableIPv6, "ipv6", false, "Enable IPv6 networking") + flags.StringVar(&conf.ExecRoot, "exec-root", defaultExecRoot, "Root directory for execution state files") + flags.StringVar(&conf.BridgeConfig.FixedCIDRv6, "fixed-cidr-v6", "", "IPv6 subnet for fixed IPs") + flags.BoolVar(&conf.BridgeConfig.EnableUserlandProxy, "userland-proxy", true, "Use userland proxy for loopback traffic") + flags.StringVar(&conf.BridgeConfig.UserlandProxyPath, "userland-proxy-path", "", "Path to the userland proxy binary") + flags.BoolVar(&conf.EnableCors, "api-enable-cors", false, "Enable CORS headers in the Engine API, this is deprecated by --api-cors-header") + flags.MarkDeprecated("api-enable-cors", "Please use --api-cors-header") + flags.StringVar(&conf.CgroupParent, "cgroup-parent", "", "Set parent cgroup for all containers") + flags.StringVar(&conf.RemappedRoot, "userns-remap", "", "User/Group setting for user namespaces") + flags.StringVar(&conf.ContainerdAddr, "containerd", "", "Path to containerd socket") + flags.BoolVar(&conf.LiveRestoreEnabled, "live-restore", false, "Enable live restore of docker when containers are still running") + flags.IntVar(&conf.OOMScoreAdjust, "oom-score-adjust", -500, "Set the oom_score_adj for the daemon") + flags.BoolVar(&conf.Init, "init", false, "Run an init in the container to forward signals and reap processes") + flags.StringVar(&conf.InitPath, "init-path", "", "Path to the docker-init binary") + flags.Int64Var(&conf.CPURealtimePeriod, "cpu-rt-period", 0, "Limit the CPU real-time period in microseconds") + flags.Int64Var(&conf.CPURealtimeRuntime, "cpu-rt-runtime", 0, "Limit the CPU real-time runtime in microseconds") + flags.StringVar(&conf.SeccompProfile, "seccomp-profile", "", "Path to seccomp profile") + flags.Var(&conf.ShmSize, "default-shm-size", "Default shm size for containers") + + attachExperimentalFlags(conf, flags) +} diff --git a/cmd/dockerd/config_unix_test.go b/cmd/dockerd/config_unix_test.go new file mode 100644 index 0000000000..595b07263b --- /dev/null +++ b/cmd/dockerd/config_unix_test.go @@ -0,0 +1,32 @@ +// +build linux,!solaris freebsd,!solaris + +package main + +import ( + "runtime" + "testing" + + "github.com/docker/docker/daemon/config" + "github.com/docker/docker/pkg/testutil/assert" + "github.com/spf13/pflag" +) + +func TestDaemonParseShmSize(t *testing.T) { + if runtime.GOOS == "solaris" { + t.Skip("ShmSize not supported on Solaris\n") + } + flags := pflag.NewFlagSet("test", pflag.ContinueOnError) + + conf := &config.Config{} + installConfigFlags(conf, flags) + // By default `--default-shm-size=64M` + expectedValue := 64 * 1024 * 1024 + if conf.ShmSize.Value() != int64(expectedValue) { + t.Fatalf("expected default shm size %d, got %d", expectedValue, conf.ShmSize.Value()) + } + assert.NilError(t, flags.Set("default-shm-size", "128M")) + expectedValue = 128 * 1024 * 1024 + if conf.ShmSize.Value() != int64(expectedValue) { + t.Fatalf("expected default shm size %d, got %d", expectedValue, conf.ShmSize.Value()) + } +} diff --git a/cmd/dockerd/config_windows.go b/cmd/dockerd/config_windows.go new file mode 100644 index 0000000000..afb4794342 --- /dev/null +++ b/cmd/dockerd/config_windows.go @@ -0,0 +1,25 @@ +package main + +import ( + "os" + "path/filepath" + + "github.com/docker/docker/daemon/config" + "github.com/spf13/pflag" +) + +var ( + defaultPidFile string + defaultGraph = filepath.Join(os.Getenv("programdata"), "docker") +) + +// installConfigFlags adds flags to the pflag.FlagSet to configure the daemon +func installConfigFlags(conf *config.Config, flags *pflag.FlagSet) { + // First handle install flags which are consistent cross-platform + installCommonConfigFlags(conf, flags) + + // Then platform-specific install flags. + flags.StringVar(&conf.BridgeConfig.FixedCIDR, "fixed-cidr", "", "IPv4 subnet for fixed IPs") + flags.StringVarP(&conf.BridgeConfig.Iface, "bridge", "b", "", "Attach containers to a virtual switch") + flags.StringVarP(&conf.SocketGroup, "group", "G", "", "Users or groups that can access the named pipe") +} diff --git a/cmd/dockerd/daemon.go b/cmd/dockerd/daemon.go index ddc160d704..88dc247cf1 100644 --- a/cmd/dockerd/daemon.go +++ b/cmd/dockerd/daemon.go @@ -31,6 +31,7 @@ import ( cliflags "github.com/docker/docker/cli/flags" "github.com/docker/docker/daemon" "github.com/docker/docker/daemon/cluster" + "github.com/docker/docker/daemon/config" "github.com/docker/docker/daemon/logger" "github.com/docker/docker/dockerversion" "github.com/docker/docker/libcontainerd" @@ -54,7 +55,7 @@ const ( // DaemonCli represents the daemon CLI. type DaemonCli struct { - *daemon.Config + *config.Config configFile *string flags *pflag.FlagSet @@ -68,7 +69,7 @@ func NewDaemonCli() *DaemonCli { return &DaemonCli{} } -func migrateKey(config *daemon.Config) (err error) { +func migrateKey(config *config.Config) (err error) { // No migration necessary on Windows if runtime.GOOS == "windows" { return nil @@ -335,7 +336,7 @@ func (cli *DaemonCli) start(opts daemonOptions) (err error) { } func (cli *DaemonCli) reloadConfig() { - reload := func(config *daemon.Config) { + reload := func(config *config.Config) { // Revalidate and reload the authorization plugins if err := validateAuthzPlugins(config.AuthorizationPlugins, cli.d.PluginStore); err != nil { @@ -363,7 +364,7 @@ func (cli *DaemonCli) reloadConfig() { } } - if err := daemon.ReloadConfiguration(*cli.configFile, cli.flags, reload); err != nil { + if err := config.Reload(*cli.configFile, cli.flags, reload); err != nil { logrus.Error(err) } } @@ -395,24 +396,24 @@ func shutdownDaemon(d *daemon.Daemon) { } } -func loadDaemonCliConfig(opts daemonOptions) (*daemon.Config, error) { - config := opts.daemonConfig +func loadDaemonCliConfig(opts daemonOptions) (*config.Config, error) { + conf := opts.daemonConfig flags := opts.flags - config.Debug = opts.common.Debug - config.Hosts = opts.common.Hosts - config.LogLevel = opts.common.LogLevel - config.TLS = opts.common.TLS - config.TLSVerify = opts.common.TLSVerify - config.CommonTLSOptions = daemon.CommonTLSOptions{} + conf.Debug = opts.common.Debug + conf.Hosts = opts.common.Hosts + conf.LogLevel = opts.common.LogLevel + conf.TLS = opts.common.TLS + conf.TLSVerify = opts.common.TLSVerify + conf.CommonTLSOptions = config.CommonTLSOptions{} if opts.common.TLSOptions != nil { - config.CommonTLSOptions.CAFile = opts.common.TLSOptions.CAFile - config.CommonTLSOptions.CertFile = opts.common.TLSOptions.CertFile - config.CommonTLSOptions.KeyFile = opts.common.TLSOptions.KeyFile + conf.CommonTLSOptions.CAFile = opts.common.TLSOptions.CAFile + conf.CommonTLSOptions.CertFile = opts.common.TLSOptions.CertFile + conf.CommonTLSOptions.KeyFile = opts.common.TLSOptions.KeyFile } if opts.configFile != "" { - c, err := daemon.MergeDaemonConfigurations(config, flags, opts.configFile) + c, err := config.MergeDaemonConfigurations(conf, flags, opts.configFile) if err != nil { if flags.Changed(flagDaemonConfigFile) || !os.IsNotExist(err) { return nil, fmt.Errorf("unable to configure the Docker daemon with file %s: %v\n", opts.configFile, err) @@ -421,11 +422,11 @@ func loadDaemonCliConfig(opts daemonOptions) (*daemon.Config, error) { // the merged configuration can be nil if the config file didn't exist. // leave the current configuration as it is if when that happens. if c != nil { - config = c + conf = c } } - if err := daemon.ValidateConfiguration(config); err != nil { + if err := config.Validate(conf); err != nil { return nil, err } @@ -442,20 +443,20 @@ func loadDaemonCliConfig(opts daemonOptions) (*daemon.Config, error) { // } // config.Labels = newLabels // - if _, err := daemon.GetConflictFreeLabels(config.Labels); err != nil { + if _, err := config.GetConflictFreeLabels(conf.Labels); err != nil { logrus.Warnf("Engine labels with duplicate keys and conflicting values have been deprecated: %s", err) } // Regardless of whether the user sets it to true or false, if they // specify TLSVerify at all then we need to turn on TLS - if config.IsValueSet(cliflags.FlagTLSVerify) { - config.TLS = true + if conf.IsValueSet(cliflags.FlagTLSVerify) { + conf.TLS = true } // ensure that the log level is the one set after merging configurations - cliflags.SetLogLevel(config.LogLevel) + cliflags.SetLogLevel(conf.LogLevel) - return config, nil + return conf, nil } func initRouter(s *apiserver.Server, d *daemon.Daemon, c *cluster.Cluster) { diff --git a/cmd/dockerd/daemon_test.go b/cmd/dockerd/daemon_test.go index b364f87843..e38f4826c8 100644 --- a/cmd/dockerd/daemon_test.go +++ b/cmd/dockerd/daemon_test.go @@ -5,7 +5,7 @@ import ( "github.com/Sirupsen/logrus" cliflags "github.com/docker/docker/cli/flags" - "github.com/docker/docker/daemon" + "github.com/docker/docker/daemon/config" "github.com/docker/docker/pkg/testutil/assert" "github.com/docker/docker/pkg/testutil/tempfile" "github.com/spf13/pflag" @@ -13,12 +13,12 @@ import ( func defaultOptions(configFile string) daemonOptions { opts := daemonOptions{ - daemonConfig: &daemon.Config{}, + daemonConfig: &config.Config{}, flags: &pflag.FlagSet{}, common: cliflags.NewCommonOptions(), } opts.common.InstallFlags(opts.flags) - opts.daemonConfig.InstallFlags(opts.flags) + installConfigFlags(opts.daemonConfig, opts.flags) opts.flags.StringVar(&opts.configFile, flagDaemonConfigFile, defaultDaemonConfigFile, "") opts.configFile = configFile return opts diff --git a/cmd/dockerd/daemon_unix_test.go b/cmd/dockerd/daemon_unix_test.go index d66dba77e1..f757c52e24 100644 --- a/cmd/dockerd/daemon_unix_test.go +++ b/cmd/dockerd/daemon_unix_test.go @@ -6,10 +6,11 @@ package main import ( - "github.com/docker/docker/daemon" + "testing" + + "github.com/docker/docker/daemon/config" "github.com/docker/docker/pkg/testutil/assert" "github.com/docker/docker/pkg/testutil/tempfile" - "testing" ) func TestLoadDaemonCliConfigWithDaemonFlags(t *testing.T) { @@ -82,10 +83,10 @@ func TestLoadDaemonConfigWithTrueDefaultValues(t *testing.T) { // make sure reloading doesn't generate configuration // conflicts after normalizing boolean values. - reload := func(reloadedConfig *daemon.Config) { + reload := func(reloadedConfig *config.Config) { assert.Equal(t, reloadedConfig.EnableUserlandProxy, false) } - assert.NilError(t, daemon.ReloadConfiguration(opts.configFile, opts.flags, reload)) + assert.NilError(t, config.Reload(opts.configFile, opts.flags, reload)) } func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) { diff --git a/cmd/dockerd/docker.go b/cmd/dockerd/docker.go index 60742ae927..6d1674f147 100644 --- a/cmd/dockerd/docker.go +++ b/cmd/dockerd/docker.go @@ -9,7 +9,7 @@ import ( "github.com/Sirupsen/logrus" "github.com/docker/docker/cli" cliflags "github.com/docker/docker/cli/flags" - "github.com/docker/docker/daemon" + "github.com/docker/docker/daemon/config" "github.com/docker/docker/dockerversion" "github.com/docker/docker/pkg/reexec" "github.com/docker/docker/pkg/term" @@ -20,14 +20,14 @@ import ( type daemonOptions struct { version bool configFile string - daemonConfig *daemon.Config + daemonConfig *config.Config common *cliflags.CommonOptions flags *pflag.FlagSet } func newDaemonCommand() *cobra.Command { opts := daemonOptions{ - daemonConfig: daemon.NewConfig(), + daemonConfig: config.New(), common: cliflags.NewCommonOptions(), } @@ -48,7 +48,7 @@ func newDaemonCommand() *cobra.Command { flags.BoolVarP(&opts.version, "version", "v", false, "Print version information and quit") flags.StringVar(&opts.configFile, flagDaemonConfigFile, defaultDaemonConfigFile, "Daemon configuration file") opts.common.InstallFlags(flags) - opts.daemonConfig.InstallFlags(flags) + installConfigFlags(opts.daemonConfig, flags) installServiceFlags(flags) return cmd diff --git a/daemon/config.go b/daemon/config/config.go similarity index 75% rename from daemon/config.go rename to daemon/config/config.go index e6f64f710b..63a5fd3643 100644 --- a/daemon/config.go +++ b/daemon/config/config.go @@ -1,4 +1,4 @@ -package daemon +package config import ( "bytes" @@ -7,12 +7,14 @@ import ( "fmt" "io" "io/ioutil" + "reflect" "runtime" "sort" "strings" "sync" "github.com/Sirupsen/logrus" + daemondiscovery "github.com/docker/docker/daemon/discovery" "github.com/docker/docker/opts" "github.com/docker/docker/pkg/discovery" "github.com/docker/docker/registry" @@ -21,26 +23,23 @@ import ( ) const ( - // defaultMaxConcurrentDownloads is the default value for + // DefaultMaxConcurrentDownloads is the default value for // maximum number of downloads that // may take place at a time for each pull. - defaultMaxConcurrentDownloads = 3 - // defaultMaxConcurrentUploads is the default value for + DefaultMaxConcurrentDownloads = 3 + // DefaultMaxConcurrentUploads is the default value for // maximum number of uploads that // may take place at a time for each push. - defaultMaxConcurrentUploads = 5 - // stockRuntimeName is the reserved name/alias used to represent the + DefaultMaxConcurrentUploads = 5 + // StockRuntimeName is the reserved name/alias used to represent the // OCI runtime being shipped with the docker daemon package. - stockRuntimeName = "runc" -) - -const ( - defaultNetworkMtu = 1500 - disableNetworkBridge = "none" -) - -const ( - defaultShutdownTimeout = 15 + StockRuntimeName = "runc" + // DefaultShmSize is the default value for container's shm size + DefaultShmSize = int64(67108864) + // DefaultNetworkMtu is the default value for network MTU + DefaultNetworkMtu = 1500 + // DisableNetworkBridge is the default value of the option to disable network bridge + DisableNetworkBridge = "none" ) // flatOptions contains configuration keys @@ -151,67 +150,29 @@ type CommonConfig struct { MetricsAddress string `json:"metrics-addr"` LogConfig - bridgeConfig // bridgeConfig holds bridge network specific configuration. + BridgeConfig // bridgeConfig holds bridge network specific configuration. registry.ServiceOptions - reloadLock sync.Mutex - valuesSet map[string]interface{} + sync.Mutex + // FIXME(vdemeester) This part is not that clear and is mainly dependent on cli flags + // It should probably be handled outside this package. + ValuesSet map[string]interface{} Experimental bool `json:"experimental"` // Experimental indicates whether experimental features should be exposed or not } -// InstallCommonFlags adds flags to the pflag.FlagSet to configure the daemon -func (config *Config) InstallCommonFlags(flags *pflag.FlagSet) { - var maxConcurrentDownloads, maxConcurrentUploads int - - config.ServiceOptions.InstallCliFlags(flags) - - flags.Var(opts.NewNamedListOptsRef("storage-opts", &config.GraphOptions, nil), "storage-opt", "Storage driver options") - flags.Var(opts.NewNamedListOptsRef("authorization-plugins", &config.AuthorizationPlugins, nil), "authorization-plugin", "Authorization plugins to load") - flags.Var(opts.NewNamedListOptsRef("exec-opts", &config.ExecOptions, nil), "exec-opt", "Runtime execution options") - flags.StringVarP(&config.Pidfile, "pidfile", "p", defaultPidFile, "Path to use for daemon PID file") - flags.StringVarP(&config.Root, "graph", "g", defaultGraph, "Root of the Docker runtime") - flags.BoolVarP(&config.AutoRestart, "restart", "r", true, "--restart on the daemon has been deprecated in favor of --restart policies on docker run") - flags.MarkDeprecated("restart", "Please use a restart policy on docker run") - flags.StringVarP(&config.GraphDriver, "storage-driver", "s", "", "Storage driver to use") - flags.IntVar(&config.Mtu, "mtu", 0, "Set the containers network MTU") - flags.BoolVar(&config.RawLogs, "raw-logs", false, "Full timestamps without ANSI coloring") - // FIXME: why the inconsistency between "hosts" and "sockets"? - flags.Var(opts.NewListOptsRef(&config.DNS, opts.ValidateIPAddress), "dns", "DNS server to use") - flags.Var(opts.NewNamedListOptsRef("dns-opts", &config.DNSOptions, nil), "dns-opt", "DNS options to use") - flags.Var(opts.NewListOptsRef(&config.DNSSearch, opts.ValidateDNSSearch), "dns-search", "DNS search domains to use") - flags.Var(opts.NewNamedListOptsRef("labels", &config.Labels, opts.ValidateLabel), "label", "Set key=value labels to the daemon") - flags.StringVar(&config.LogConfig.Type, "log-driver", "json-file", "Default driver for container logs") - flags.Var(opts.NewNamedMapOpts("log-opts", config.LogConfig.Config, nil), "log-opt", "Default log driver options for containers") - flags.StringVar(&config.ClusterAdvertise, "cluster-advertise", "", "Address or interface name to advertise") - flags.StringVar(&config.ClusterStore, "cluster-store", "", "URL of the distributed storage backend") - flags.Var(opts.NewNamedMapOpts("cluster-store-opts", config.ClusterOpts, nil), "cluster-store-opt", "Set cluster store options") - flags.StringVar(&config.CorsHeaders, "api-cors-header", "", "Set CORS headers in the Engine API") - flags.IntVar(&maxConcurrentDownloads, "max-concurrent-downloads", defaultMaxConcurrentDownloads, "Set the max concurrent downloads for each pull") - flags.IntVar(&maxConcurrentUploads, "max-concurrent-uploads", defaultMaxConcurrentUploads, "Set the max concurrent uploads for each push") - flags.IntVar(&config.ShutdownTimeout, "shutdown-timeout", defaultShutdownTimeout, "Set the default shutdown timeout") - - flags.StringVar(&config.SwarmDefaultAdvertiseAddr, "swarm-default-advertise-addr", "", "Set default address or interface for swarm advertised address") - flags.BoolVar(&config.Experimental, "experimental", false, "Enable experimental features") - - flags.StringVar(&config.MetricsAddress, "metrics-addr", "", "Set default address and port to serve the metrics api on") - - config.MaxConcurrentDownloads = &maxConcurrentDownloads - config.MaxConcurrentUploads = &maxConcurrentUploads -} - // IsValueSet returns true if a configuration value // was explicitly set in the configuration file. -func (config *Config) IsValueSet(name string) bool { - if config.valuesSet == nil { +func (conf *Config) IsValueSet(name string) bool { + if conf.ValuesSet == nil { return false } - _, ok := config.valuesSet[name] + _, ok := conf.ValuesSet[name] return ok } -// NewConfig returns a new fully initialized Config struct -func NewConfig() *Config { +// New returns a new fully initialized Config struct +func New() *Config { config := Config{} config.LogConfig.Config = make(map[string]string) config.ClusterOpts = make(map[string]string) @@ -222,12 +183,13 @@ func NewConfig() *Config { return &config } -func parseClusterAdvertiseSettings(clusterStore, clusterAdvertise string) (string, error) { +// ParseClusterAdvertiseSettings parses the specified advertise settings +func ParseClusterAdvertiseSettings(clusterStore, clusterAdvertise string) (string, error) { if runtime.GOOS == "solaris" && (clusterAdvertise != "" || clusterStore != "") { return "", errors.New("Cluster Advertise Settings not supported on Solaris") } if clusterAdvertise == "" { - return "", errDiscoveryDisabled + return "", daemondiscovery.ErrDiscoveryDisabled } if clusterStore == "" { return "", errors.New("invalid cluster configuration. --cluster-advertise must be accompanied by --cluster-store configuration") @@ -264,15 +226,15 @@ func GetConflictFreeLabels(labels []string) ([]string, error) { return newLabels, nil } -// ReloadConfiguration reads the configuration in the host and reloads the daemon and server. -func ReloadConfiguration(configFile string, flags *pflag.FlagSet, reload func(*Config)) error { +// Reload reads the configuration in the host and reloads the daemon and server. +func Reload(configFile string, flags *pflag.FlagSet, reload func(*Config)) error { logrus.Infof("Got signal to reload configuration, reloading from: %s", configFile) newConfig, err := getConflictFreeConfiguration(configFile, flags) if err != nil { return err } - if err := ValidateConfiguration(newConfig); err != nil { + if err := Validate(newConfig); err != nil { return fmt.Errorf("file configuration validation failed (%v)", err) } @@ -313,7 +275,7 @@ func MergeDaemonConfigurations(flagsConfig *Config, flags *pflag.FlagSet, config return nil, err } - if err := ValidateConfiguration(fileConfig); err != nil { + if err := Validate(fileConfig); err != nil { return nil, fmt.Errorf("file configuration validation failed (%v)", err) } @@ -324,7 +286,7 @@ func MergeDaemonConfigurations(flagsConfig *Config, flags *pflag.FlagSet, config // We need to validate again once both fileConfig and flagsConfig // have been merged - if err := ValidateConfiguration(fileConfig); err != nil { + if err := Validate(fileConfig); err != nil { return nil, fmt.Errorf("file configuration validation failed (%v)", err) } @@ -385,7 +347,7 @@ func getConflictFreeConfiguration(configFile string, flags *pflag.FlagSet) (*Con }) } - config.valuesSet = configSet + config.ValuesSet = configSet } reader = bytes.NewReader(b) @@ -473,10 +435,10 @@ func findConfigurationConflicts(config map[string]interface{}, flags *pflag.Flag return nil } -// ValidateConfiguration validates some specific configs. +// Validate validates some specific configs. // such as config.DNS, config.Labels, config.DNSSearch, // as well as config.MaxConcurrentDownloads, config.MaxConcurrentUploads. -func ValidateConfiguration(config *Config) error { +func Validate(config *Config) error { // validate DNS for _, dns := range config.DNS { if _, err := opts.ValidateIPAddress(dns); err != nil { @@ -510,12 +472,12 @@ func ValidateConfiguration(config *Config) error { // validate that "default" runtime is not reset if runtimes := config.GetAllRuntimes(); len(runtimes) > 0 { - if _, ok := runtimes[stockRuntimeName]; ok { - return fmt.Errorf("runtime name '%s' is reserved", stockRuntimeName) + if _, ok := runtimes[StockRuntimeName]; ok { + return fmt.Errorf("runtime name '%s' is reserved", StockRuntimeName) } } - if defaultRuntime := config.GetDefaultRuntimeName(); defaultRuntime != "" && defaultRuntime != stockRuntimeName { + if defaultRuntime := config.GetDefaultRuntimeName(); defaultRuntime != "" && defaultRuntime != StockRuntimeName { runtimes := config.GetAllRuntimes() if _, ok := runtimes[defaultRuntime]; !ok { return fmt.Errorf("specified default runtime '%s' does not exist", defaultRuntime) @@ -526,14 +488,29 @@ func ValidateConfiguration(config *Config) error { } // GetAuthorizationPlugins returns daemon's sorted authorization plugins -func (config *Config) GetAuthorizationPlugins() []string { - config.reloadLock.Lock() - defer config.reloadLock.Unlock() +func (conf *Config) GetAuthorizationPlugins() []string { + conf.Lock() + defer conf.Unlock() - authPlugins := make([]string, 0, len(config.AuthorizationPlugins)) - for _, p := range config.AuthorizationPlugins { + authPlugins := make([]string, 0, len(conf.AuthorizationPlugins)) + for _, p := range conf.AuthorizationPlugins { authPlugins = append(authPlugins, p) } sort.Strings(authPlugins) return authPlugins } + +// ModifiedDiscoverySettings returns whether the discovery configuration has been modified or not. +func ModifiedDiscoverySettings(config *Config, backendType, advertise string, clusterOpts map[string]string) bool { + if config.ClusterStore != backendType || config.ClusterAdvertise != advertise { + return true + } + + if (config.ClusterOpts == nil && clusterOpts == nil) || + (config.ClusterOpts == nil && len(clusterOpts) == 0) || + (len(config.ClusterOpts) == 0 && clusterOpts == nil) { + return false + } + + return !reflect.DeepEqual(config.ClusterOpts, clusterOpts) +} diff --git a/daemon/config/config_common_unix.go b/daemon/config/config_common_unix.go new file mode 100644 index 0000000000..1afd381fbf --- /dev/null +++ b/daemon/config/config_common_unix.go @@ -0,0 +1,70 @@ +// +build solaris linux freebsd + +package config + +import ( + "net" + + "github.com/docker/docker/api/types" +) + +// CommonUnixConfig defines configuration of a docker daemon that is +// common across Unix platforms. +type CommonUnixConfig struct { + ExecRoot string `json:"exec-root,omitempty"` + ContainerdAddr string `json:"containerd,omitempty"` + Runtimes map[string]types.Runtime `json:"runtimes,omitempty"` + DefaultRuntime string `json:"default-runtime,omitempty"` + DefaultInitBinary string `json:"default-init,omitempty"` +} + +type commonUnixBridgeConfig struct { + DefaultIP net.IP `json:"ip,omitempty"` + IP string `json:"bip,omitempty"` + DefaultGatewayIPv4 net.IP `json:"default-gateway,omitempty"` + DefaultGatewayIPv6 net.IP `json:"default-gateway-v6,omitempty"` + InterContainerCommunication bool `json:"icc,omitempty"` +} + +// GetRuntime returns the runtime path and arguments for a given +// runtime name +func (conf *Config) GetRuntime(name string) *types.Runtime { + conf.Lock() + defer conf.Unlock() + if rt, ok := conf.Runtimes[name]; ok { + return &rt + } + return nil +} + +// GetDefaultRuntimeName returns the current default runtime +func (conf *Config) GetDefaultRuntimeName() string { + conf.Lock() + rt := conf.DefaultRuntime + conf.Unlock() + + return rt +} + +// GetAllRuntimes returns a copy of the runtimes map +func (conf *Config) GetAllRuntimes() map[string]types.Runtime { + conf.Lock() + rts := conf.Runtimes + conf.Unlock() + return rts +} + +// GetExecRoot returns the user configured Exec-root +func (conf *Config) GetExecRoot() string { + return conf.ExecRoot +} + +// GetInitPath returns the configure docker-init path +func (conf *Config) GetInitPath() string { + conf.Lock() + defer conf.Unlock() + if conf.InitPath != "" { + return conf.InitPath + } + return conf.DefaultInitBinary +} diff --git a/daemon/config/config_common_unix_test.go b/daemon/config/config_common_unix_test.go new file mode 100644 index 0000000000..707e1909aa --- /dev/null +++ b/daemon/config/config_common_unix_test.go @@ -0,0 +1,43 @@ +// +build !windows + +package config + +import ( + "testing" + + "github.com/docker/docker/api/types" +) + +func TestCommonUnixValidateConfigurationErrors(t *testing.T) { + testCases := []struct { + config *Config + }{ + // Can't override the stock runtime + { + config: &Config{ + CommonUnixConfig: CommonUnixConfig{ + Runtimes: map[string]types.Runtime{ + StockRuntimeName: {}, + }, + }, + }, + }, + // Default runtime should be present in runtimes + { + config: &Config{ + CommonUnixConfig: CommonUnixConfig{ + Runtimes: map[string]types.Runtime{ + "foo": {}, + }, + DefaultRuntime: "bar", + }, + }, + }, + } + for _, tc := range testCases { + err := Validate(tc.config) + if err == nil { + t.Fatalf("expected error, got nil for config %v", tc.config) + } + } +} diff --git a/daemon/config_solaris.go b/daemon/config/config_solaris.go similarity index 50% rename from daemon/config_solaris.go rename to daemon/config/config_solaris.go index bc18ccd7e4..30f20ad27c 100644 --- a/daemon/config_solaris.go +++ b/daemon/config/config_solaris.go @@ -1,4 +1,4 @@ -package daemon +package config import ( "github.com/spf13/pflag" @@ -20,28 +20,16 @@ type Config struct { CommonUnixConfig } -// bridgeConfig stores all the bridge driver specific +// BridgeConfig stores all the bridge driver specific // configuration. -type bridgeConfig struct { +type BridgeConfig struct { commonBridgeConfig // Fields below here are platform specific. commonUnixBridgeConfig } -// InstallFlags adds command-line options to the top-level flag parser for -// the current process. -func (config *Config) InstallFlags(flags *pflag.FlagSet) { - // First handle install flags which are consistent cross-platform - config.InstallCommonFlags(flags) - - // Then install flags common to unix platforms - config.InstallCommonUnixFlags(flags) - - // Then platform-specific install flags - config.attachExperimentalFlags(flags) -} - -func (config *Config) isSwarmCompatible() error { +// IsSwarmCompatible defines if swarm mode can be enabled in this config +func (conf *Config) IsSwarmCompatible() error { return nil } diff --git a/daemon/config_test.go b/daemon/config/config_test.go similarity index 54% rename from daemon/config_test.go rename to daemon/config/config_test.go index 90f6a1277f..5bddac650c 100644 --- a/daemon/config_test.go +++ b/daemon/config/config_test.go @@ -1,4 +1,4 @@ -package daemon +package config import ( "io/ioutil" @@ -7,6 +7,7 @@ import ( "strings" "testing" + "github.com/docker/docker/daemon/discovery" "github.com/docker/docker/opts" "github.com/docker/docker/pkg/testutil/assert" "github.com/spf13/pflag" @@ -39,17 +40,17 @@ func TestParseClusterAdvertiseSettings(t *testing.T) { if runtime.GOOS == "solaris" { t.Skip("ClusterSettings not supported on Solaris\n") } - _, err := parseClusterAdvertiseSettings("something", "") - if err != errDiscoveryDisabled { + _, err := ParseClusterAdvertiseSettings("something", "") + if err != discovery.ErrDiscoveryDisabled { t.Fatalf("expected discovery disabled error, got %v\n", err) } - _, err = parseClusterAdvertiseSettings("", "something") + _, err = ParseClusterAdvertiseSettings("", "something") if err == nil { t.Fatalf("expected discovery store error, got %v\n", err) } - _, err = parseClusterAdvertiseSettings("etcd", "127.0.0.1:8080") + _, err = ParseClusterAdvertiseSettings("etcd", "127.0.0.1:8080") if err != nil { t.Fatal(err) } @@ -160,70 +161,175 @@ func TestFindConfigurationConflictsWithMergedValues(t *testing.T) { } } -func TestValidateConfiguration(t *testing.T) { - c1 := &Config{ - CommonConfig: CommonConfig{ - Labels: []string{"one"}, +func TestValidateConfigurationErrors(t *testing.T) { + minusNumber := -10 + testCases := []struct { + config *Config + }{ + { + config: &Config{ + CommonConfig: CommonConfig{ + Labels: []string{"one"}, + }, + }, + }, + { + config: &Config{ + CommonConfig: CommonConfig{ + Labels: []string{"foo=bar", "one"}, + }, + }, + }, + { + config: &Config{ + CommonConfig: CommonConfig{ + DNS: []string{"1.1.1.1o"}, + }, + }, + }, + { + config: &Config{ + CommonConfig: CommonConfig{ + DNS: []string{"2.2.2.2", "1.1.1.1o"}, + }, + }, + }, + { + config: &Config{ + CommonConfig: CommonConfig{ + DNSSearch: []string{"123456"}, + }, + }, + }, + { + config: &Config{ + CommonConfig: CommonConfig{ + DNSSearch: []string{"a.b.c", "123456"}, + }, + }, + }, + { + config: &Config{ + CommonConfig: CommonConfig{ + MaxConcurrentDownloads: &minusNumber, + // This is weird... + ValuesSet: map[string]interface{}{ + "max-concurrent-downloads": -1, + }, + }, + }, + }, + { + config: &Config{ + CommonConfig: CommonConfig{ + MaxConcurrentUploads: &minusNumber, + // This is weird... + ValuesSet: map[string]interface{}{ + "max-concurrent-uploads": -1, + }, + }, + }, }, } - - err := ValidateConfiguration(c1) - if err == nil { - t.Fatal("expected error, got nil") - } - - c2 := &Config{ - CommonConfig: CommonConfig{ - Labels: []string{"one=two"}, - }, - } - - err = ValidateConfiguration(c2) - if err != nil { - t.Fatalf("expected no error, got error %v", err) - } - - c3 := &Config{ - CommonConfig: CommonConfig{ - DNS: []string{"1.1.1.1"}, - }, - } - - err = ValidateConfiguration(c3) - if err != nil { - t.Fatalf("expected no error, got error %v", err) - } - - c4 := &Config{ - CommonConfig: CommonConfig{ - DNS: []string{"1.1.1.1o"}, - }, - } - - err = ValidateConfiguration(c4) - if err == nil { - t.Fatal("expected error, got nil") - } - - c5 := &Config{ - CommonConfig: CommonConfig{ - DNSSearch: []string{"a.b.c"}, - }, - } - - err = ValidateConfiguration(c5) - if err != nil { - t.Fatalf("expected no error, got error %v", err) - } - - c6 := &Config{ - CommonConfig: CommonConfig{ - DNSSearch: []string{"123456"}, - }, - } - - err = ValidateConfiguration(c6) - if err == nil { - t.Fatal("expected error, got nil") + for _, tc := range testCases { + err := Validate(tc.config) + if err == nil { + t.Fatalf("expected error, got nil for config %v", tc.config) + } + } +} + +func TestValidateConfiguration(t *testing.T) { + testCases := []struct { + config *Config + }{ + { + config: &Config{ + CommonConfig: CommonConfig{ + Labels: []string{"one=two"}, + }, + }, + }, + { + config: &Config{ + CommonConfig: CommonConfig{ + DNS: []string{"1.1.1.1"}, + }, + }, + }, + { + config: &Config{ + CommonConfig: CommonConfig{ + DNSSearch: []string{"a.b.c"}, + }, + }, + }, + } + for _, tc := range testCases { + err := Validate(tc.config) + if err != nil { + t.Fatalf("expected no error, got error %v", err) + } + } +} + +func TestModifiedDiscoverySettings(t *testing.T) { + cases := []struct { + current *Config + modified *Config + expected bool + }{ + { + current: discoveryConfig("foo", "bar", map[string]string{}), + modified: discoveryConfig("foo", "bar", map[string]string{}), + expected: false, + }, + { + current: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}), + modified: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}), + expected: false, + }, + { + current: discoveryConfig("foo", "bar", map[string]string{}), + modified: discoveryConfig("foo", "bar", nil), + expected: false, + }, + { + current: discoveryConfig("foo", "bar", nil), + modified: discoveryConfig("foo", "bar", map[string]string{}), + expected: false, + }, + { + current: discoveryConfig("foo", "bar", nil), + modified: discoveryConfig("baz", "bar", nil), + expected: true, + }, + { + current: discoveryConfig("foo", "bar", nil), + modified: discoveryConfig("foo", "baz", nil), + expected: true, + }, + { + current: discoveryConfig("foo", "bar", nil), + modified: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}), + expected: true, + }, + } + + for _, c := range cases { + got := ModifiedDiscoverySettings(c.current, c.modified.ClusterStore, c.modified.ClusterAdvertise, c.modified.ClusterOpts) + if c.expected != got { + t.Fatalf("expected %v, got %v: current config %v, new config %v", c.expected, got, c.current, c.modified) + } + } +} + +func discoveryConfig(backendAddr, advertiseAddr string, opts map[string]string) *Config { + return &Config{ + CommonConfig: CommonConfig{ + ClusterStore: backendAddr, + ClusterAdvertise: advertiseAddr, + ClusterOpts: opts, + }, } } diff --git a/daemon/config/config_unix.go b/daemon/config/config_unix.go new file mode 100644 index 0000000000..f0f1fe8e57 --- /dev/null +++ b/daemon/config/config_unix.go @@ -0,0 +1,62 @@ +// +build linux freebsd + +package config + +import ( + "fmt" + + "github.com/docker/docker/opts" + units "github.com/docker/go-units" +) + +// Config defines the configuration of a docker daemon. +// It includes json tags to deserialize configuration from a file +// using the same names that the flags in the command line uses. +type Config struct { + CommonConfig + + // These fields are common to all unix platforms. + CommonUnixConfig + + // Fields below here are platform specific. + CgroupParent string `json:"cgroup-parent,omitempty"` + EnableSelinuxSupport bool `json:"selinux-enabled,omitempty"` + RemappedRoot string `json:"userns-remap,omitempty"` + Ulimits map[string]*units.Ulimit `json:"default-ulimits,omitempty"` + CPURealtimePeriod int64 `json:"cpu-rt-period,omitempty"` + CPURealtimeRuntime int64 `json:"cpu-rt-runtime,omitempty"` + OOMScoreAdjust int `json:"oom-score-adjust,omitempty"` + Init bool `json:"init,omitempty"` + InitPath string `json:"init-path,omitempty"` + SeccompProfile string `json:"seccomp-profile,omitempty"` + ShmSize opts.MemBytes `json:"default-shm-size,omitempty"` +} + +// BridgeConfig stores all the bridge driver specific +// configuration. +type BridgeConfig struct { + commonBridgeConfig + + // These fields are common to all unix platforms. + commonUnixBridgeConfig + + // Fields below here are platform specific. + EnableIPv6 bool `json:"ipv6,omitempty"` + EnableIPTables bool `json:"iptables,omitempty"` + EnableIPForward bool `json:"ip-forward,omitempty"` + EnableIPMasq bool `json:"ip-masq,omitempty"` + EnableUserlandProxy bool `json:"userland-proxy,omitempty"` + UserlandProxyPath string `json:"userland-proxy-path,omitempty"` + FixedCIDRv6 string `json:"fixed-cidr-v6,omitempty"` +} + +// IsSwarmCompatible defines if swarm mode can be enabled in this config +func (conf *Config) IsSwarmCompatible() error { + if conf.ClusterStore != "" || conf.ClusterAdvertise != "" { + return fmt.Errorf("--cluster-store and --cluster-advertise daemon configurations are incompatible with swarm mode") + } + if conf.LiveRestoreEnabled { + return fmt.Errorf("--live-restore daemon configuration is incompatible with swarm mode") + } + return nil +} diff --git a/daemon/config_unix_test.go b/daemon/config/config_unix_test.go similarity index 74% rename from daemon/config_unix_test.go rename to daemon/config/config_unix_test.go index 9e73bf430b..3e7d1be94a 100644 --- a/daemon/config_unix_test.go +++ b/daemon/config/config_unix_test.go @@ -1,15 +1,12 @@ // +build !windows -package daemon +package config import ( "io/ioutil" "runtime" "testing" - - "github.com/docker/docker/pkg/testutil/assert" - "github.com/spf13/pflag" ) func TestDaemonConfigurationMerge(t *testing.T) { @@ -84,26 +81,6 @@ func TestDaemonConfigurationMerge(t *testing.T) { } } -func TestDaemonParseShmSize(t *testing.T) { - if runtime.GOOS == "solaris" { - t.Skip("ShmSize not supported on Solaris\n") - } - flags := pflag.NewFlagSet("test", pflag.ContinueOnError) - - config := &Config{} - config.InstallFlags(flags) - // By default `--default-shm-size=64M` - expectedValue := 64 * 1024 * 1024 - if config.ShmSize.Value() != int64(expectedValue) { - t.Fatalf("expected default shm size %d, got %d", expectedValue, config.ShmSize.Value()) - } - assert.NilError(t, flags.Set("default-shm-size", "128M")) - expectedValue = 128 * 1024 * 1024 - if config.ShmSize.Value() != int64(expectedValue) { - t.Fatalf("expected default shm size %d, got %d", expectedValue, config.ShmSize.Value()) - } -} - func TestDaemonConfigurationMergeShmSize(t *testing.T) { if runtime.GOOS == "solaris" { t.Skip("ShmSize not supported on Solaris\n") diff --git a/daemon/config/config_windows.go b/daemon/config/config_windows.go new file mode 100644 index 0000000000..849acc1ac6 --- /dev/null +++ b/daemon/config/config_windows.go @@ -0,0 +1,52 @@ +package config + +import ( + "github.com/docker/docker/api/types" +) + +// BridgeConfig stores all the bridge driver specific +// configuration. +type BridgeConfig struct { + commonBridgeConfig +} + +// Config defines the configuration of a docker daemon. +// These are the configuration settings that you pass +// to the docker daemon when you launch it with say: `dockerd -e windows` +type Config struct { + CommonConfig + + // Fields below here are platform specific. (There are none presently + // for the Windows daemon.) +} + +// GetRuntime returns the runtime path and arguments for a given +// runtime name +func (conf *Config) GetRuntime(name string) *types.Runtime { + return nil +} + +// GetInitPath returns the configure docker-init path +func (conf *Config) GetInitPath() string { + return "" +} + +// GetDefaultRuntimeName returns the current default runtime +func (conf *Config) GetDefaultRuntimeName() string { + return StockRuntimeName +} + +// GetAllRuntimes returns a copy of the runtimes map +func (conf *Config) GetAllRuntimes() map[string]types.Runtime { + return map[string]types.Runtime{} +} + +// GetExecRoot returns the user configured Exec-root +func (conf *Config) GetExecRoot() string { + return "" +} + +// IsSwarmCompatible defines if swarm mode can be enabled in this config +func (conf *Config) IsSwarmCompatible() error { + return nil +} diff --git a/daemon/config_windows_test.go b/daemon/config/config_windows_test.go similarity index 98% rename from daemon/config_windows_test.go rename to daemon/config/config_windows_test.go index 4a7b95c17d..1c435c630a 100644 --- a/daemon/config_windows_test.go +++ b/daemon/config/config_windows_test.go @@ -1,6 +1,6 @@ // +build windows -package daemon +package config import ( "io/ioutil" diff --git a/daemon/config_common_unix.go b/daemon/config_common_unix.go deleted file mode 100644 index 5e20f84069..0000000000 --- a/daemon/config_common_unix.go +++ /dev/null @@ -1,89 +0,0 @@ -// +build solaris linux freebsd - -package daemon - -import ( - "net" - - "github.com/docker/docker/api/types" - "github.com/docker/docker/opts" - "github.com/spf13/pflag" -) - -// CommonUnixConfig defines configuration of a docker daemon that is -// common across Unix platforms. -type CommonUnixConfig struct { - ExecRoot string `json:"exec-root,omitempty"` - ContainerdAddr string `json:"containerd,omitempty"` - Runtimes map[string]types.Runtime `json:"runtimes,omitempty"` - DefaultRuntime string `json:"default-runtime,omitempty"` -} - -type commonUnixBridgeConfig struct { - DefaultIP net.IP `json:"ip,omitempty"` - IP string `json:"bip,omitempty"` - DefaultGatewayIPv4 net.IP `json:"default-gateway,omitempty"` - DefaultGatewayIPv6 net.IP `json:"default-gateway-v6,omitempty"` - InterContainerCommunication bool `json:"icc,omitempty"` -} - -// InstallCommonUnixFlags adds command-line options to the top-level flag parser for -// the current process that are common across Unix platforms. -func (config *Config) InstallCommonUnixFlags(flags *pflag.FlagSet) { - config.Runtimes = make(map[string]types.Runtime) - - flags.StringVarP(&config.SocketGroup, "group", "G", "docker", "Group for the unix socket") - flags.StringVar(&config.bridgeConfig.IP, "bip", "", "Specify network bridge IP") - flags.StringVarP(&config.bridgeConfig.Iface, "bridge", "b", "", "Attach containers to a network bridge") - flags.StringVar(&config.bridgeConfig.FixedCIDR, "fixed-cidr", "", "IPv4 subnet for fixed IPs") - flags.Var(opts.NewIPOpt(&config.bridgeConfig.DefaultGatewayIPv4, ""), "default-gateway", "Container default gateway IPv4 address") - flags.Var(opts.NewIPOpt(&config.bridgeConfig.DefaultGatewayIPv6, ""), "default-gateway-v6", "Container default gateway IPv6 address") - flags.BoolVar(&config.bridgeConfig.InterContainerCommunication, "icc", true, "Enable inter-container communication") - flags.Var(opts.NewIPOpt(&config.bridgeConfig.DefaultIP, "0.0.0.0"), "ip", "Default IP when binding container ports") - flags.Var(opts.NewNamedRuntimeOpt("runtimes", &config.Runtimes, stockRuntimeName), "add-runtime", "Register an additional OCI compatible runtime") - flags.StringVar(&config.DefaultRuntime, "default-runtime", stockRuntimeName, "Default OCI runtime for containers") - -} - -// GetRuntime returns the runtime path and arguments for a given -// runtime name -func (config *Config) GetRuntime(name string) *types.Runtime { - config.reloadLock.Lock() - defer config.reloadLock.Unlock() - if rt, ok := config.Runtimes[name]; ok { - return &rt - } - return nil -} - -// GetDefaultRuntimeName returns the current default runtime -func (config *Config) GetDefaultRuntimeName() string { - config.reloadLock.Lock() - rt := config.DefaultRuntime - config.reloadLock.Unlock() - - return rt -} - -// GetAllRuntimes returns a copy of the runtimes map -func (config *Config) GetAllRuntimes() map[string]types.Runtime { - config.reloadLock.Lock() - rts := config.Runtimes - config.reloadLock.Unlock() - return rts -} - -// GetExecRoot returns the user configured Exec-root -func (config *Config) GetExecRoot() string { - return config.ExecRoot -} - -// GetInitPath returns the configure docker-init path -func (config *Config) GetInitPath() string { - config.reloadLock.Lock() - defer config.reloadLock.Unlock() - if config.InitPath != "" { - return config.InitPath - } - return DefaultInitBinary -} diff --git a/daemon/config_experimental.go b/daemon/config_experimental.go deleted file mode 100644 index 963a51e5a3..0000000000 --- a/daemon/config_experimental.go +++ /dev/null @@ -1,8 +0,0 @@ -package daemon - -import ( - "github.com/spf13/pflag" -) - -func (config *Config) attachExperimentalFlags(cmd *pflag.FlagSet) { -} diff --git a/daemon/config_unix.go b/daemon/config_unix.go deleted file mode 100644 index 8f71c8e5e6..0000000000 --- a/daemon/config_unix.go +++ /dev/null @@ -1,110 +0,0 @@ -// +build linux freebsd - -package daemon - -import ( - "fmt" - - "github.com/docker/docker/opts" - units "github.com/docker/go-units" - "github.com/spf13/pflag" -) - -var ( - defaultPidFile = "/var/run/docker.pid" - defaultGraph = "/var/lib/docker" - defaultExecRoot = "/var/run/docker" - defaultShmSize = int64(67108864) -) - -// Config defines the configuration of a docker daemon. -// It includes json tags to deserialize configuration from a file -// using the same names that the flags in the command line uses. -type Config struct { - CommonConfig - - // These fields are common to all unix platforms. - CommonUnixConfig - - // Fields below here are platform specific. - CgroupParent string `json:"cgroup-parent,omitempty"` - EnableSelinuxSupport bool `json:"selinux-enabled,omitempty"` - RemappedRoot string `json:"userns-remap,omitempty"` - Ulimits map[string]*units.Ulimit `json:"default-ulimits,omitempty"` - CPURealtimePeriod int64 `json:"cpu-rt-period,omitempty"` - CPURealtimeRuntime int64 `json:"cpu-rt-runtime,omitempty"` - OOMScoreAdjust int `json:"oom-score-adjust,omitempty"` - Init bool `json:"init,omitempty"` - InitPath string `json:"init-path,omitempty"` - SeccompProfile string `json:"seccomp-profile,omitempty"` - ShmSize opts.MemBytes `json:"default-shm-size,omitempty"` -} - -// bridgeConfig stores all the bridge driver specific -// configuration. -type bridgeConfig struct { - commonBridgeConfig - - // These fields are common to all unix platforms. - commonUnixBridgeConfig - - // Fields below here are platform specific. - EnableIPv6 bool `json:"ipv6,omitempty"` - EnableIPTables bool `json:"iptables,omitempty"` - EnableIPForward bool `json:"ip-forward,omitempty"` - EnableIPMasq bool `json:"ip-masq,omitempty"` - EnableUserlandProxy bool `json:"userland-proxy,omitempty"` - UserlandProxyPath string `json:"userland-proxy-path,omitempty"` - FixedCIDRv6 string `json:"fixed-cidr-v6,omitempty"` -} - -// InstallFlags adds flags to the pflag.FlagSet to configure the daemon -func (config *Config) InstallFlags(flags *pflag.FlagSet) { - // First handle install flags which are consistent cross-platform - config.InstallCommonFlags(flags) - - // Then install flags common to unix platforms - config.InstallCommonUnixFlags(flags) - - config.Ulimits = make(map[string]*units.Ulimit) - - // Set default value for `--default-shm-size` - config.ShmSize = opts.MemBytes(defaultShmSize) - - // Then platform-specific install flags - flags.BoolVar(&config.EnableSelinuxSupport, "selinux-enabled", false, "Enable selinux support") - flags.Var(opts.NewUlimitOpt(&config.Ulimits), "default-ulimit", "Default ulimits for containers") - flags.BoolVar(&config.bridgeConfig.EnableIPTables, "iptables", true, "Enable addition of iptables rules") - flags.BoolVar(&config.bridgeConfig.EnableIPForward, "ip-forward", true, "Enable net.ipv4.ip_forward") - flags.BoolVar(&config.bridgeConfig.EnableIPMasq, "ip-masq", true, "Enable IP masquerading") - flags.BoolVar(&config.bridgeConfig.EnableIPv6, "ipv6", false, "Enable IPv6 networking") - flags.StringVar(&config.ExecRoot, "exec-root", defaultExecRoot, "Root directory for execution state files") - flags.StringVar(&config.bridgeConfig.FixedCIDRv6, "fixed-cidr-v6", "", "IPv6 subnet for fixed IPs") - flags.BoolVar(&config.bridgeConfig.EnableUserlandProxy, "userland-proxy", true, "Use userland proxy for loopback traffic") - flags.StringVar(&config.bridgeConfig.UserlandProxyPath, "userland-proxy-path", "", "Path to the userland proxy binary") - flags.BoolVar(&config.EnableCors, "api-enable-cors", false, "Enable CORS headers in the Engine API, this is deprecated by --api-cors-header") - flags.MarkDeprecated("api-enable-cors", "Please use --api-cors-header") - flags.StringVar(&config.CgroupParent, "cgroup-parent", "", "Set parent cgroup for all containers") - flags.StringVar(&config.RemappedRoot, "userns-remap", "", "User/Group setting for user namespaces") - flags.StringVar(&config.ContainerdAddr, "containerd", "", "Path to containerd socket") - flags.BoolVar(&config.LiveRestoreEnabled, "live-restore", false, "Enable live restore of docker when containers are still running") - flags.IntVar(&config.OOMScoreAdjust, "oom-score-adjust", -500, "Set the oom_score_adj for the daemon") - flags.BoolVar(&config.Init, "init", false, "Run an init in the container to forward signals and reap processes") - flags.StringVar(&config.InitPath, "init-path", "", "Path to the docker-init binary") - flags.Int64Var(&config.CPURealtimePeriod, "cpu-rt-period", 0, "Limit the CPU real-time period in microseconds") - flags.Int64Var(&config.CPURealtimeRuntime, "cpu-rt-runtime", 0, "Limit the CPU real-time runtime in microseconds") - flags.StringVar(&config.SeccompProfile, "seccomp-profile", "", "Path to seccomp profile") - flags.Var(&config.ShmSize, "default-shm-size", "Default shm size for containers") - - config.attachExperimentalFlags(flags) -} - -func (config *Config) isSwarmCompatible() error { - if config.ClusterStore != "" || config.ClusterAdvertise != "" { - return fmt.Errorf("--cluster-store and --cluster-advertise daemon configurations are incompatible with swarm mode") - } - if config.LiveRestoreEnabled { - return fmt.Errorf("--live-restore daemon configuration is incompatible with swarm mode") - } - return nil -} diff --git a/daemon/config_windows.go b/daemon/config_windows.go deleted file mode 100644 index ec3f84005c..0000000000 --- a/daemon/config_windows.go +++ /dev/null @@ -1,71 +0,0 @@ -package daemon - -import ( - "os" - "path/filepath" - - "github.com/docker/docker/api/types" - "github.com/spf13/pflag" -) - -var ( - defaultPidFile string - defaultGraph = filepath.Join(os.Getenv("programdata"), "docker") -) - -// bridgeConfig stores all the bridge driver specific -// configuration. -type bridgeConfig struct { - commonBridgeConfig -} - -// Config defines the configuration of a docker daemon. -// These are the configuration settings that you pass -// to the docker daemon when you launch it with say: `dockerd -e windows` -type Config struct { - CommonConfig - - // Fields below here are platform specific. (There are none presently - // for the Windows daemon.) -} - -// InstallFlags adds flags to the pflag.FlagSet to configure the daemon -func (config *Config) InstallFlags(flags *pflag.FlagSet) { - // First handle install flags which are consistent cross-platform - config.InstallCommonFlags(flags) - - // Then platform-specific install flags. - flags.StringVar(&config.bridgeConfig.FixedCIDR, "fixed-cidr", "", "IPv4 subnet for fixed IPs") - flags.StringVarP(&config.bridgeConfig.Iface, "bridge", "b", "", "Attach containers to a virtual switch") - flags.StringVarP(&config.SocketGroup, "group", "G", "", "Users or groups that can access the named pipe") -} - -// GetRuntime returns the runtime path and arguments for a given -// runtime name -func (config *Config) GetRuntime(name string) *types.Runtime { - return nil -} - -// GetInitPath returns the configure docker-init path -func (config *Config) GetInitPath() string { - return "" -} - -// GetDefaultRuntimeName returns the current default runtime -func (config *Config) GetDefaultRuntimeName() string { - return stockRuntimeName -} - -// GetAllRuntimes returns a copy of the runtimes map -func (config *Config) GetAllRuntimes() map[string]types.Runtime { - return map[string]types.Runtime{} -} - -// GetExecRoot returns the user configured Exec-root -func (config *Config) GetExecRoot() string { - return "" -} - -func (config *Config) isSwarmCompatible() error { - return nil -} diff --git a/daemon/container_operations.go b/daemon/container_operations.go index 3cad44106d..986c9ef10b 100644 --- a/daemon/container_operations.go +++ b/daemon/container_operations.go @@ -282,7 +282,7 @@ func (daemon *Daemon) updateEndpointNetworkSettings(container *container.Contain } if container.HostConfig.NetworkMode == runconfig.DefaultDaemonNetworkMode() { - container.NetworkSettings.Bridge = daemon.configStore.bridgeConfig.Iface + container.NetworkSettings.Bridge = daemon.configStore.BridgeConfig.Iface } return nil diff --git a/daemon/daemon.go b/daemon/daemon.go index 560b89a419..17846177c6 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -24,6 +24,8 @@ import ( "github.com/docker/docker/api/types" containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" + "github.com/docker/docker/daemon/config" + "github.com/docker/docker/daemon/discovery" "github.com/docker/docker/daemon/events" "github.com/docker/docker/daemon/exec" // register graph drivers @@ -82,14 +84,14 @@ type Daemon struct { distributionMetadataStore dmetadata.Store trustKey libtrust.PrivateKey idIndex *truncindex.TruncIndex - configStore *Config + configStore *config.Config statsCollector *stats.Collector defaultLogConfig containertypes.LogConfig RegistryService registry.Service EventsService *events.Events netController libnetwork.NetworkController volumes *store.VolumeStore - discoveryWatcher discoveryReloader + discoveryWatcher discovery.Reloader root string seccompEnabled bool apparmorEnabled bool @@ -459,12 +461,12 @@ func (daemon *Daemon) IsSwarmCompatible() error { if daemon.configStore == nil { return nil } - return daemon.configStore.isSwarmCompatible() + return daemon.configStore.IsSwarmCompatible() } // NewDaemon sets up everything for the daemon to be able to service // requests from the webserver. -func NewDaemon(config *Config, registryService registry.Service, containerdRemote libcontainerd.Remote) (daemon *Daemon, err error) { +func NewDaemon(config *config.Config, registryService registry.Service, containerdRemote libcontainerd.Remote) (daemon *Daemon, err error) { setDefaultMtu(config) // Ensure that we have a correct root key limit for launching containers. @@ -947,12 +949,12 @@ func (daemon *Daemon) setupInitLayer(initPath string) error { return initlayer.Setup(initPath, rootUID, rootGID) } -func setDefaultMtu(config *Config) { +func setDefaultMtu(conf *config.Config) { // do nothing if the config does not have the default 0 value. - if config.Mtu != 0 { + if conf.Mtu != 0 { return } - config.Mtu = defaultNetworkMtu + conf.Mtu = config.DefaultNetworkMtu } func (daemon *Daemon) configureVolumes(rootUID, rootGID int) (*store.VolumeStore, error) { @@ -975,17 +977,17 @@ func (daemon *Daemon) IsShuttingDown() bool { } // initDiscovery initializes the discovery watcher for this daemon. -func (daemon *Daemon) initDiscovery(config *Config) error { - advertise, err := parseClusterAdvertiseSettings(config.ClusterStore, config.ClusterAdvertise) +func (daemon *Daemon) initDiscovery(conf *config.Config) error { + advertise, err := config.ParseClusterAdvertiseSettings(conf.ClusterStore, conf.ClusterAdvertise) if err != nil { - if err == errDiscoveryDisabled { + if err == discovery.ErrDiscoveryDisabled { return nil } return err } - config.ClusterAdvertise = advertise - discoveryWatcher, err := initDiscovery(config.ClusterStore, config.ClusterAdvertise, config.ClusterOpts) + conf.ClusterAdvertise = advertise + discoveryWatcher, err := discovery.Init(conf.ClusterStore, conf.ClusterAdvertise, conf.ClusterOpts) if err != nil { return fmt.Errorf("discovery initialization failed (%v)", err) } @@ -1005,60 +1007,60 @@ func (daemon *Daemon) initDiscovery(config *Config) error { // - Daemon max concurrent uploads // - Cluster discovery (reconfigure and restart) // - Daemon live restore -// - Daemon shutdown timeout (in seconds) -func (daemon *Daemon) Reload(config *Config) (err error) { +// - Daemon shutdown timeout (in seconds). +func (daemon *Daemon) Reload(conf *config.Config) (err error) { - daemon.configStore.reloadLock.Lock() + daemon.configStore.Lock() - attributes := daemon.platformReload(config) + attributes := daemon.platformReload(conf) defer func() { // we're unlocking here, because // LogDaemonEventWithAttributes() -> SystemInfo() -> GetAllRuntimes() // holds that lock too. - daemon.configStore.reloadLock.Unlock() + daemon.configStore.Unlock() if err == nil { daemon.LogDaemonEventWithAttributes("reload", attributes) } }() - if err := daemon.reloadClusterDiscovery(config); err != nil { + if err := daemon.reloadClusterDiscovery(conf); err != nil { return err } - if config.IsValueSet("labels") { - daemon.configStore.Labels = config.Labels + if conf.IsValueSet("labels") { + daemon.configStore.Labels = conf.Labels } - if config.IsValueSet("debug") { - daemon.configStore.Debug = config.Debug + if conf.IsValueSet("debug") { + daemon.configStore.Debug = conf.Debug } - if config.IsValueSet("insecure-registries") { - daemon.configStore.InsecureRegistries = config.InsecureRegistries - if err := daemon.RegistryService.LoadInsecureRegistries(config.InsecureRegistries); err != nil { + if conf.IsValueSet("insecure-registries") { + daemon.configStore.InsecureRegistries = conf.InsecureRegistries + if err := daemon.RegistryService.LoadInsecureRegistries(conf.InsecureRegistries); err != nil { return err } } - if config.IsValueSet("registry-mirrors") { - daemon.configStore.Mirrors = config.Mirrors - if err := daemon.RegistryService.LoadMirrors(config.Mirrors); err != nil { + if conf.IsValueSet("registry-mirrors") { + daemon.configStore.Mirrors = conf.Mirrors + if err := daemon.RegistryService.LoadMirrors(conf.Mirrors); err != nil { return err } } - if config.IsValueSet("live-restore") { - daemon.configStore.LiveRestoreEnabled = config.LiveRestoreEnabled - if err := daemon.containerdRemote.UpdateOptions(libcontainerd.WithLiveRestore(config.LiveRestoreEnabled)); err != nil { + if conf.IsValueSet("live-restore") { + daemon.configStore.LiveRestoreEnabled = conf.LiveRestoreEnabled + if err := daemon.containerdRemote.UpdateOptions(libcontainerd.WithLiveRestore(conf.LiveRestoreEnabled)); err != nil { return err } } // If no value is set for max-concurrent-downloads we assume it is the default value // We always "reset" as the cost is lightweight and easy to maintain. - if config.IsValueSet("max-concurrent-downloads") && config.MaxConcurrentDownloads != nil { - *daemon.configStore.MaxConcurrentDownloads = *config.MaxConcurrentDownloads + if conf.IsValueSet("max-concurrent-downloads") && conf.MaxConcurrentDownloads != nil { + *daemon.configStore.MaxConcurrentDownloads = *conf.MaxConcurrentDownloads } else { - maxConcurrentDownloads := defaultMaxConcurrentDownloads + maxConcurrentDownloads := config.DefaultMaxConcurrentDownloads daemon.configStore.MaxConcurrentDownloads = &maxConcurrentDownloads } logrus.Debugf("Reset Max Concurrent Downloads: %d", *daemon.configStore.MaxConcurrentDownloads) @@ -1068,10 +1070,10 @@ func (daemon *Daemon) Reload(config *Config) (err error) { // If no value is set for max-concurrent-upload we assume it is the default value // We always "reset" as the cost is lightweight and easy to maintain. - if config.IsValueSet("max-concurrent-uploads") && config.MaxConcurrentUploads != nil { - *daemon.configStore.MaxConcurrentUploads = *config.MaxConcurrentUploads + if conf.IsValueSet("max-concurrent-uploads") && conf.MaxConcurrentUploads != nil { + *daemon.configStore.MaxConcurrentUploads = *conf.MaxConcurrentUploads } else { - maxConcurrentUploads := defaultMaxConcurrentUploads + maxConcurrentUploads := config.DefaultMaxConcurrentUploads daemon.configStore.MaxConcurrentUploads = &maxConcurrentUploads } logrus.Debugf("Reset Max Concurrent Uploads: %d", *daemon.configStore.MaxConcurrentUploads) @@ -1079,8 +1081,8 @@ func (daemon *Daemon) Reload(config *Config) (err error) { daemon.uploadManager.SetConcurrency(*daemon.configStore.MaxConcurrentUploads) } - if config.IsValueSet("shutdown-timeout") { - daemon.configStore.ShutdownTimeout = config.ShutdownTimeout + if conf.IsValueSet("shutdown-timeout") { + daemon.configStore.ShutdownTimeout = conf.ShutdownTimeout logrus.Debugf("Reset Shutdown Timeout: %d", daemon.configStore.ShutdownTimeout) } @@ -1137,52 +1139,52 @@ func (daemon *Daemon) Reload(config *Config) (err error) { return nil } -func (daemon *Daemon) reloadClusterDiscovery(config *Config) error { +func (daemon *Daemon) reloadClusterDiscovery(conf *config.Config) error { var err error newAdvertise := daemon.configStore.ClusterAdvertise newClusterStore := daemon.configStore.ClusterStore - if config.IsValueSet("cluster-advertise") { - if config.IsValueSet("cluster-store") { - newClusterStore = config.ClusterStore + if conf.IsValueSet("cluster-advertise") { + if conf.IsValueSet("cluster-store") { + newClusterStore = conf.ClusterStore } - newAdvertise, err = parseClusterAdvertiseSettings(newClusterStore, config.ClusterAdvertise) - if err != nil && err != errDiscoveryDisabled { + newAdvertise, err = config.ParseClusterAdvertiseSettings(newClusterStore, conf.ClusterAdvertise) + if err != nil && err != discovery.ErrDiscoveryDisabled { return err } } if daemon.clusterProvider != nil { - if err := config.isSwarmCompatible(); err != nil { + if err := conf.IsSwarmCompatible(); err != nil { return err } } // check discovery modifications - if !modifiedDiscoverySettings(daemon.configStore, newAdvertise, newClusterStore, config.ClusterOpts) { + if !config.ModifiedDiscoverySettings(daemon.configStore, newAdvertise, newClusterStore, conf.ClusterOpts) { return nil } // enable discovery for the first time if it was not previously enabled if daemon.discoveryWatcher == nil { - discoveryWatcher, err := initDiscovery(newClusterStore, newAdvertise, config.ClusterOpts) + discoveryWatcher, err := discovery.Init(newClusterStore, newAdvertise, conf.ClusterOpts) if err != nil { return fmt.Errorf("discovery initialization failed (%v)", err) } daemon.discoveryWatcher = discoveryWatcher } else { - if err == errDiscoveryDisabled { + if err == discovery.ErrDiscoveryDisabled { // disable discovery if it was previously enabled and it's disabled now daemon.discoveryWatcher.Stop() } else { // reload discovery - if err = daemon.discoveryWatcher.Reload(config.ClusterStore, newAdvertise, config.ClusterOpts); err != nil { + if err = daemon.discoveryWatcher.Reload(conf.ClusterStore, newAdvertise, conf.ClusterOpts); err != nil { return err } } } daemon.configStore.ClusterStore = newClusterStore - daemon.configStore.ClusterOpts = config.ClusterOpts + daemon.configStore.ClusterOpts = conf.ClusterOpts daemon.configStore.ClusterAdvertise = newAdvertise if daemon.netController == nil { @@ -1201,11 +1203,11 @@ func (daemon *Daemon) reloadClusterDiscovery(config *Config) error { return nil } -func isBridgeNetworkDisabled(config *Config) bool { - return config.bridgeConfig.Iface == disableNetworkBridge +func isBridgeNetworkDisabled(conf *config.Config) bool { + return conf.BridgeConfig.Iface == config.DisableNetworkBridge } -func (daemon *Daemon) networkOptions(dconfig *Config, pg plugingetter.PluginGetter, activeSandboxes map[string]interface{}) ([]nwconfig.Option, error) { +func (daemon *Daemon) networkOptions(dconfig *config.Config, pg plugingetter.PluginGetter, activeSandboxes map[string]interface{}) ([]nwconfig.Option, error) { options := []nwconfig.Option{} if dconfig == nil { return options, nil @@ -1297,7 +1299,7 @@ func (daemon *Daemon) PluginGetter() *plugin.Store { } // CreateDaemonRoot creates the root for the daemon -func CreateDaemonRoot(config *Config) error { +func CreateDaemonRoot(config *config.Config) error { // get the canonical path to the Docker root directory var realRoot string if _, err := os.Stat(config.Root); err != nil && os.IsNotExist(err) { diff --git a/daemon/daemon_test.go b/daemon/daemon_test.go index 87550d455b..8d8d5c6db8 100644 --- a/daemon/daemon_test.go +++ b/daemon/daemon_test.go @@ -12,6 +12,7 @@ import ( containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" + "github.com/docker/docker/daemon/config" "github.com/docker/docker/pkg/discovery" _ "github.com/docker/docker/pkg/discovery/memory" "github.com/docker/docker/pkg/registrar" @@ -316,18 +317,18 @@ func TestMerge(t *testing.T) { func TestDaemonReloadLabels(t *testing.T) { daemon := &Daemon{} - daemon.configStore = &Config{ - CommonConfig: CommonConfig{ + daemon.configStore = &config.Config{ + CommonConfig: config.CommonConfig{ Labels: []string{"foo:bar"}, }, } valuesSets := make(map[string]interface{}) valuesSets["labels"] = "foo:baz" - newConfig := &Config{ - CommonConfig: CommonConfig{ + newConfig := &config.Config{ + CommonConfig: config.CommonConfig{ Labels: []string{"foo:baz"}, - valuesSet: valuesSets, + ValuesSet: valuesSets, }, } @@ -353,7 +354,7 @@ func TestDaemonReloadMirrors(t *testing.T) { }, }) - daemon.configStore = &Config{} + daemon.configStore = &config.Config{} type pair struct { valid bool @@ -388,12 +389,12 @@ func TestDaemonReloadMirrors(t *testing.T) { valuesSets := make(map[string]interface{}) valuesSets["registry-mirrors"] = value.mirrors - newConfig := &Config{ - CommonConfig: CommonConfig{ + newConfig := &config.Config{ + CommonConfig: config.CommonConfig{ ServiceOptions: registry.ServiceOptions{ Mirrors: value.mirrors, }, - valuesSet: valuesSets, + ValuesSet: valuesSets, }, } @@ -448,7 +449,7 @@ func TestDaemonReloadInsecureRegistries(t *testing.T) { }, }) - daemon.configStore = &Config{} + daemon.configStore = &config.Config{} insecureRegistries := []string{ "127.0.0.0/8", // this will be kept @@ -461,12 +462,12 @@ func TestDaemonReloadInsecureRegistries(t *testing.T) { valuesSets := make(map[string]interface{}) valuesSets["insecure-registries"] = insecureRegistries - newConfig := &Config{ - CommonConfig: CommonConfig{ + newConfig := &config.Config{ + CommonConfig: config.CommonConfig{ ServiceOptions: registry.ServiceOptions{ InsecureRegistries: insecureRegistries, }, - valuesSet: valuesSets, + ValuesSet: valuesSets, }, } @@ -523,8 +524,8 @@ func TestDaemonReloadInsecureRegistries(t *testing.T) { func TestDaemonReloadNotAffectOthers(t *testing.T) { daemon := &Daemon{} - daemon.configStore = &Config{ - CommonConfig: CommonConfig{ + daemon.configStore = &config.Config{ + CommonConfig: config.CommonConfig{ Labels: []string{"foo:bar"}, Debug: true, }, @@ -532,10 +533,10 @@ func TestDaemonReloadNotAffectOthers(t *testing.T) { valuesSets := make(map[string]interface{}) valuesSets["labels"] = "foo:baz" - newConfig := &Config{ - CommonConfig: CommonConfig{ + newConfig := &config.Config{ + CommonConfig: config.CommonConfig{ Labels: []string{"foo:baz"}, - valuesSet: valuesSets, + ValuesSet: valuesSets, }, } @@ -555,8 +556,8 @@ func TestDaemonReloadNotAffectOthers(t *testing.T) { func TestDaemonDiscoveryReload(t *testing.T) { daemon := &Daemon{} - daemon.configStore = &Config{ - CommonConfig: CommonConfig{ + daemon.configStore = &config.Config{ + CommonConfig: config.CommonConfig{ ClusterStore: "memory://127.0.0.1", ClusterAdvertise: "127.0.0.1:3333", }, @@ -594,11 +595,11 @@ func TestDaemonDiscoveryReload(t *testing.T) { valuesSets := make(map[string]interface{}) valuesSets["cluster-store"] = "memory://127.0.0.1:2222" valuesSets["cluster-advertise"] = "127.0.0.1:5555" - newConfig := &Config{ - CommonConfig: CommonConfig{ + newConfig := &config.Config{ + CommonConfig: config.CommonConfig{ ClusterStore: "memory://127.0.0.1:2222", ClusterAdvertise: "127.0.0.1:5555", - valuesSet: valuesSets, + ValuesSet: valuesSets, }, } @@ -632,16 +633,16 @@ func TestDaemonDiscoveryReload(t *testing.T) { func TestDaemonDiscoveryReloadFromEmptyDiscovery(t *testing.T) { daemon := &Daemon{} - daemon.configStore = &Config{} + daemon.configStore = &config.Config{} valuesSet := make(map[string]interface{}) valuesSet["cluster-store"] = "memory://127.0.0.1:2222" valuesSet["cluster-advertise"] = "127.0.0.1:5555" - newConfig := &Config{ - CommonConfig: CommonConfig{ + newConfig := &config.Config{ + CommonConfig: config.CommonConfig{ ClusterStore: "memory://127.0.0.1:2222", ClusterAdvertise: "127.0.0.1:5555", - valuesSet: valuesSet, + ValuesSet: valuesSet, }, } @@ -677,17 +678,17 @@ func TestDaemonDiscoveryReloadFromEmptyDiscovery(t *testing.T) { func TestDaemonDiscoveryReloadOnlyClusterAdvertise(t *testing.T) { daemon := &Daemon{} - daemon.configStore = &Config{ - CommonConfig: CommonConfig{ + daemon.configStore = &config.Config{ + CommonConfig: config.CommonConfig{ ClusterStore: "memory://127.0.0.1", }, } valuesSets := make(map[string]interface{}) valuesSets["cluster-advertise"] = "127.0.0.1:5555" - newConfig := &Config{ - CommonConfig: CommonConfig{ + newConfig := &config.Config{ + CommonConfig: config.CommonConfig{ ClusterAdvertise: "127.0.0.1:5555", - valuesSet: valuesSets, + ValuesSet: valuesSets, }, } expected := discovery.Entries{ diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index b048da2979..1bb543f9e7 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -23,6 +23,7 @@ import ( pblkiodev "github.com/docker/docker/api/types/blkiodev" containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" + "github.com/docker/docker/daemon/config" "github.com/docker/docker/image" "github.com/docker/docker/opts" "github.com/docker/docker/pkg/idtools" @@ -256,7 +257,7 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf hostConfig.MemorySwap = hostConfig.Memory * 2 } if hostConfig.ShmSize == 0 { - hostConfig.ShmSize = defaultShmSize + hostConfig.ShmSize = config.DefaultShmSize if daemon.configStore != nil { hostConfig.ShmSize = int64(daemon.configStore.ShmSize) } @@ -474,7 +475,7 @@ func (daemon *Daemon) getCgroupDriver() string { } // getCD gets the raw value of the native.cgroupdriver option, if set. -func getCD(config *Config) string { +func getCD(config *config.Config) string { for _, option := range config.ExecOptions { key, val, err := parsers.ParseKeyValueOpt(option) if err != nil || !strings.EqualFold(key, "native.cgroupdriver") { @@ -486,7 +487,7 @@ func getCD(config *Config) string { } // VerifyCgroupDriver validates native.cgroupdriver -func VerifyCgroupDriver(config *Config) error { +func VerifyCgroupDriver(config *config.Config) error { cd := getCD(config) if cd == "" || cd == cgroupFsDriver || cd == cgroupSystemdDriver { return nil @@ -495,7 +496,7 @@ func VerifyCgroupDriver(config *Config) error { } // UsingSystemd returns true if cli option includes native.cgroupdriver=systemd -func UsingSystemd(config *Config) bool { +func UsingSystemd(config *config.Config) bool { return getCD(config) == cgroupSystemdDriver } @@ -568,19 +569,19 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes. } // platformReload updates configuration with platform specific options -func (daemon *Daemon) platformReload(config *Config) map[string]string { - if config.IsValueSet("runtimes") { - daemon.configStore.Runtimes = config.Runtimes +func (daemon *Daemon) platformReload(conf *config.Config) map[string]string { + if conf.IsValueSet("runtimes") { + daemon.configStore.Runtimes = conf.Runtimes // Always set the default one - daemon.configStore.Runtimes[stockRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary} + daemon.configStore.Runtimes[config.StockRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary} } - if config.DefaultRuntime != "" { - daemon.configStore.DefaultRuntime = config.DefaultRuntime + if conf.DefaultRuntime != "" { + daemon.configStore.DefaultRuntime = conf.DefaultRuntime } - if config.IsValueSet("default-shm-size") { - daemon.configStore.ShmSize = config.ShmSize + if conf.IsValueSet("default-shm-size") { + daemon.configStore.ShmSize = conf.ShmSize } // Update attributes @@ -600,33 +601,33 @@ func (daemon *Daemon) platformReload(config *Config) map[string]string { } // verifyDaemonSettings performs validation of daemon config struct -func verifyDaemonSettings(config *Config) error { +func verifyDaemonSettings(conf *config.Config) error { // Check for mutually incompatible config options - if config.bridgeConfig.Iface != "" && config.bridgeConfig.IP != "" { + if conf.BridgeConfig.Iface != "" && conf.BridgeConfig.IP != "" { return fmt.Errorf("You specified -b & --bip, mutually exclusive options. Please specify only one") } - if !config.bridgeConfig.EnableIPTables && !config.bridgeConfig.InterContainerCommunication { + if !conf.BridgeConfig.EnableIPTables && !conf.BridgeConfig.InterContainerCommunication { return fmt.Errorf("You specified --iptables=false with --icc=false. ICC=false uses iptables to function. Please set --icc or --iptables to true") } - if !config.bridgeConfig.EnableIPTables && config.bridgeConfig.EnableIPMasq { - config.bridgeConfig.EnableIPMasq = false + if !conf.BridgeConfig.EnableIPTables && conf.BridgeConfig.EnableIPMasq { + conf.BridgeConfig.EnableIPMasq = false } - if err := VerifyCgroupDriver(config); err != nil { + if err := VerifyCgroupDriver(conf); err != nil { return err } - if config.CgroupParent != "" && UsingSystemd(config) { - if len(config.CgroupParent) <= 6 || !strings.HasSuffix(config.CgroupParent, ".slice") { + if conf.CgroupParent != "" && UsingSystemd(conf) { + if len(conf.CgroupParent) <= 6 || !strings.HasSuffix(conf.CgroupParent, ".slice") { return fmt.Errorf("cgroup-parent for systemd cgroup should be a valid slice named as \"xxx.slice\"") } } - if config.DefaultRuntime == "" { - config.DefaultRuntime = stockRuntimeName + if conf.DefaultRuntime == "" { + conf.DefaultRuntime = config.StockRuntimeName } - if config.Runtimes == nil { - config.Runtimes = make(map[string]types.Runtime) + if conf.Runtimes == nil { + conf.Runtimes = make(map[string]types.Runtime) } - config.Runtimes[stockRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary} + conf.Runtimes[config.StockRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary} return nil } @@ -641,7 +642,7 @@ func checkSystem() error { // configureMaxThreads sets the Go runtime max threads threshold // which is 90% of the kernel setting from /proc/sys/kernel/threads-max -func configureMaxThreads(config *Config) error { +func configureMaxThreads(config *config.Config) error { mt, err := ioutil.ReadFile("/proc/sys/kernel/threads-max") if err != nil { return err @@ -688,7 +689,7 @@ func overlaySupportsSelinux() (bool, error) { } // configureKernelSecuritySupport configures and validates security support for the kernel -func configureKernelSecuritySupport(config *Config, driverName string) error { +func configureKernelSecuritySupport(config *config.Config, driverName string) error { if config.EnableSelinuxSupport { if !selinuxEnabled() { logrus.Warn("Docker could not enable SELinux on the host system") @@ -713,7 +714,7 @@ func configureKernelSecuritySupport(config *Config, driverName string) error { return nil } -func (daemon *Daemon) initNetworkController(config *Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) { +func (daemon *Daemon) initNetworkController(config *config.Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) { netOptions, err := daemon.networkOptions(config, daemon.PluginStore, activeSandboxes) if err != nil { return nil, err @@ -762,12 +763,12 @@ func (daemon *Daemon) initNetworkController(config *Config, activeSandboxes map[ return controller, nil } -func driverOptions(config *Config) []nwconfig.Option { +func driverOptions(config *config.Config) []nwconfig.Option { bridgeConfig := options.Generic{ - "EnableIPForwarding": config.bridgeConfig.EnableIPForward, - "EnableIPTables": config.bridgeConfig.EnableIPTables, - "EnableUserlandProxy": config.bridgeConfig.EnableUserlandProxy, - "UserlandProxyPath": config.bridgeConfig.UserlandProxyPath} + "EnableIPForwarding": config.BridgeConfig.EnableIPForward, + "EnableIPTables": config.BridgeConfig.EnableIPTables, + "EnableUserlandProxy": config.BridgeConfig.EnableUserlandProxy, + "UserlandProxyPath": config.BridgeConfig.UserlandProxyPath} bridgeOption := options.Generic{netlabel.GenericData: bridgeConfig} dOptions := []nwconfig.Option{} @@ -775,22 +776,22 @@ func driverOptions(config *Config) []nwconfig.Option { return dOptions } -func initBridgeDriver(controller libnetwork.NetworkController, config *Config) error { +func initBridgeDriver(controller libnetwork.NetworkController, config *config.Config) error { bridgeName := bridge.DefaultBridgeName - if config.bridgeConfig.Iface != "" { - bridgeName = config.bridgeConfig.Iface + if config.BridgeConfig.Iface != "" { + bridgeName = config.BridgeConfig.Iface } netOption := map[string]string{ bridge.BridgeName: bridgeName, bridge.DefaultBridge: strconv.FormatBool(true), netlabel.DriverMTU: strconv.Itoa(config.Mtu), - bridge.EnableIPMasquerade: strconv.FormatBool(config.bridgeConfig.EnableIPMasq), - bridge.EnableICC: strconv.FormatBool(config.bridgeConfig.InterContainerCommunication), + bridge.EnableIPMasquerade: strconv.FormatBool(config.BridgeConfig.EnableIPMasq), + bridge.EnableICC: strconv.FormatBool(config.BridgeConfig.InterContainerCommunication), } // --ip processing - if config.bridgeConfig.DefaultIP != nil { - netOption[bridge.DefaultBindingIP] = config.bridgeConfig.DefaultIP.String() + if config.BridgeConfig.DefaultIP != nil { + netOption[bridge.DefaultBindingIP] = config.BridgeConfig.DefaultIP.String() } var ( @@ -806,8 +807,8 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e } nw := nwList[0] - if len(nwList) > 1 && config.bridgeConfig.FixedCIDR != "" { - _, fCIDR, err := net.ParseCIDR(config.bridgeConfig.FixedCIDR) + if len(nwList) > 1 && config.BridgeConfig.FixedCIDR != "" { + _, fCIDR, err := net.ParseCIDR(config.BridgeConfig.FixedCIDR) if err != nil { return errors.Wrap(err, "parse CIDR failed") } @@ -826,9 +827,9 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e ipamV4Conf.Gateway = nw.IP.String() } - if config.bridgeConfig.IP != "" { - ipamV4Conf.PreferredPool = config.bridgeConfig.IP - ip, _, err := net.ParseCIDR(config.bridgeConfig.IP) + if config.BridgeConfig.IP != "" { + ipamV4Conf.PreferredPool = config.BridgeConfig.IP + ip, _, err := net.ParseCIDR(config.BridgeConfig.IP) if err != nil { return err } @@ -837,8 +838,8 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e logrus.Infof("Default bridge (%s) is assigned with an IP address %s. Daemon option --bip can be used to set a preferred IP address", bridgeName, ipamV4Conf.PreferredPool) } - if config.bridgeConfig.FixedCIDR != "" { - _, fCIDR, err := net.ParseCIDR(config.bridgeConfig.FixedCIDR) + if config.BridgeConfig.FixedCIDR != "" { + _, fCIDR, err := net.ParseCIDR(config.BridgeConfig.FixedCIDR) if err != nil { return err } @@ -846,13 +847,13 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e ipamV4Conf.SubPool = fCIDR.String() } - if config.bridgeConfig.DefaultGatewayIPv4 != nil { - ipamV4Conf.AuxAddresses["DefaultGatewayIPv4"] = config.bridgeConfig.DefaultGatewayIPv4.String() + if config.BridgeConfig.DefaultGatewayIPv4 != nil { + ipamV4Conf.AuxAddresses["DefaultGatewayIPv4"] = config.BridgeConfig.DefaultGatewayIPv4.String() } var deferIPv6Alloc bool - if config.bridgeConfig.FixedCIDRv6 != "" { - _, fCIDRv6, err := net.ParseCIDR(config.bridgeConfig.FixedCIDRv6) + if config.BridgeConfig.FixedCIDRv6 != "" { + _, fCIDRv6, err := net.ParseCIDR(config.BridgeConfig.FixedCIDRv6) if err != nil { return err } @@ -882,11 +883,11 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e } } - if config.bridgeConfig.DefaultGatewayIPv6 != nil { + if config.BridgeConfig.DefaultGatewayIPv6 != nil { if ipamV6Conf == nil { ipamV6Conf = &libnetwork.IpamConf{AuxAddresses: make(map[string]string)} } - ipamV6Conf.AuxAddresses["DefaultGatewayIPv6"] = config.bridgeConfig.DefaultGatewayIPv6.String() + ipamV6Conf.AuxAddresses["DefaultGatewayIPv6"] = config.BridgeConfig.DefaultGatewayIPv6.String() } v4Conf := []*libnetwork.IpamConf{ipamV4Conf} @@ -896,7 +897,7 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e } // Initialize default network on "bridge" with the same name _, err = controller.NewNetwork("bridge", "bridge", "", - libnetwork.NetworkOptionEnableIPv6(config.bridgeConfig.EnableIPv6), + libnetwork.NetworkOptionEnableIPv6(config.BridgeConfig.EnableIPv6), libnetwork.NetworkOptionDriverOpts(netOption), libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf, nil), libnetwork.NetworkOptionDeferIPv6Alloc(deferIPv6Alloc)) @@ -1012,7 +1013,7 @@ func parseRemappedRoot(usergrp string) (string, string, error) { return username, groupname, nil } -func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error) { +func setupRemappedRoot(config *config.Config) ([]idtools.IDMap, []idtools.IDMap, error) { if runtime.GOOS != "linux" && config.RemappedRoot != "" { return nil, nil, fmt.Errorf("User namespaces are only supported on Linux") } @@ -1045,7 +1046,7 @@ func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error) return uidMaps, gidMaps, nil } -func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error { +func setupDaemonRoot(config *config.Config, rootDir string, rootUID, rootGID int) error { config.Root = rootDir // the docker root metadata directory needs to have execute permissions for all users (g+x,o+x) // so that syscalls executing as non-root, operating on subdirectories of the graph root @@ -1219,7 +1220,7 @@ func rootFSToAPIType(rootfs *image.RootFS) types.RootFS { } // setupDaemonProcess sets various settings for the daemon's process -func setupDaemonProcess(config *Config) error { +func setupDaemonProcess(config *config.Config) error { // setup the daemons oom_score_adj return setupOOMScoreAdj(config.OOMScoreAdjust) } diff --git a/daemon/daemon_unix_test.go b/daemon/daemon_unix_test.go index 6250d359e3..9889bd19fe 100644 --- a/daemon/daemon_unix_test.go +++ b/daemon/daemon_unix_test.go @@ -10,6 +10,7 @@ import ( containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" + "github.com/docker/docker/daemon/config" "github.com/docker/docker/volume" "github.com/docker/docker/volume/drivers" "github.com/docker/docker/volume/local" @@ -181,8 +182,8 @@ func TestParseSecurityOpt(t *testing.T) { func TestNetworkOptions(t *testing.T) { daemon := &Daemon{} - dconfigCorrect := &Config{ - CommonConfig: CommonConfig{ + dconfigCorrect := &config.Config{ + CommonConfig: config.CommonConfig{ ClusterStore: "consul://localhost:8500", ClusterAdvertise: "192.168.0.1:8000", }, @@ -192,8 +193,8 @@ func TestNetworkOptions(t *testing.T) { t.Fatalf("Expect networkOptions success, got error: %v", err) } - dconfigWrong := &Config{ - CommonConfig: CommonConfig{ + dconfigWrong := &config.Config{ + CommonConfig: config.CommonConfig{ ClusterStore: "consul://localhost:8500://test://bbb", }, } diff --git a/daemon/daemon_windows.go b/daemon/daemon_windows.go index 1c416bdc9c..79768eb74b 100644 --- a/daemon/daemon_windows.go +++ b/daemon/daemon_windows.go @@ -11,6 +11,7 @@ import ( "github.com/docker/docker/api/types" containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" + "github.com/docker/docker/daemon/config" "github.com/docker/docker/image" "github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/parsers" @@ -210,12 +211,12 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes. } // platformReload updates configuration with platform specific options -func (daemon *Daemon) platformReload(config *Config) map[string]string { +func (daemon *Daemon) platformReload(config *config.Config) map[string]string { return map[string]string{} } // verifyDaemonSettings performs validation of daemon config struct -func verifyDaemonSettings(config *Config) error { +func verifyDaemonSettings(config *config.Config) error { return nil } @@ -239,16 +240,16 @@ func checkSystem() error { } // configureKernelSecuritySupport configures and validate security support for the kernel -func configureKernelSecuritySupport(config *Config, driverName string) error { +func configureKernelSecuritySupport(config *config.Config, driverName string) error { return nil } // configureMaxThreads sets the Go runtime max threads threshold -func configureMaxThreads(config *Config) error { +func configureMaxThreads(config *config.Config) error { return nil } -func (daemon *Daemon) initNetworkController(config *Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) { +func (daemon *Daemon) initNetworkController(config *config.Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) { netOptions, err := daemon.networkOptions(config, nil, nil) if err != nil { return nil, err @@ -376,7 +377,7 @@ func (daemon *Daemon) initNetworkController(config *Config, activeSandboxes map[ return controller, nil } -func initBridgeDriver(controller libnetwork.NetworkController, config *Config) error { +func initBridgeDriver(controller libnetwork.NetworkController, config *config.Config) error { if _, err := controller.NetworkByName(runconfig.DefaultDaemonNetworkMode().NetworkName()); err == nil { return nil } @@ -388,8 +389,8 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e var ipamOption libnetwork.NetworkOption var subnetPrefix string - if config.bridgeConfig.FixedCIDR != "" { - subnetPrefix = config.bridgeConfig.FixedCIDR + if config.BridgeConfig.FixedCIDR != "" { + subnetPrefix = config.BridgeConfig.FixedCIDR } else { // TP5 doesn't support properly detecting subnet osv := system.GetOSVersion() @@ -434,11 +435,11 @@ func (daemon *Daemon) cleanupMounts() error { return nil } -func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error) { +func setupRemappedRoot(config *config.Config) ([]idtools.IDMap, []idtools.IDMap, error) { return nil, nil, nil } -func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error { +func setupDaemonRoot(config *config.Config, rootDir string, rootUID, rootGID int) error { config.Root = rootDir // Create the root directory if it doesn't exists if err := system.MkdirAllWithACL(config.Root, 0); err != nil && !os.IsExist(err) { @@ -479,7 +480,7 @@ func (daemon *Daemon) conditionalUnmountOnCleanup(container *container.Container return nil } -func driverOptions(config *Config) []nwconfig.Option { +func driverOptions(config *config.Config) []nwconfig.Option { return []nwconfig.Option{} } @@ -593,7 +594,7 @@ func rootFSToAPIType(rootfs *image.RootFS) types.RootFS { } } -func setupDaemonProcess(config *Config) error { +func setupDaemonProcess(config *config.Config) error { return nil } diff --git a/daemon/discovery.go b/daemon/discovery/discovery.go similarity index 85% rename from daemon/discovery.go rename to daemon/discovery/discovery.go index ee4ea875b7..24c305f8e0 100644 --- a/daemon/discovery.go +++ b/daemon/discovery/discovery.go @@ -1,9 +1,8 @@ -package daemon +package discovery import ( "errors" "fmt" - "reflect" "strconv" "time" @@ -21,9 +20,11 @@ const ( defaultDiscoveryTTLFactor = 3 ) -var errDiscoveryDisabled = errors.New("discovery is disabled") +// ErrDiscoveryDisabled is an error returned if the discovery is disabled +var ErrDiscoveryDisabled = errors.New("discovery is disabled") -type discoveryReloader interface { +// Reloader is the discovery reloader of the daemon +type Reloader interface { discovery.Watcher Stop() Reload(backend, address string, clusterOpts map[string]string) error @@ -93,9 +94,9 @@ func discoveryOpts(clusterOpts map[string]string) (time.Duration, time.Duration, return heartbeat, ttl, nil } -// initDiscovery initializes the nodes discovery subsystem by connecting to the specified backend +// Init initializes the nodes discovery subsystem by connecting to the specified backend // and starts a registration loop to advertise the current node under the specified address. -func initDiscovery(backendAddress, advertiseAddress string, clusterOpts map[string]string) (discoveryReloader, error) { +func Init(backendAddress, advertiseAddress string, clusterOpts map[string]string) (Reloader, error) { heartbeat, backend, err := parseDiscoveryOptions(backendAddress, clusterOpts) if err != nil { return nil, err @@ -198,18 +199,3 @@ func parseDiscoveryOptions(backendAddress string, clusterOpts map[string]string) } return heartbeat, backend, nil } - -// modifiedDiscoverySettings returns whether the discovery configuration has been modified or not. -func modifiedDiscoverySettings(config *Config, backendType, advertise string, clusterOpts map[string]string) bool { - if config.ClusterStore != backendType || config.ClusterAdvertise != advertise { - return true - } - - if (config.ClusterOpts == nil && clusterOpts == nil) || - (config.ClusterOpts == nil && len(clusterOpts) == 0) || - (len(config.ClusterOpts) == 0 && clusterOpts == nil) { - return false - } - - return !reflect.DeepEqual(config.ClusterOpts, clusterOpts) -} diff --git a/daemon/discovery_test.go b/daemon/discovery/discovery_test.go similarity index 62% rename from daemon/discovery_test.go rename to daemon/discovery/discovery_test.go index 336973c516..ae409c7fd1 100644 --- a/daemon/discovery_test.go +++ b/daemon/discovery/discovery_test.go @@ -1,4 +1,4 @@ -package daemon +package discovery import ( "testing" @@ -101,64 +101,3 @@ func TestDiscoveryOpts(t *testing.T) { t.Fatalf("TTL - Expected : %v, Actual : %v", expected, ttl) } } - -func TestModifiedDiscoverySettings(t *testing.T) { - cases := []struct { - current *Config - modified *Config - expected bool - }{ - { - current: discoveryConfig("foo", "bar", map[string]string{}), - modified: discoveryConfig("foo", "bar", map[string]string{}), - expected: false, - }, - { - current: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}), - modified: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}), - expected: false, - }, - { - current: discoveryConfig("foo", "bar", map[string]string{}), - modified: discoveryConfig("foo", "bar", nil), - expected: false, - }, - { - current: discoveryConfig("foo", "bar", nil), - modified: discoveryConfig("foo", "bar", map[string]string{}), - expected: false, - }, - { - current: discoveryConfig("foo", "bar", nil), - modified: discoveryConfig("baz", "bar", nil), - expected: true, - }, - { - current: discoveryConfig("foo", "bar", nil), - modified: discoveryConfig("foo", "baz", nil), - expected: true, - }, - { - current: discoveryConfig("foo", "bar", nil), - modified: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}), - expected: true, - }, - } - - for _, c := range cases { - got := modifiedDiscoverySettings(c.current, c.modified.ClusterStore, c.modified.ClusterAdvertise, c.modified.ClusterOpts) - if c.expected != got { - t.Fatalf("expected %v, got %v: current config %v, new config %v", c.expected, got, c.current, c.modified) - } - } -} - -func discoveryConfig(backendAddr, advertiseAddr string, opts map[string]string) *Config { - return &Config{ - CommonConfig: CommonConfig{ - ClusterStore: backendAddr, - ClusterAdvertise: advertiseAddr, - ClusterOpts: opts, - }, - } -}