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>
This commit is contained in:
Vincent Demeester 2017-01-23 12:23:07 +01:00
parent 41650df87e
commit db63f9370e
No known key found for this signature in database
GPG key ID: 083CC6FD6EB699A3
32 changed files with 900 additions and 748 deletions

52
cmd/dockerd/config.go Normal file
View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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) { func loadDaemonCliConfig(opts daemonOptions) (*config.Config, error) {
config := opts.daemonConfig conf := opts.daemonConfig
flags := opts.flags flags := opts.flags
config.Debug = opts.common.Debug conf.Debug = opts.common.Debug
config.Hosts = opts.common.Hosts conf.Hosts = opts.common.Hosts
config.LogLevel = opts.common.LogLevel conf.LogLevel = opts.common.LogLevel
config.TLS = opts.common.TLS conf.TLS = opts.common.TLS
config.TLSVerify = opts.common.TLSVerify conf.TLSVerify = opts.common.TLSVerify
config.CommonTLSOptions = daemon.CommonTLSOptions{} conf.CommonTLSOptions = config.CommonTLSOptions{}
if opts.common.TLSOptions != nil { if opts.common.TLSOptions != nil {
config.CommonTLSOptions.CAFile = opts.common.TLSOptions.CAFile conf.CommonTLSOptions.CAFile = opts.common.TLSOptions.CAFile
config.CommonTLSOptions.CertFile = opts.common.TLSOptions.CertFile conf.CommonTLSOptions.CertFile = opts.common.TLSOptions.CertFile
config.CommonTLSOptions.KeyFile = opts.common.TLSOptions.KeyFile 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) { if conf.IsValueSet(cliflags.FlagTLSVerify) {
config.TLS = true 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) {

View file

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

View file

@ -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) {

View file

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

View file

@ -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 DefaultMaxConcurrentDownloads = 3
// defaultMaxConcurrentUploads is the default value for // 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 DefaultMaxConcurrentUploads = 5
// stockRuntimeName is the reserved name/alias used to represent the // 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" StockRuntimeName = "runc"
) // DefaultShmSize is the default value for container's shm size
DefaultShmSize = int64(67108864)
const ( // DefaultNetworkMtu is the default value for network MTU
defaultNetworkMtu = 1500 DefaultNetworkMtu = 1500
disableNetworkBridge = "none" // DisableNetworkBridge is the default value of the option to disable network bridge
) DisableNetworkBridge = "none"
const (
defaultShutdownTimeout = 15
) )
// 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 sync.Mutex
valuesSet map[string]interface{} // 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 { func (conf *Config) IsValueSet(name string) bool {
if config.valuesSet == nil { 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 // New returns a new fully initialized Config struct
func NewConfig() *Config { 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. // Reload reads the configuration in the host and reloads the daemon and server.
func ReloadConfiguration(configFile string, flags *pflag.FlagSet, reload func(*Config)) error { 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 { if _, ok := runtimes[StockRuntimeName]; ok {
return fmt.Errorf("runtime name '%s' is reserved", stockRuntimeName) 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 { func (conf *Config) GetAuthorizationPlugins() []string {
config.reloadLock.Lock() conf.Lock()
defer config.reloadLock.Unlock() defer conf.Unlock()
authPlugins := make([]string, 0, len(config.AuthorizationPlugins)) authPlugins := make([]string, 0, len(conf.AuthorizationPlugins))
for _, p := range config.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)
}

View file

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

View file

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

View file

@ -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 // IsSwarmCompatible defines if swarm mode can be enabled in this config
// the current process. func (conf *Config) IsSwarmCompatible() error {
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 {
return nil return nil
} }

View file

@ -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", "") _, err := ParseClusterAdvertiseSettings("something", "")
if err != errDiscoveryDisabled { 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) { func TestValidateConfigurationErrors(t *testing.T) {
c1 := &Config{ minusNumber := -10
testCases := []struct {
config *Config
}{
{
config: &Config{
CommonConfig: CommonConfig{ CommonConfig: CommonConfig{
Labels: []string{"one"}, Labels: []string{"one"},
}, },
}
err := ValidateConfiguration(c1)
if err == nil {
t.Fatal("expected error, got nil")
}
c2 := &Config{
CommonConfig: CommonConfig{
Labels: []string{"one=two"},
}, },
}
err = ValidateConfiguration(c2)
if err != nil {
t.Fatalf("expected no error, got error %v", err)
}
c3 := &Config{
CommonConfig: CommonConfig{
DNS: []string{"1.1.1.1"},
}, },
} {
config: &Config{
err = ValidateConfiguration(c3) CommonConfig: CommonConfig{
if err != nil { Labels: []string{"foo=bar", "one"},
t.Fatalf("expected no error, got error %v", err) },
} },
},
c4 := &Config{ {
config: &Config{
CommonConfig: CommonConfig{ CommonConfig: CommonConfig{
DNS: []string{"1.1.1.1o"}, DNS: []string{"1.1.1.1o"},
}, },
}
err = ValidateConfiguration(c4)
if err == nil {
t.Fatal("expected error, got nil")
}
c5 := &Config{
CommonConfig: CommonConfig{
DNSSearch: []string{"a.b.c"},
}, },
} },
{
err = ValidateConfiguration(c5) config: &Config{
if err != nil { CommonConfig: CommonConfig{
t.Fatalf("expected no error, got error %v", err) DNS: []string{"2.2.2.2", "1.1.1.1o"},
} },
},
c6 := &Config{ },
{
config: &Config{
CommonConfig: CommonConfig{ CommonConfig: CommonConfig{
DNSSearch: []string{"123456"}, 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,
},
},
},
},
}
for _, tc := range testCases {
err := Validate(tc.config)
if err == nil {
t.Fatalf("expected error, got nil for config %v", tc.config)
}
}
} }
err = ValidateConfiguration(c6) func TestValidateConfiguration(t *testing.T) {
if err == nil { testCases := []struct {
t.Fatal("expected error, got nil") config *Config
}{
{
config: &Config{
CommonConfig: CommonConfig{
Labels: []string{"one=two"},
},
},
},
{
config: &Config{
CommonConfig: CommonConfig{
DNS: []string{"1.1.1.1"},
},
},
},
{
config: &Config{
CommonConfig: CommonConfig{
DNSSearch: []string{"a.b.c"},
},
},
},
}
for _, tc := range testCases {
err := Validate(tc.config)
if err != nil {
t.Fatalf("expected no error, got error %v", err)
}
}
}
func TestModifiedDiscoverySettings(t *testing.T) {
cases := []struct {
current *Config
modified *Config
expected bool
}{
{
current: discoveryConfig("foo", "bar", map[string]string{}),
modified: discoveryConfig("foo", "bar", map[string]string{}),
expected: false,
},
{
current: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}),
modified: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}),
expected: false,
},
{
current: discoveryConfig("foo", "bar", map[string]string{}),
modified: discoveryConfig("foo", "bar", nil),
expected: false,
},
{
current: discoveryConfig("foo", "bar", nil),
modified: discoveryConfig("foo", "bar", map[string]string{}),
expected: false,
},
{
current: discoveryConfig("foo", "bar", nil),
modified: discoveryConfig("baz", "bar", nil),
expected: true,
},
{
current: discoveryConfig("foo", "bar", nil),
modified: discoveryConfig("foo", "baz", nil),
expected: true,
},
{
current: discoveryConfig("foo", "bar", nil),
modified: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}),
expected: true,
},
}
for _, c := range cases {
got := ModifiedDiscoverySettings(c.current, c.modified.ClusterStore, c.modified.ClusterAdvertise, c.modified.ClusterOpts)
if c.expected != got {
t.Fatalf("expected %v, got %v: current config %v, new config %v", c.expected, got, c.current, c.modified)
}
}
}
func discoveryConfig(backendAddr, advertiseAddr string, opts map[string]string) *Config {
return &Config{
CommonConfig: CommonConfig{
ClusterStore: backendAddr,
ClusterAdvertise: advertiseAddr,
ClusterOpts: opts,
},
} }
} }

View file

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

View file

@ -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")

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 { func (daemon *Daemon) initDiscovery(conf *config.Config) error {
advertise, err := parseClusterAdvertiseSettings(config.ClusterStore, config.ClusterAdvertise) 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 conf.ClusterAdvertise = advertise
discoveryWatcher, err := initDiscovery(config.ClusterStore, config.ClusterAdvertise, config.ClusterOpts) 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) // - Daemon shutdown timeout (in seconds).
func (daemon *Daemon) Reload(config *Config) (err error) { 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") { if conf.IsValueSet("labels") {
daemon.configStore.Labels = config.Labels daemon.configStore.Labels = conf.Labels
} }
if config.IsValueSet("debug") { if conf.IsValueSet("debug") {
daemon.configStore.Debug = config.Debug daemon.configStore.Debug = conf.Debug
} }
if config.IsValueSet("insecure-registries") { if conf.IsValueSet("insecure-registries") {
daemon.configStore.InsecureRegistries = config.InsecureRegistries daemon.configStore.InsecureRegistries = conf.InsecureRegistries
if err := daemon.RegistryService.LoadInsecureRegistries(config.InsecureRegistries); err != nil { if err := daemon.RegistryService.LoadInsecureRegistries(conf.InsecureRegistries); err != nil {
return err return err
} }
} }
if config.IsValueSet("registry-mirrors") { if conf.IsValueSet("registry-mirrors") {
daemon.configStore.Mirrors = config.Mirrors daemon.configStore.Mirrors = conf.Mirrors
if err := daemon.RegistryService.LoadMirrors(config.Mirrors); err != nil { if err := daemon.RegistryService.LoadMirrors(conf.Mirrors); err != nil {
return err return err
} }
} }
if config.IsValueSet("live-restore") { if conf.IsValueSet("live-restore") {
daemon.configStore.LiveRestoreEnabled = config.LiveRestoreEnabled daemon.configStore.LiveRestoreEnabled = conf.LiveRestoreEnabled
if err := daemon.containerdRemote.UpdateOptions(libcontainerd.WithLiveRestore(config.LiveRestoreEnabled)); err != nil { 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 { if conf.IsValueSet("max-concurrent-downloads") && conf.MaxConcurrentDownloads != nil {
*daemon.configStore.MaxConcurrentDownloads = *config.MaxConcurrentDownloads *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 { if conf.IsValueSet("max-concurrent-uploads") && conf.MaxConcurrentUploads != nil {
*daemon.configStore.MaxConcurrentUploads = *config.MaxConcurrentUploads *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") { if conf.IsValueSet("shutdown-timeout") {
daemon.configStore.ShutdownTimeout = config.ShutdownTimeout 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 conf.IsValueSet("cluster-advertise") {
if config.IsValueSet("cluster-store") { if conf.IsValueSet("cluster-store") {
newClusterStore = config.ClusterStore newClusterStore = conf.ClusterStore
} }
newAdvertise, err = parseClusterAdvertiseSettings(newClusterStore, config.ClusterAdvertise) newAdvertise, err = config.ParseClusterAdvertiseSettings(newClusterStore, conf.ClusterAdvertise)
if err != nil && err != errDiscoveryDisabled { 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 { func isBridgeNetworkDisabled(conf *config.Config) bool {
return config.bridgeConfig.Iface == disableNetworkBridge 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) {

View file

@ -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{ daemon.configStore = &config.Config{
CommonConfig: CommonConfig{ 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{ newConfig := &config.Config{
CommonConfig: CommonConfig{ 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{ newConfig := &config.Config{
CommonConfig: CommonConfig{ 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{ newConfig := &config.Config{
CommonConfig: CommonConfig{ 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{ daemon.configStore = &config.Config{
CommonConfig: CommonConfig{ 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{ newConfig := &config.Config{
CommonConfig: CommonConfig{ 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{ daemon.configStore = &config.Config{
CommonConfig: CommonConfig{ 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{ newConfig := &config.Config{
CommonConfig: CommonConfig{ 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{ newConfig := &config.Config{
CommonConfig: CommonConfig{ 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{ daemon.configStore = &config.Config{
CommonConfig: CommonConfig{ 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{ newConfig := &config.Config{
CommonConfig: CommonConfig{ 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{

View file

@ -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 { func (daemon *Daemon) platformReload(conf *config.Config) map[string]string {
if config.IsValueSet("runtimes") { if conf.IsValueSet("runtimes") {
daemon.configStore.Runtimes = config.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 != "" { if conf.DefaultRuntime != "" {
daemon.configStore.DefaultRuntime = config.DefaultRuntime daemon.configStore.DefaultRuntime = conf.DefaultRuntime
} }
if config.IsValueSet("default-shm-size") { if conf.IsValueSet("default-shm-size") {
daemon.configStore.ShmSize = config.ShmSize 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 { if !conf.BridgeConfig.EnableIPTables && conf.BridgeConfig.EnableIPMasq {
config.bridgeConfig.EnableIPMasq = false 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 conf.CgroupParent != "" && UsingSystemd(conf) {
if len(config.CgroupParent) <= 6 || !strings.HasSuffix(config.CgroupParent, ".slice") { 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 == "" { if conf.DefaultRuntime == "" {
config.DefaultRuntime = stockRuntimeName conf.DefaultRuntime = config.StockRuntimeName
} }
if config.Runtimes == nil { if conf.Runtimes == nil {
config.Runtimes = make(map[string]types.Runtime) 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, "EnableIPForwarding": config.BridgeConfig.EnableIPForward,
"EnableIPTables": config.bridgeConfig.EnableIPTables, "EnableIPTables": config.BridgeConfig.EnableIPTables,
"EnableUserlandProxy": config.bridgeConfig.EnableUserlandProxy, "EnableUserlandProxy": config.BridgeConfig.EnableUserlandProxy,
"UserlandProxyPath": config.bridgeConfig.UserlandProxyPath} "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 != "" { if config.BridgeConfig.Iface != "" {
bridgeName = 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.EnableIPMasquerade: strconv.FormatBool(config.BridgeConfig.EnableIPMasq),
bridge.EnableICC: strconv.FormatBool(config.bridgeConfig.InterContainerCommunication), bridge.EnableICC: strconv.FormatBool(config.BridgeConfig.InterContainerCommunication),
} }
// --ip processing // --ip processing
if config.bridgeConfig.DefaultIP != nil { if config.BridgeConfig.DefaultIP != nil {
netOption[bridge.DefaultBindingIP] = config.bridgeConfig.DefaultIP.String() 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 != "" { if len(nwList) > 1 && config.BridgeConfig.FixedCIDR != "" {
_, fCIDR, err := net.ParseCIDR(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 != "" { if config.BridgeConfig.IP != "" {
ipamV4Conf.PreferredPool = config.bridgeConfig.IP ipamV4Conf.PreferredPool = config.BridgeConfig.IP
ip, _, err := net.ParseCIDR(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 != "" { if config.BridgeConfig.FixedCIDR != "" {
_, fCIDR, err := net.ParseCIDR(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 { if config.BridgeConfig.DefaultGatewayIPv4 != nil {
ipamV4Conf.AuxAddresses["DefaultGatewayIPv4"] = config.bridgeConfig.DefaultGatewayIPv4.String() ipamV4Conf.AuxAddresses["DefaultGatewayIPv4"] = config.BridgeConfig.DefaultGatewayIPv4.String()
} }
var deferIPv6Alloc bool var deferIPv6Alloc bool
if config.bridgeConfig.FixedCIDRv6 != "" { if config.BridgeConfig.FixedCIDRv6 != "" {
_, fCIDRv6, err := net.ParseCIDR(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)
} }

View file

@ -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{ dconfigCorrect := &config.Config{
CommonConfig: CommonConfig{ 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{ dconfigWrong := &config.Config{
CommonConfig: CommonConfig{ CommonConfig: config.CommonConfig{
ClusterStore: "consul://localhost:8500://test://bbb", ClusterStore: "consul://localhost:8500://test://bbb",
}, },
} }

View file

@ -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 != "" { if config.BridgeConfig.FixedCIDR != "" {
subnetPrefix = 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
} }

View file

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

View file

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