Procházet zdrojové kódy

Extract daemon configuration and discovery to their own package

This also moves some cli specific in `cmd/dockerd` as it does not
really belong to the `daemon/config` package.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Vincent Demeester před 8 roky
rodič
revize
db63f9370e

+ 52 - 0
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
+}

+ 34 - 0
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")
+
+}

+ 9 - 0
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) {
+}

+ 19 - 0
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)
+}

+ 51 - 0
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)
+}

+ 32 - 0
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())
+	}
+}

+ 25 - 0
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")
+}

+ 24 - 23
cmd/dockerd/daemon.go

@@ -31,6 +31,7 @@ import (
 	cliflags "github.com/docker/docker/cli/flags"
 	cliflags "github.com/docker/docker/cli/flags"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/daemon"
 	"github.com/docker/docker/daemon/cluster"
 	"github.com/docker/docker/daemon/cluster"
+	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/libcontainerd"
 	"github.com/docker/docker/libcontainerd"
@@ -54,7 +55,7 @@ const (
 
 
 // DaemonCli represents the daemon CLI.
 // DaemonCli represents the daemon CLI.
 type DaemonCli struct {
 type DaemonCli struct {
-	*daemon.Config
+	*config.Config
 	configFile *string
 	configFile *string
 	flags      *pflag.FlagSet
 	flags      *pflag.FlagSet
 
 
@@ -68,7 +69,7 @@ func NewDaemonCli() *DaemonCli {
 	return &DaemonCli{}
 	return &DaemonCli{}
 }
 }
 
 
-func migrateKey(config *daemon.Config) (err error) {
+func migrateKey(config *config.Config) (err error) {
 	// No migration necessary on Windows
 	// No migration necessary on Windows
 	if runtime.GOOS == "windows" {
 	if runtime.GOOS == "windows" {
 		return nil
 		return nil
@@ -335,7 +336,7 @@ func (cli *DaemonCli) start(opts daemonOptions) (err error) {
 }
 }
 
 
 func (cli *DaemonCli) reloadConfig() {
 func (cli *DaemonCli) reloadConfig() {
-	reload := func(config *daemon.Config) {
+	reload := func(config *config.Config) {
 
 
 		// Revalidate and reload the authorization plugins
 		// Revalidate and reload the authorization plugins
 		if err := validateAuthzPlugins(config.AuthorizationPlugins, cli.d.PluginStore); err != nil {
 		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)
 		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
 	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 {
 	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 != "" {
 	if opts.configFile != "" {
-		c, err := daemon.MergeDaemonConfigurations(config, flags, opts.configFile)
+		c, err := config.MergeDaemonConfigurations(conf, flags, opts.configFile)
 		if err != nil {
 		if err != nil {
 			if flags.Changed(flagDaemonConfigFile) || !os.IsNotExist(err) {
 			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)
 				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.
 		// the merged configuration can be nil if the config file didn't exist.
 		// leave the current configuration as it is if when that happens.
 		// leave the current configuration as it is if when that happens.
 		if c != nil {
 		if c != nil {
-			config = c
+			conf = c
 		}
 		}
 	}
 	}
 
 
-	if err := daemon.ValidateConfiguration(config); err != nil {
+	if err := config.Validate(conf); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
@@ -442,20 +443,20 @@ func loadDaemonCliConfig(opts daemonOptions) (*daemon.Config, error) {
 	// }
 	// }
 	// config.Labels = newLabels
 	// 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)
 		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
 	// Regardless of whether the user sets it to true or false, if they
 	// specify TLSVerify at all then we need to turn on TLS
 	// 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
 	// 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) {
 func initRouter(s *apiserver.Server, d *daemon.Daemon, c *cluster.Cluster) {

+ 3 - 3
cmd/dockerd/daemon_test.go

@@ -5,7 +5,7 @@ import (
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	cliflags "github.com/docker/docker/cli/flags"
 	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/assert"
 	"github.com/docker/docker/pkg/testutil/tempfile"
 	"github.com/docker/docker/pkg/testutil/tempfile"
 	"github.com/spf13/pflag"
 	"github.com/spf13/pflag"
@@ -13,12 +13,12 @@ import (
 
 
 func defaultOptions(configFile string) daemonOptions {
 func defaultOptions(configFile string) daemonOptions {
 	opts := daemonOptions{
 	opts := daemonOptions{
-		daemonConfig: &daemon.Config{},
+		daemonConfig: &config.Config{},
 		flags:        &pflag.FlagSet{},
 		flags:        &pflag.FlagSet{},
 		common:       cliflags.NewCommonOptions(),
 		common:       cliflags.NewCommonOptions(),
 	}
 	}
 	opts.common.InstallFlags(opts.flags)
 	opts.common.InstallFlags(opts.flags)
-	opts.daemonConfig.InstallFlags(opts.flags)
+	installConfigFlags(opts.daemonConfig, opts.flags)
 	opts.flags.StringVar(&opts.configFile, flagDaemonConfigFile, defaultDaemonConfigFile, "")
 	opts.flags.StringVar(&opts.configFile, flagDaemonConfigFile, defaultDaemonConfigFile, "")
 	opts.configFile = configFile
 	opts.configFile = configFile
 	return opts
 	return opts

+ 5 - 4
cmd/dockerd/daemon_unix_test.go

@@ -6,10 +6,11 @@
 package main
 package main
 
 
 import (
 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/assert"
 	"github.com/docker/docker/pkg/testutil/tempfile"
 	"github.com/docker/docker/pkg/testutil/tempfile"
-	"testing"
 )
 )
 
 
 func TestLoadDaemonCliConfigWithDaemonFlags(t *testing.T) {
 func TestLoadDaemonCliConfigWithDaemonFlags(t *testing.T) {
@@ -82,10 +83,10 @@ func TestLoadDaemonConfigWithTrueDefaultValues(t *testing.T) {
 
 
 	// make sure reloading doesn't generate configuration
 	// make sure reloading doesn't generate configuration
 	// conflicts after normalizing boolean values.
 	// conflicts after normalizing boolean values.
-	reload := func(reloadedConfig *daemon.Config) {
+	reload := func(reloadedConfig *config.Config) {
 		assert.Equal(t, reloadedConfig.EnableUserlandProxy, false)
 		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) {
 func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) {

+ 4 - 4
cmd/dockerd/docker.go

@@ -9,7 +9,7 @@ import (
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/cli"
 	"github.com/docker/docker/cli"
 	cliflags "github.com/docker/docker/cli/flags"
 	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/dockerversion"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/docker/pkg/term"
 	"github.com/docker/docker/pkg/term"
@@ -20,14 +20,14 @@ import (
 type daemonOptions struct {
 type daemonOptions struct {
 	version      bool
 	version      bool
 	configFile   string
 	configFile   string
-	daemonConfig *daemon.Config
+	daemonConfig *config.Config
 	common       *cliflags.CommonOptions
 	common       *cliflags.CommonOptions
 	flags        *pflag.FlagSet
 	flags        *pflag.FlagSet
 }
 }
 
 
 func newDaemonCommand() *cobra.Command {
 func newDaemonCommand() *cobra.Command {
 	opts := daemonOptions{
 	opts := daemonOptions{
-		daemonConfig: daemon.NewConfig(),
+		daemonConfig: config.New(),
 		common:       cliflags.NewCommonOptions(),
 		common:       cliflags.NewCommonOptions(),
 	}
 	}
 
 
@@ -48,7 +48,7 @@ func newDaemonCommand() *cobra.Command {
 	flags.BoolVarP(&opts.version, "version", "v", false, "Print version information and quit")
 	flags.BoolVarP(&opts.version, "version", "v", false, "Print version information and quit")
 	flags.StringVar(&opts.configFile, flagDaemonConfigFile, defaultDaemonConfigFile, "Daemon configuration file")
 	flags.StringVar(&opts.configFile, flagDaemonConfigFile, defaultDaemonConfigFile, "Daemon configuration file")
 	opts.common.InstallFlags(flags)
 	opts.common.InstallFlags(flags)
-	opts.daemonConfig.InstallFlags(flags)
+	installConfigFlags(opts.daemonConfig, flags)
 	installServiceFlags(flags)
 	installServiceFlags(flags)
 
 
 	return cmd
 	return cmd

+ 59 - 82
daemon/config.go → daemon/config/config.go

@@ -1,4 +1,4 @@
-package daemon
+package config
 
 
 import (
 import (
 	"bytes"
 	"bytes"
@@ -7,12 +7,14 @@ import (
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 	"io/ioutil"
 	"io/ioutil"
+	"reflect"
 	"runtime"
 	"runtime"
 	"sort"
 	"sort"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
 
 
 	"github.com/Sirupsen/logrus"
 	"github.com/Sirupsen/logrus"
+	daemondiscovery "github.com/docker/docker/daemon/discovery"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/discovery"
 	"github.com/docker/docker/pkg/discovery"
 	"github.com/docker/docker/registry"
 	"github.com/docker/docker/registry"
@@ -21,26 +23,23 @@ import (
 )
 )
 
 
 const (
 const (
-	// defaultMaxConcurrentDownloads is the default value for
+	// DefaultMaxConcurrentDownloads is the default value for
 	// maximum number of downloads that
 	// maximum number of downloads that
 	// may take place at a time for each pull.
 	// 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
 	// maximum number of uploads that
 	// may take place at a time for each push.
 	// 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.
 	// 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
 // flatOptions contains configuration keys
@@ -151,67 +150,29 @@ type CommonConfig struct {
 	MetricsAddress            string `json:"metrics-addr"`
 	MetricsAddress            string `json:"metrics-addr"`
 
 
 	LogConfig
 	LogConfig
-	bridgeConfig // bridgeConfig holds bridge network specific configuration.
+	BridgeConfig // bridgeConfig holds bridge network specific configuration.
 	registry.ServiceOptions
 	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
 	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
 // IsValueSet returns true if a configuration value
 // was explicitly set in the configuration file.
 // 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
 		return false
 	}
 	}
-	_, ok := config.valuesSet[name]
+	_, ok := conf.ValuesSet[name]
 	return ok
 	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 := Config{}
 	config.LogConfig.Config = make(map[string]string)
 	config.LogConfig.Config = make(map[string]string)
 	config.ClusterOpts = make(map[string]string)
 	config.ClusterOpts = make(map[string]string)
@@ -222,12 +183,13 @@ func NewConfig() *Config {
 	return &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 != "") {
 	if runtime.GOOS == "solaris" && (clusterAdvertise != "" || clusterStore != "") {
 		return "", errors.New("Cluster Advertise Settings not supported on Solaris")
 		return "", errors.New("Cluster Advertise Settings not supported on Solaris")
 	}
 	}
 	if clusterAdvertise == "" {
 	if clusterAdvertise == "" {
-		return "", errDiscoveryDisabled
+		return "", daemondiscovery.ErrDiscoveryDisabled
 	}
 	}
 	if clusterStore == "" {
 	if clusterStore == "" {
 		return "", errors.New("invalid cluster configuration. --cluster-advertise must be accompanied by --cluster-store configuration")
 		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
 	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)
 	logrus.Infof("Got signal to reload configuration, reloading from: %s", configFile)
 	newConfig, err := getConflictFreeConfiguration(configFile, flags)
 	newConfig, err := getConflictFreeConfiguration(configFile, flags)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	if err := ValidateConfiguration(newConfig); err != nil {
+	if err := Validate(newConfig); err != nil {
 		return fmt.Errorf("file configuration validation failed (%v)", err)
 		return fmt.Errorf("file configuration validation failed (%v)", err)
 	}
 	}
 
 
@@ -313,7 +275,7 @@ func MergeDaemonConfigurations(flagsConfig *Config, flags *pflag.FlagSet, config
 		return nil, err
 		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)
 		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
 	// We need to validate again once both fileConfig and flagsConfig
 	// have been merged
 	// 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)
 		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)
 	reader = bytes.NewReader(b)
@@ -473,10 +435,10 @@ func findConfigurationConflicts(config map[string]interface{}, flags *pflag.Flag
 	return nil
 	return nil
 }
 }
 
 
-// ValidateConfiguration validates some specific configs.
+// Validate validates some specific configs.
 // such as config.DNS, config.Labels, config.DNSSearch,
 // such as config.DNS, config.Labels, config.DNSSearch,
 // as well as config.MaxConcurrentDownloads, config.MaxConcurrentUploads.
 // as well as config.MaxConcurrentDownloads, config.MaxConcurrentUploads.
-func ValidateConfiguration(config *Config) error {
+func Validate(config *Config) error {
 	// validate DNS
 	// validate DNS
 	for _, dns := range config.DNS {
 	for _, dns := range config.DNS {
 		if _, err := opts.ValidateIPAddress(dns); err != nil {
 		if _, err := opts.ValidateIPAddress(dns); err != nil {
@@ -510,12 +472,12 @@ func ValidateConfiguration(config *Config) error {
 
 
 	// validate that "default" runtime is not reset
 	// validate that "default" runtime is not reset
 	if runtimes := config.GetAllRuntimes(); len(runtimes) > 0 {
 	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()
 		runtimes := config.GetAllRuntimes()
 		if _, ok := runtimes[defaultRuntime]; !ok {
 		if _, ok := runtimes[defaultRuntime]; !ok {
 			return fmt.Errorf("specified default runtime '%s' does not exist", defaultRuntime)
 			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
 // 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)
 		authPlugins = append(authPlugins, p)
 	}
 	}
 	sort.Strings(authPlugins)
 	sort.Strings(authPlugins)
 	return 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)
+}

+ 70 - 0
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
+}

+ 43 - 0
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)
+		}
+	}
+}

+ 5 - 17
daemon/config_solaris.go → daemon/config/config_solaris.go

@@ -1,4 +1,4 @@
-package daemon
+package config
 
 
 import (
 import (
 	"github.com/spf13/pflag"
 	"github.com/spf13/pflag"
@@ -20,28 +20,16 @@ type Config struct {
 	CommonUnixConfig
 	CommonUnixConfig
 }
 }
 
 
-// bridgeConfig stores all the bridge driver specific
+// BridgeConfig stores all the bridge driver specific
 // configuration.
 // configuration.
-type bridgeConfig struct {
+type BridgeConfig struct {
 	commonBridgeConfig
 	commonBridgeConfig
 
 
 	// Fields below here are platform specific.
 	// Fields below here are platform specific.
 	commonUnixBridgeConfig
 	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
 	return nil
 }
 }

+ 159 - 53
daemon/config_test.go → daemon/config/config_test.go

@@ -1,4 +1,4 @@
-package daemon
+package config
 
 
 import (
 import (
 	"io/ioutil"
 	"io/ioutil"
@@ -7,6 +7,7 @@ import (
 	"strings"
 	"strings"
 	"testing"
 	"testing"
 
 
+	"github.com/docker/docker/daemon/discovery"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/testutil/assert"
 	"github.com/docker/docker/pkg/testutil/assert"
 	"github.com/spf13/pflag"
 	"github.com/spf13/pflag"
@@ -39,17 +40,17 @@ func TestParseClusterAdvertiseSettings(t *testing.T) {
 	if runtime.GOOS == "solaris" {
 	if runtime.GOOS == "solaris" {
 		t.Skip("ClusterSettings not supported on Solaris\n")
 		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)
 		t.Fatalf("expected discovery disabled error, got %v\n", err)
 	}
 	}
 
 
-	_, err = parseClusterAdvertiseSettings("", "something")
+	_, err = ParseClusterAdvertiseSettings("", "something")
 	if err == nil {
 	if err == nil {
 		t.Fatalf("expected discovery store error, got %v\n", err)
 		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 {
 	if err != nil {
 		t.Fatal(err)
 		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"},
+				},
+			},
 		},
 		},
-	}
-
-	err := ValidateConfiguration(c1)
-	if err == nil {
-		t.Fatal("expected error, got nil")
-	}
-
-	c2 := &Config{
-		CommonConfig: CommonConfig{
-			Labels: []string{"one=two"},
+		{
+			config: &Config{
+				CommonConfig: CommonConfig{
+					Labels: []string{"foo=bar", "one"},
+				},
+			},
 		},
 		},
-	}
-
-	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"},
+		{
+			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(c3)
-	if err != nil {
-		t.Fatalf("expected no error, got error %v", err)
+	for _, tc := range testCases {
+		err := Validate(tc.config)
+		if err == nil {
+			t.Fatalf("expected error, got nil for config %v", tc.config)
+		}
 	}
 	}
+}
 
 
-	c4 := &Config{
-		CommonConfig: CommonConfig{
-			DNS: []string{"1.1.1.1o"},
+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"},
+				},
+			},
 		},
 		},
 	}
 	}
-
-	err = ValidateConfiguration(c4)
-	if err == nil {
-		t.Fatal("expected error, got nil")
+	for _, tc := range testCases {
+		err := Validate(tc.config)
+		if err != nil {
+			t.Fatalf("expected no error, got error %v", err)
+		}
 	}
 	}
+}
 
 
-	c5 := &Config{
-		CommonConfig: CommonConfig{
-			DNSSearch: []string{"a.b.c"},
+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,
 		},
 		},
 	}
 	}
 
 
-	err = ValidateConfiguration(c5)
-	if err != nil {
-		t.Fatalf("expected no error, got error %v", err)
+	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)
+		}
 	}
 	}
+}
 
 
-	c6 := &Config{
+func discoveryConfig(backendAddr, advertiseAddr string, opts map[string]string) *Config {
+	return &Config{
 		CommonConfig: CommonConfig{
 		CommonConfig: CommonConfig{
-			DNSSearch: []string{"123456"},
+			ClusterStore:     backendAddr,
+			ClusterAdvertise: advertiseAddr,
+			ClusterOpts:      opts,
 		},
 		},
 	}
 	}
-
-	err = ValidateConfiguration(c6)
-	if err == nil {
-		t.Fatal("expected error, got nil")
-	}
 }
 }

+ 62 - 0
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
+}

+ 1 - 24
daemon/config_unix_test.go → daemon/config/config_unix_test.go

@@ -1,15 +1,12 @@
 // +build !windows
 // +build !windows
 
 
-package daemon
+package config
 
 
 import (
 import (
 	"io/ioutil"
 	"io/ioutil"
 	"runtime"
 	"runtime"
 
 
 	"testing"
 	"testing"
-
-	"github.com/docker/docker/pkg/testutil/assert"
-	"github.com/spf13/pflag"
 )
 )
 
 
 func TestDaemonConfigurationMerge(t *testing.T) {
 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) {
 func TestDaemonConfigurationMergeShmSize(t *testing.T) {
 	if runtime.GOOS == "solaris" {
 	if runtime.GOOS == "solaris" {
 		t.Skip("ShmSize not supported on Solaris\n")
 		t.Skip("ShmSize not supported on Solaris\n")

+ 52 - 0
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
+}

+ 1 - 1
daemon/config_windows_test.go → daemon/config/config_windows_test.go

@@ -1,6 +1,6 @@
 // +build windows
 // +build windows
 
 
-package daemon
+package config
 
 
 import (
 import (
 	"io/ioutil"
 	"io/ioutil"

+ 0 - 89
daemon/config_common_unix.go

@@ -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
-}

+ 0 - 8
daemon/config_experimental.go

@@ -1,8 +0,0 @@
-package daemon
-
-import (
-	"github.com/spf13/pflag"
-)
-
-func (config *Config) attachExperimentalFlags(cmd *pflag.FlagSet) {
-}

+ 0 - 110
daemon/config_unix.go

@@ -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
-}

+ 0 - 71
daemon/config_windows.go

@@ -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
-}

+ 1 - 1
daemon/container_operations.go

@@ -282,7 +282,7 @@ func (daemon *Daemon) updateEndpointNetworkSettings(container *container.Contain
 	}
 	}
 
 
 	if container.HostConfig.NetworkMode == runconfig.DefaultDaemonNetworkMode() {
 	if container.HostConfig.NetworkMode == runconfig.DefaultDaemonNetworkMode() {
-		container.NetworkSettings.Bridge = daemon.configStore.bridgeConfig.Iface
+		container.NetworkSettings.Bridge = daemon.configStore.BridgeConfig.Iface
 	}
 	}
 
 
 	return nil
 	return nil

+ 57 - 55
daemon/daemon.go

@@ -24,6 +24,8 @@ import (
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
 	containertypes "github.com/docker/docker/api/types/container"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/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/events"
 	"github.com/docker/docker/daemon/exec"
 	"github.com/docker/docker/daemon/exec"
 	// register graph drivers
 	// register graph drivers
@@ -82,14 +84,14 @@ type Daemon struct {
 	distributionMetadataStore dmetadata.Store
 	distributionMetadataStore dmetadata.Store
 	trustKey                  libtrust.PrivateKey
 	trustKey                  libtrust.PrivateKey
 	idIndex                   *truncindex.TruncIndex
 	idIndex                   *truncindex.TruncIndex
-	configStore               *Config
+	configStore               *config.Config
 	statsCollector            *stats.Collector
 	statsCollector            *stats.Collector
 	defaultLogConfig          containertypes.LogConfig
 	defaultLogConfig          containertypes.LogConfig
 	RegistryService           registry.Service
 	RegistryService           registry.Service
 	EventsService             *events.Events
 	EventsService             *events.Events
 	netController             libnetwork.NetworkController
 	netController             libnetwork.NetworkController
 	volumes                   *store.VolumeStore
 	volumes                   *store.VolumeStore
-	discoveryWatcher          discoveryReloader
+	discoveryWatcher          discovery.Reloader
 	root                      string
 	root                      string
 	seccompEnabled            bool
 	seccompEnabled            bool
 	apparmorEnabled           bool
 	apparmorEnabled           bool
@@ -459,12 +461,12 @@ func (daemon *Daemon) IsSwarmCompatible() error {
 	if daemon.configStore == nil {
 	if daemon.configStore == nil {
 		return nil
 		return nil
 	}
 	}
-	return daemon.configStore.isSwarmCompatible()
+	return daemon.configStore.IsSwarmCompatible()
 }
 }
 
 
 // NewDaemon sets up everything for the daemon to be able to service
 // NewDaemon sets up everything for the daemon to be able to service
 // requests from the webserver.
 // 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)
 	setDefaultMtu(config)
 
 
 	// Ensure that we have a correct root key limit for launching containers.
 	// 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)
 	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.
 	// do nothing if the config does not have the default 0 value.
-	if config.Mtu != 0 {
+	if conf.Mtu != 0 {
 		return
 		return
 	}
 	}
-	config.Mtu = defaultNetworkMtu
+	conf.Mtu = config.DefaultNetworkMtu
 }
 }
 
 
 func (daemon *Daemon) configureVolumes(rootUID, rootGID int) (*store.VolumeStore, error) {
 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.
 // 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 != nil {
-		if err == errDiscoveryDisabled {
+		if err == discovery.ErrDiscoveryDisabled {
 			return nil
 			return nil
 		}
 		}
 		return err
 		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 {
 	if err != nil {
 		return fmt.Errorf("discovery initialization failed (%v)", err)
 		return fmt.Errorf("discovery initialization failed (%v)", err)
 	}
 	}
@@ -1005,60 +1007,60 @@ func (daemon *Daemon) initDiscovery(config *Config) error {
 // - Daemon max concurrent uploads
 // - Daemon max concurrent uploads
 // - Cluster discovery (reconfigure and restart)
 // - Cluster discovery (reconfigure and restart)
 // - Daemon live restore
 // - 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() {
 	defer func() {
 		// we're unlocking here, because
 		// we're unlocking here, because
 		// LogDaemonEventWithAttributes() -> SystemInfo() -> GetAllRuntimes()
 		// LogDaemonEventWithAttributes() -> SystemInfo() -> GetAllRuntimes()
 		// holds that lock too.
 		// holds that lock too.
-		daemon.configStore.reloadLock.Unlock()
+		daemon.configStore.Unlock()
 		if err == nil {
 		if err == nil {
 			daemon.LogDaemonEventWithAttributes("reload", attributes)
 			daemon.LogDaemonEventWithAttributes("reload", attributes)
 		}
 		}
 	}()
 	}()
 
 
-	if err := daemon.reloadClusterDiscovery(config); err != nil {
+	if err := daemon.reloadClusterDiscovery(conf); err != nil {
 		return err
 		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
 			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
 			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
 			return err
 		}
 		}
 	}
 	}
 
 
 	// If no value is set for max-concurrent-downloads we assume it is the default value
 	// 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.
 	// 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 {
 	} else {
-		maxConcurrentDownloads := defaultMaxConcurrentDownloads
+		maxConcurrentDownloads := config.DefaultMaxConcurrentDownloads
 		daemon.configStore.MaxConcurrentDownloads = &maxConcurrentDownloads
 		daemon.configStore.MaxConcurrentDownloads = &maxConcurrentDownloads
 	}
 	}
 	logrus.Debugf("Reset Max Concurrent Downloads: %d", *daemon.configStore.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
 	// 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.
 	// 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 {
 	} else {
-		maxConcurrentUploads := defaultMaxConcurrentUploads
+		maxConcurrentUploads := config.DefaultMaxConcurrentUploads
 		daemon.configStore.MaxConcurrentUploads = &maxConcurrentUploads
 		daemon.configStore.MaxConcurrentUploads = &maxConcurrentUploads
 	}
 	}
 	logrus.Debugf("Reset Max Concurrent Uploads: %d", *daemon.configStore.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)
 		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)
 		logrus.Debugf("Reset Shutdown Timeout: %d", daemon.configStore.ShutdownTimeout)
 	}
 	}
 
 
@@ -1137,52 +1139,52 @@ func (daemon *Daemon) Reload(config *Config) (err error) {
 	return nil
 	return nil
 }
 }
 
 
-func (daemon *Daemon) reloadClusterDiscovery(config *Config) error {
+func (daemon *Daemon) reloadClusterDiscovery(conf *config.Config) error {
 	var err error
 	var err error
 	newAdvertise := daemon.configStore.ClusterAdvertise
 	newAdvertise := daemon.configStore.ClusterAdvertise
 	newClusterStore := daemon.configStore.ClusterStore
 	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
 			return err
 		}
 		}
 	}
 	}
 
 
 	if daemon.clusterProvider != nil {
 	if daemon.clusterProvider != nil {
-		if err := config.isSwarmCompatible(); err != nil {
+		if err := conf.IsSwarmCompatible(); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
 
 
 	// check discovery modifications
 	// check discovery modifications
-	if !modifiedDiscoverySettings(daemon.configStore, newAdvertise, newClusterStore, config.ClusterOpts) {
+	if !config.ModifiedDiscoverySettings(daemon.configStore, newAdvertise, newClusterStore, conf.ClusterOpts) {
 		return nil
 		return nil
 	}
 	}
 
 
 	// enable discovery for the first time if it was not previously enabled
 	// enable discovery for the first time if it was not previously enabled
 	if daemon.discoveryWatcher == nil {
 	if daemon.discoveryWatcher == nil {
-		discoveryWatcher, err := initDiscovery(newClusterStore, newAdvertise, config.ClusterOpts)
+		discoveryWatcher, err := discovery.Init(newClusterStore, newAdvertise, conf.ClusterOpts)
 		if err != nil {
 		if err != nil {
 			return fmt.Errorf("discovery initialization failed (%v)", err)
 			return fmt.Errorf("discovery initialization failed (%v)", err)
 		}
 		}
 		daemon.discoveryWatcher = discoveryWatcher
 		daemon.discoveryWatcher = discoveryWatcher
 	} else {
 	} else {
-		if err == errDiscoveryDisabled {
+		if err == discovery.ErrDiscoveryDisabled {
 			// disable discovery if it was previously enabled and it's disabled now
 			// disable discovery if it was previously enabled and it's disabled now
 			daemon.discoveryWatcher.Stop()
 			daemon.discoveryWatcher.Stop()
 		} else {
 		} else {
 			// reload discovery
 			// 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
 				return err
 			}
 			}
 		}
 		}
 	}
 	}
 
 
 	daemon.configStore.ClusterStore = newClusterStore
 	daemon.configStore.ClusterStore = newClusterStore
-	daemon.configStore.ClusterOpts = config.ClusterOpts
+	daemon.configStore.ClusterOpts = conf.ClusterOpts
 	daemon.configStore.ClusterAdvertise = newAdvertise
 	daemon.configStore.ClusterAdvertise = newAdvertise
 
 
 	if daemon.netController == nil {
 	if daemon.netController == nil {
@@ -1201,11 +1203,11 @@ func (daemon *Daemon) reloadClusterDiscovery(config *Config) error {
 	return nil
 	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{}
 	options := []nwconfig.Option{}
 	if dconfig == nil {
 	if dconfig == nil {
 		return options, nil
 		return options, nil
@@ -1297,7 +1299,7 @@ func (daemon *Daemon) PluginGetter() *plugin.Store {
 }
 }
 
 
 // CreateDaemonRoot creates the root for the daemon
 // 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
 	// get the canonical path to the Docker root directory
 	var realRoot string
 	var realRoot string
 	if _, err := os.Stat(config.Root); err != nil && os.IsNotExist(err) {
 	if _, err := os.Stat(config.Root); err != nil && os.IsNotExist(err) {

+ 33 - 32
daemon/daemon_test.go

@@ -12,6 +12,7 @@ import (
 
 
 	containertypes "github.com/docker/docker/api/types/container"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/container"
+	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/pkg/discovery"
 	"github.com/docker/docker/pkg/discovery"
 	_ "github.com/docker/docker/pkg/discovery/memory"
 	_ "github.com/docker/docker/pkg/discovery/memory"
 	"github.com/docker/docker/pkg/registrar"
 	"github.com/docker/docker/pkg/registrar"
@@ -316,18 +317,18 @@ func TestMerge(t *testing.T) {
 
 
 func TestDaemonReloadLabels(t *testing.T) {
 func TestDaemonReloadLabels(t *testing.T) {
 	daemon := &Daemon{}
 	daemon := &Daemon{}
-	daemon.configStore = &Config{
-		CommonConfig: CommonConfig{
+	daemon.configStore = &config.Config{
+		CommonConfig: config.CommonConfig{
 			Labels: []string{"foo:bar"},
 			Labels: []string{"foo:bar"},
 		},
 		},
 	}
 	}
 
 
 	valuesSets := make(map[string]interface{})
 	valuesSets := make(map[string]interface{})
 	valuesSets["labels"] = "foo:baz"
 	valuesSets["labels"] = "foo:baz"
-	newConfig := &Config{
-		CommonConfig: CommonConfig{
+	newConfig := &config.Config{
+		CommonConfig: config.CommonConfig{
 			Labels:    []string{"foo:baz"},
 			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 {
 	type pair struct {
 		valid   bool
 		valid   bool
@@ -388,12 +389,12 @@ func TestDaemonReloadMirrors(t *testing.T) {
 		valuesSets := make(map[string]interface{})
 		valuesSets := make(map[string]interface{})
 		valuesSets["registry-mirrors"] = value.mirrors
 		valuesSets["registry-mirrors"] = value.mirrors
 
 
-		newConfig := &Config{
-			CommonConfig: CommonConfig{
+		newConfig := &config.Config{
+			CommonConfig: config.CommonConfig{
 				ServiceOptions: registry.ServiceOptions{
 				ServiceOptions: registry.ServiceOptions{
 					Mirrors: value.mirrors,
 					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{
 	insecureRegistries := []string{
 		"127.0.0.0/8",     // this will be kept
 		"127.0.0.0/8",     // this will be kept
@@ -461,12 +462,12 @@ func TestDaemonReloadInsecureRegistries(t *testing.T) {
 	valuesSets := make(map[string]interface{})
 	valuesSets := make(map[string]interface{})
 	valuesSets["insecure-registries"] = insecureRegistries
 	valuesSets["insecure-registries"] = insecureRegistries
 
 
-	newConfig := &Config{
-		CommonConfig: CommonConfig{
+	newConfig := &config.Config{
+		CommonConfig: config.CommonConfig{
 			ServiceOptions: registry.ServiceOptions{
 			ServiceOptions: registry.ServiceOptions{
 				InsecureRegistries: insecureRegistries,
 				InsecureRegistries: insecureRegistries,
 			},
 			},
-			valuesSet: valuesSets,
+			ValuesSet: valuesSets,
 		},
 		},
 	}
 	}
 
 
@@ -523,8 +524,8 @@ func TestDaemonReloadInsecureRegistries(t *testing.T) {
 
 
 func TestDaemonReloadNotAffectOthers(t *testing.T) {
 func TestDaemonReloadNotAffectOthers(t *testing.T) {
 	daemon := &Daemon{}
 	daemon := &Daemon{}
-	daemon.configStore = &Config{
-		CommonConfig: CommonConfig{
+	daemon.configStore = &config.Config{
+		CommonConfig: config.CommonConfig{
 			Labels: []string{"foo:bar"},
 			Labels: []string{"foo:bar"},
 			Debug:  true,
 			Debug:  true,
 		},
 		},
@@ -532,10 +533,10 @@ func TestDaemonReloadNotAffectOthers(t *testing.T) {
 
 
 	valuesSets := make(map[string]interface{})
 	valuesSets := make(map[string]interface{})
 	valuesSets["labels"] = "foo:baz"
 	valuesSets["labels"] = "foo:baz"
-	newConfig := &Config{
-		CommonConfig: CommonConfig{
+	newConfig := &config.Config{
+		CommonConfig: config.CommonConfig{
 			Labels:    []string{"foo:baz"},
 			Labels:    []string{"foo:baz"},
-			valuesSet: valuesSets,
+			ValuesSet: valuesSets,
 		},
 		},
 	}
 	}
 
 
@@ -555,8 +556,8 @@ func TestDaemonReloadNotAffectOthers(t *testing.T) {
 
 
 func TestDaemonDiscoveryReload(t *testing.T) {
 func TestDaemonDiscoveryReload(t *testing.T) {
 	daemon := &Daemon{}
 	daemon := &Daemon{}
-	daemon.configStore = &Config{
-		CommonConfig: CommonConfig{
+	daemon.configStore = &config.Config{
+		CommonConfig: config.CommonConfig{
 			ClusterStore:     "memory://127.0.0.1",
 			ClusterStore:     "memory://127.0.0.1",
 			ClusterAdvertise: "127.0.0.1:3333",
 			ClusterAdvertise: "127.0.0.1:3333",
 		},
 		},
@@ -594,11 +595,11 @@ func TestDaemonDiscoveryReload(t *testing.T) {
 	valuesSets := make(map[string]interface{})
 	valuesSets := make(map[string]interface{})
 	valuesSets["cluster-store"] = "memory://127.0.0.1:2222"
 	valuesSets["cluster-store"] = "memory://127.0.0.1:2222"
 	valuesSets["cluster-advertise"] = "127.0.0.1:5555"
 	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",
 			ClusterStore:     "memory://127.0.0.1:2222",
 			ClusterAdvertise: "127.0.0.1:5555",
 			ClusterAdvertise: "127.0.0.1:5555",
-			valuesSet:        valuesSets,
+			ValuesSet:        valuesSets,
 		},
 		},
 	}
 	}
 
 
@@ -632,16 +633,16 @@ func TestDaemonDiscoveryReload(t *testing.T) {
 
 
 func TestDaemonDiscoveryReloadFromEmptyDiscovery(t *testing.T) {
 func TestDaemonDiscoveryReloadFromEmptyDiscovery(t *testing.T) {
 	daemon := &Daemon{}
 	daemon := &Daemon{}
-	daemon.configStore = &Config{}
+	daemon.configStore = &config.Config{}
 
 
 	valuesSet := make(map[string]interface{})
 	valuesSet := make(map[string]interface{})
 	valuesSet["cluster-store"] = "memory://127.0.0.1:2222"
 	valuesSet["cluster-store"] = "memory://127.0.0.1:2222"
 	valuesSet["cluster-advertise"] = "127.0.0.1:5555"
 	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",
 			ClusterStore:     "memory://127.0.0.1:2222",
 			ClusterAdvertise: "127.0.0.1:5555",
 			ClusterAdvertise: "127.0.0.1:5555",
-			valuesSet:        valuesSet,
+			ValuesSet:        valuesSet,
 		},
 		},
 	}
 	}
 
 
@@ -677,17 +678,17 @@ func TestDaemonDiscoveryReloadFromEmptyDiscovery(t *testing.T) {
 
 
 func TestDaemonDiscoveryReloadOnlyClusterAdvertise(t *testing.T) {
 func TestDaemonDiscoveryReloadOnlyClusterAdvertise(t *testing.T) {
 	daemon := &Daemon{}
 	daemon := &Daemon{}
-	daemon.configStore = &Config{
-		CommonConfig: CommonConfig{
+	daemon.configStore = &config.Config{
+		CommonConfig: config.CommonConfig{
 			ClusterStore: "memory://127.0.0.1",
 			ClusterStore: "memory://127.0.0.1",
 		},
 		},
 	}
 	}
 	valuesSets := make(map[string]interface{})
 	valuesSets := make(map[string]interface{})
 	valuesSets["cluster-advertise"] = "127.0.0.1:5555"
 	valuesSets["cluster-advertise"] = "127.0.0.1:5555"
-	newConfig := &Config{
-		CommonConfig: CommonConfig{
+	newConfig := &config.Config{
+		CommonConfig: config.CommonConfig{
 			ClusterAdvertise: "127.0.0.1:5555",
 			ClusterAdvertise: "127.0.0.1:5555",
-			valuesSet:        valuesSets,
+			ValuesSet:        valuesSets,
 		},
 		},
 	}
 	}
 	expected := discovery.Entries{
 	expected := discovery.Entries{

+ 58 - 57
daemon/daemon_unix.go

@@ -23,6 +23,7 @@ import (
 	pblkiodev "github.com/docker/docker/api/types/blkiodev"
 	pblkiodev "github.com/docker/docker/api/types/blkiodev"
 	containertypes "github.com/docker/docker/api/types/container"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/container"
+	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/idtools"
@@ -256,7 +257,7 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf
 		hostConfig.MemorySwap = hostConfig.Memory * 2
 		hostConfig.MemorySwap = hostConfig.Memory * 2
 	}
 	}
 	if hostConfig.ShmSize == 0 {
 	if hostConfig.ShmSize == 0 {
-		hostConfig.ShmSize = defaultShmSize
+		hostConfig.ShmSize = config.DefaultShmSize
 		if daemon.configStore != nil {
 		if daemon.configStore != nil {
 			hostConfig.ShmSize = int64(daemon.configStore.ShmSize)
 			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.
 // 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 {
 	for _, option := range config.ExecOptions {
 		key, val, err := parsers.ParseKeyValueOpt(option)
 		key, val, err := parsers.ParseKeyValueOpt(option)
 		if err != nil || !strings.EqualFold(key, "native.cgroupdriver") {
 		if err != nil || !strings.EqualFold(key, "native.cgroupdriver") {
@@ -486,7 +487,7 @@ func getCD(config *Config) string {
 }
 }
 
 
 // VerifyCgroupDriver validates native.cgroupdriver
 // VerifyCgroupDriver validates native.cgroupdriver
-func VerifyCgroupDriver(config *Config) error {
+func VerifyCgroupDriver(config *config.Config) error {
 	cd := getCD(config)
 	cd := getCD(config)
 	if cd == "" || cd == cgroupFsDriver || cd == cgroupSystemdDriver {
 	if cd == "" || cd == cgroupFsDriver || cd == cgroupSystemdDriver {
 		return nil
 		return nil
@@ -495,7 +496,7 @@ func VerifyCgroupDriver(config *Config) error {
 }
 }
 
 
 // UsingSystemd returns true if cli option includes native.cgroupdriver=systemd
 // 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
 	return getCD(config) == cgroupSystemdDriver
 }
 }
 
 
@@ -568,19 +569,19 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
 }
 }
 
 
 // platformReload updates configuration with platform specific options
 // 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
 		// 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
 	// Update attributes
@@ -600,33 +601,33 @@ func (daemon *Daemon) platformReload(config *Config) map[string]string {
 }
 }
 
 
 // verifyDaemonSettings performs validation of daemon config struct
 // verifyDaemonSettings performs validation of daemon config struct
-func verifyDaemonSettings(config *Config) error {
+func verifyDaemonSettings(conf *config.Config) error {
 	// Check for mutually incompatible config options
 	// 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")
 		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")
 		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
 		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\"")
 			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
 	return nil
 }
 }
@@ -641,7 +642,7 @@ func checkSystem() error {
 
 
 // configureMaxThreads sets the Go runtime max threads threshold
 // configureMaxThreads sets the Go runtime max threads threshold
 // which is 90% of the kernel setting from /proc/sys/kernel/threads-max
 // 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")
 	mt, err := ioutil.ReadFile("/proc/sys/kernel/threads-max")
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -688,7 +689,7 @@ func overlaySupportsSelinux() (bool, error) {
 }
 }
 
 
 // configureKernelSecuritySupport configures and validates security support for the kernel
 // 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 config.EnableSelinuxSupport {
 		if !selinuxEnabled() {
 		if !selinuxEnabled() {
 			logrus.Warn("Docker could not enable SELinux on the host system")
 			logrus.Warn("Docker could not enable SELinux on the host system")
@@ -713,7 +714,7 @@ func configureKernelSecuritySupport(config *Config, driverName string) error {
 	return nil
 	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)
 	netOptions, err := daemon.networkOptions(config, daemon.PluginStore, activeSandboxes)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -762,12 +763,12 @@ func (daemon *Daemon) initNetworkController(config *Config, activeSandboxes map[
 	return controller, nil
 	return controller, nil
 }
 }
 
 
-func driverOptions(config *Config) []nwconfig.Option {
+func driverOptions(config *config.Config) []nwconfig.Option {
 	bridgeConfig := options.Generic{
 	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}
 	bridgeOption := options.Generic{netlabel.GenericData: bridgeConfig}
 
 
 	dOptions := []nwconfig.Option{}
 	dOptions := []nwconfig.Option{}
@@ -775,22 +776,22 @@ func driverOptions(config *Config) []nwconfig.Option {
 	return dOptions
 	return dOptions
 }
 }
 
 
-func initBridgeDriver(controller libnetwork.NetworkController, config *Config) error {
+func initBridgeDriver(controller libnetwork.NetworkController, config *config.Config) error {
 	bridgeName := bridge.DefaultBridgeName
 	bridgeName := bridge.DefaultBridgeName
-	if config.bridgeConfig.Iface != "" {
-		bridgeName = config.bridgeConfig.Iface
+	if config.BridgeConfig.Iface != "" {
+		bridgeName = config.BridgeConfig.Iface
 	}
 	}
 	netOption := map[string]string{
 	netOption := map[string]string{
 		bridge.BridgeName:         bridgeName,
 		bridge.BridgeName:         bridgeName,
 		bridge.DefaultBridge:      strconv.FormatBool(true),
 		bridge.DefaultBridge:      strconv.FormatBool(true),
 		netlabel.DriverMTU:        strconv.Itoa(config.Mtu),
 		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
 	// --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 (
 	var (
@@ -806,8 +807,8 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
 	}
 	}
 
 
 	nw := nwList[0]
 	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 {
 		if err != nil {
 			return errors.Wrap(err, "parse CIDR failed")
 			return errors.Wrap(err, "parse CIDR failed")
 		}
 		}
@@ -826,9 +827,9 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
 		ipamV4Conf.Gateway = nw.IP.String()
 		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 {
 		if err != nil {
 			return err
 			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)
 		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 {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -846,13 +847,13 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
 		ipamV4Conf.SubPool = fCIDR.String()
 		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
 	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 {
 		if err != nil {
 			return err
 			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 {
 		if ipamV6Conf == nil {
 			ipamV6Conf = &libnetwork.IpamConf{AuxAddresses: make(map[string]string)}
 			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}
 	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
 	// Initialize default network on "bridge" with the same name
 	_, err = controller.NewNetwork("bridge", "bridge", "",
 	_, err = controller.NewNetwork("bridge", "bridge", "",
-		libnetwork.NetworkOptionEnableIPv6(config.bridgeConfig.EnableIPv6),
+		libnetwork.NetworkOptionEnableIPv6(config.BridgeConfig.EnableIPv6),
 		libnetwork.NetworkOptionDriverOpts(netOption),
 		libnetwork.NetworkOptionDriverOpts(netOption),
 		libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf, nil),
 		libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf, nil),
 		libnetwork.NetworkOptionDeferIPv6Alloc(deferIPv6Alloc))
 		libnetwork.NetworkOptionDeferIPv6Alloc(deferIPv6Alloc))
@@ -1012,7 +1013,7 @@ func parseRemappedRoot(usergrp string) (string, string, error) {
 	return username, groupname, nil
 	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 != "" {
 	if runtime.GOOS != "linux" && config.RemappedRoot != "" {
 		return nil, nil, fmt.Errorf("User namespaces are only supported on Linux")
 		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
 	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
 	config.Root = rootDir
 	// the docker root metadata directory needs to have execute permissions for all users (g+x,o+x)
 	// 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
 	// 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
 // 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
 	// setup the daemons oom_score_adj
 	return setupOOMScoreAdj(config.OOMScoreAdjust)
 	return setupOOMScoreAdj(config.OOMScoreAdjust)
 }
 }

+ 5 - 4
daemon/daemon_unix_test.go

@@ -10,6 +10,7 @@ import (
 
 
 	containertypes "github.com/docker/docker/api/types/container"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/container"
+	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/volume"
 	"github.com/docker/docker/volume"
 	"github.com/docker/docker/volume/drivers"
 	"github.com/docker/docker/volume/drivers"
 	"github.com/docker/docker/volume/local"
 	"github.com/docker/docker/volume/local"
@@ -181,8 +182,8 @@ func TestParseSecurityOpt(t *testing.T) {
 
 
 func TestNetworkOptions(t *testing.T) {
 func TestNetworkOptions(t *testing.T) {
 	daemon := &Daemon{}
 	daemon := &Daemon{}
-	dconfigCorrect := &Config{
-		CommonConfig: CommonConfig{
+	dconfigCorrect := &config.Config{
+		CommonConfig: config.CommonConfig{
 			ClusterStore:     "consul://localhost:8500",
 			ClusterStore:     "consul://localhost:8500",
 			ClusterAdvertise: "192.168.0.1:8000",
 			ClusterAdvertise: "192.168.0.1:8000",
 		},
 		},
@@ -192,8 +193,8 @@ func TestNetworkOptions(t *testing.T) {
 		t.Fatalf("Expect networkOptions success, got error: %v", err)
 		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",
 			ClusterStore: "consul://localhost:8500://test://bbb",
 		},
 		},
 	}
 	}

+ 13 - 12
daemon/daemon_windows.go

@@ -11,6 +11,7 @@ import (
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
 	containertypes "github.com/docker/docker/api/types/container"
 	containertypes "github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/container"
+	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/parsers"
@@ -210,12 +211,12 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
 }
 }
 
 
 // platformReload updates configuration with platform specific options
 // 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{}
 	return map[string]string{}
 }
 }
 
 
 // verifyDaemonSettings performs validation of daemon config struct
 // verifyDaemonSettings performs validation of daemon config struct
-func verifyDaemonSettings(config *Config) error {
+func verifyDaemonSettings(config *config.Config) error {
 	return nil
 	return nil
 }
 }
 
 
@@ -239,16 +240,16 @@ func checkSystem() error {
 }
 }
 
 
 // configureKernelSecuritySupport configures and validate security support for the kernel
 // 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
 	return nil
 }
 }
 
 
 // configureMaxThreads sets the Go runtime max threads threshold
 // configureMaxThreads sets the Go runtime max threads threshold
-func configureMaxThreads(config *Config) error {
+func configureMaxThreads(config *config.Config) error {
 	return nil
 	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)
 	netOptions, err := daemon.networkOptions(config, nil, nil)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -376,7 +377,7 @@ func (daemon *Daemon) initNetworkController(config *Config, activeSandboxes map[
 	return controller, nil
 	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 {
 	if _, err := controller.NetworkByName(runconfig.DefaultDaemonNetworkMode().NetworkName()); err == nil {
 		return nil
 		return nil
 	}
 	}
@@ -388,8 +389,8 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
 	var ipamOption libnetwork.NetworkOption
 	var ipamOption libnetwork.NetworkOption
 	var subnetPrefix string
 	var subnetPrefix string
 
 
-	if config.bridgeConfig.FixedCIDR != "" {
-		subnetPrefix = config.bridgeConfig.FixedCIDR
+	if config.BridgeConfig.FixedCIDR != "" {
+		subnetPrefix = config.BridgeConfig.FixedCIDR
 	} else {
 	} else {
 		// TP5 doesn't support properly detecting subnet
 		// TP5 doesn't support properly detecting subnet
 		osv := system.GetOSVersion()
 		osv := system.GetOSVersion()
@@ -434,11 +435,11 @@ func (daemon *Daemon) cleanupMounts() error {
 	return nil
 	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
 	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
 	config.Root = rootDir
 	// Create the root directory if it doesn't exists
 	// Create the root directory if it doesn't exists
 	if err := system.MkdirAllWithACL(config.Root, 0); err != nil && !os.IsExist(err) {
 	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
 	return nil
 }
 }
 
 
-func driverOptions(config *Config) []nwconfig.Option {
+func driverOptions(config *config.Config) []nwconfig.Option {
 	return []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
 	return nil
 }
 }
 
 

+ 7 - 21
daemon/discovery.go → daemon/discovery/discovery.go

@@ -1,9 +1,8 @@
-package daemon
+package discovery
 
 
 import (
 import (
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
-	"reflect"
 	"strconv"
 	"strconv"
 	"time"
 	"time"
 
 
@@ -21,9 +20,11 @@ const (
 	defaultDiscoveryTTLFactor = 3
 	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
 	discovery.Watcher
 	Stop()
 	Stop()
 	Reload(backend, address string, clusterOpts map[string]string) error
 	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
 	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.
 // 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)
 	heartbeat, backend, err := parseDiscoveryOptions(backendAddress, clusterOpts)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
@@ -198,18 +199,3 @@ func parseDiscoveryOptions(backendAddress string, clusterOpts map[string]string)
 	}
 	}
 	return heartbeat, backend, nil
 	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)
-}

+ 1 - 62
daemon/discovery_test.go → daemon/discovery/discovery_test.go

@@ -1,4 +1,4 @@
-package daemon
+package discovery
 
 
 import (
 import (
 	"testing"
 	"testing"
@@ -101,64 +101,3 @@ func TestDiscoveryOpts(t *testing.T) {
 		t.Fatalf("TTL - Expected : %v, Actual : %v", expected, ttl)
 		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,
-		},
-	}
-}