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"
"github.com/docker/docker/daemon"
"github.com/docker/docker/daemon/cluster"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/daemon/logger"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/libcontainerd"
@ -54,7 +55,7 @@ const (
// DaemonCli represents the daemon CLI.
type DaemonCli struct {
*daemon.Config
*config.Config
configFile *string
flags *pflag.FlagSet
@ -68,7 +69,7 @@ func NewDaemonCli() *DaemonCli {
return &DaemonCli{}
}
func migrateKey(config *daemon.Config) (err error) {
func migrateKey(config *config.Config) (err error) {
// No migration necessary on Windows
if runtime.GOOS == "windows" {
return nil
@ -335,7 +336,7 @@ func (cli *DaemonCli) start(opts daemonOptions) (err error) {
}
func (cli *DaemonCli) reloadConfig() {
reload := func(config *daemon.Config) {
reload := func(config *config.Config) {
// Revalidate and reload the authorization plugins
if err := validateAuthzPlugins(config.AuthorizationPlugins, cli.d.PluginStore); err != nil {
@ -363,7 +364,7 @@ func (cli *DaemonCli) reloadConfig() {
}
}
if err := daemon.ReloadConfiguration(*cli.configFile, cli.flags, reload); err != nil {
if err := config.Reload(*cli.configFile, cli.flags, reload); err != nil {
logrus.Error(err)
}
}
@ -395,24 +396,24 @@ func shutdownDaemon(d *daemon.Daemon) {
}
}
func loadDaemonCliConfig(opts daemonOptions) (*daemon.Config, error) {
config := opts.daemonConfig
func loadDaemonCliConfig(opts daemonOptions) (*config.Config, error) {
conf := opts.daemonConfig
flags := opts.flags
config.Debug = opts.common.Debug
config.Hosts = opts.common.Hosts
config.LogLevel = opts.common.LogLevel
config.TLS = opts.common.TLS
config.TLSVerify = opts.common.TLSVerify
config.CommonTLSOptions = daemon.CommonTLSOptions{}
conf.Debug = opts.common.Debug
conf.Hosts = opts.common.Hosts
conf.LogLevel = opts.common.LogLevel
conf.TLS = opts.common.TLS
conf.TLSVerify = opts.common.TLSVerify
conf.CommonTLSOptions = config.CommonTLSOptions{}
if opts.common.TLSOptions != nil {
config.CommonTLSOptions.CAFile = opts.common.TLSOptions.CAFile
config.CommonTLSOptions.CertFile = opts.common.TLSOptions.CertFile
config.CommonTLSOptions.KeyFile = opts.common.TLSOptions.KeyFile
conf.CommonTLSOptions.CAFile = opts.common.TLSOptions.CAFile
conf.CommonTLSOptions.CertFile = opts.common.TLSOptions.CertFile
conf.CommonTLSOptions.KeyFile = opts.common.TLSOptions.KeyFile
}
if opts.configFile != "" {
c, err := daemon.MergeDaemonConfigurations(config, flags, opts.configFile)
c, err := config.MergeDaemonConfigurations(conf, flags, opts.configFile)
if err != nil {
if flags.Changed(flagDaemonConfigFile) || !os.IsNotExist(err) {
return nil, fmt.Errorf("unable to configure the Docker daemon with file %s: %v\n", opts.configFile, err)
@ -421,11 +422,11 @@ func loadDaemonCliConfig(opts daemonOptions) (*daemon.Config, error) {
// the merged configuration can be nil if the config file didn't exist.
// leave the current configuration as it is if when that happens.
if c != nil {
config = c
conf = c
}
}
if err := daemon.ValidateConfiguration(config); err != nil {
if err := config.Validate(conf); err != nil {
return nil, err
}
@ -442,20 +443,20 @@ func loadDaemonCliConfig(opts daemonOptions) (*daemon.Config, error) {
// }
// config.Labels = newLabels
//
if _, err := daemon.GetConflictFreeLabels(config.Labels); err != nil {
if _, err := config.GetConflictFreeLabels(conf.Labels); err != nil {
logrus.Warnf("Engine labels with duplicate keys and conflicting values have been deprecated: %s", err)
}
// Regardless of whether the user sets it to true or false, if they
// specify TLSVerify at all then we need to turn on TLS
if config.IsValueSet(cliflags.FlagTLSVerify) {
config.TLS = true
if conf.IsValueSet(cliflags.FlagTLSVerify) {
conf.TLS = true
}
// ensure that the log level is the one set after merging configurations
cliflags.SetLogLevel(config.LogLevel)
cliflags.SetLogLevel(conf.LogLevel)
return config, nil
return conf, nil
}
func initRouter(s *apiserver.Server, d *daemon.Daemon, c *cluster.Cluster) {

View file

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

View file

@ -6,10 +6,11 @@
package main
import (
"github.com/docker/docker/daemon"
"testing"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/pkg/testutil/assert"
"github.com/docker/docker/pkg/testutil/tempfile"
"testing"
)
func TestLoadDaemonCliConfigWithDaemonFlags(t *testing.T) {
@ -82,10 +83,10 @@ func TestLoadDaemonConfigWithTrueDefaultValues(t *testing.T) {
// make sure reloading doesn't generate configuration
// conflicts after normalizing boolean values.
reload := func(reloadedConfig *daemon.Config) {
reload := func(reloadedConfig *config.Config) {
assert.Equal(t, reloadedConfig.EnableUserlandProxy, false)
}
assert.NilError(t, daemon.ReloadConfiguration(opts.configFile, opts.flags, reload))
assert.NilError(t, config.Reload(opts.configFile, opts.flags, reload))
}
func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) {

View file

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

View file

@ -1,4 +1,4 @@
package daemon
package config
import (
"bytes"
@ -7,12 +7,14 @@ import (
"fmt"
"io"
"io/ioutil"
"reflect"
"runtime"
"sort"
"strings"
"sync"
"github.com/Sirupsen/logrus"
daemondiscovery "github.com/docker/docker/daemon/discovery"
"github.com/docker/docker/opts"
"github.com/docker/docker/pkg/discovery"
"github.com/docker/docker/registry"
@ -21,26 +23,23 @@ import (
)
const (
// defaultMaxConcurrentDownloads is the default value for
// DefaultMaxConcurrentDownloads is the default value for
// maximum number of downloads that
// may take place at a time for each pull.
defaultMaxConcurrentDownloads = 3
// defaultMaxConcurrentUploads is the default value for
DefaultMaxConcurrentDownloads = 3
// DefaultMaxConcurrentUploads is the default value for
// maximum number of uploads that
// may take place at a time for each push.
defaultMaxConcurrentUploads = 5
// stockRuntimeName is the reserved name/alias used to represent the
DefaultMaxConcurrentUploads = 5
// StockRuntimeName is the reserved name/alias used to represent the
// OCI runtime being shipped with the docker daemon package.
stockRuntimeName = "runc"
)
const (
defaultNetworkMtu = 1500
disableNetworkBridge = "none"
)
const (
defaultShutdownTimeout = 15
StockRuntimeName = "runc"
// DefaultShmSize is the default value for container's shm size
DefaultShmSize = int64(67108864)
// DefaultNetworkMtu is the default value for network MTU
DefaultNetworkMtu = 1500
// DisableNetworkBridge is the default value of the option to disable network bridge
DisableNetworkBridge = "none"
)
// flatOptions contains configuration keys
@ -151,67 +150,29 @@ type CommonConfig struct {
MetricsAddress string `json:"metrics-addr"`
LogConfig
bridgeConfig // bridgeConfig holds bridge network specific configuration.
BridgeConfig // bridgeConfig holds bridge network specific configuration.
registry.ServiceOptions
reloadLock sync.Mutex
valuesSet map[string]interface{}
sync.Mutex
// FIXME(vdemeester) This part is not that clear and is mainly dependent on cli flags
// It should probably be handled outside this package.
ValuesSet map[string]interface{}
Experimental bool `json:"experimental"` // Experimental indicates whether experimental features should be exposed or not
}
// InstallCommonFlags adds flags to the pflag.FlagSet to configure the daemon
func (config *Config) InstallCommonFlags(flags *pflag.FlagSet) {
var maxConcurrentDownloads, maxConcurrentUploads int
config.ServiceOptions.InstallCliFlags(flags)
flags.Var(opts.NewNamedListOptsRef("storage-opts", &config.GraphOptions, nil), "storage-opt", "Storage driver options")
flags.Var(opts.NewNamedListOptsRef("authorization-plugins", &config.AuthorizationPlugins, nil), "authorization-plugin", "Authorization plugins to load")
flags.Var(opts.NewNamedListOptsRef("exec-opts", &config.ExecOptions, nil), "exec-opt", "Runtime execution options")
flags.StringVarP(&config.Pidfile, "pidfile", "p", defaultPidFile, "Path to use for daemon PID file")
flags.StringVarP(&config.Root, "graph", "g", defaultGraph, "Root of the Docker runtime")
flags.BoolVarP(&config.AutoRestart, "restart", "r", true, "--restart on the daemon has been deprecated in favor of --restart policies on docker run")
flags.MarkDeprecated("restart", "Please use a restart policy on docker run")
flags.StringVarP(&config.GraphDriver, "storage-driver", "s", "", "Storage driver to use")
flags.IntVar(&config.Mtu, "mtu", 0, "Set the containers network MTU")
flags.BoolVar(&config.RawLogs, "raw-logs", false, "Full timestamps without ANSI coloring")
// FIXME: why the inconsistency between "hosts" and "sockets"?
flags.Var(opts.NewListOptsRef(&config.DNS, opts.ValidateIPAddress), "dns", "DNS server to use")
flags.Var(opts.NewNamedListOptsRef("dns-opts", &config.DNSOptions, nil), "dns-opt", "DNS options to use")
flags.Var(opts.NewListOptsRef(&config.DNSSearch, opts.ValidateDNSSearch), "dns-search", "DNS search domains to use")
flags.Var(opts.NewNamedListOptsRef("labels", &config.Labels, opts.ValidateLabel), "label", "Set key=value labels to the daemon")
flags.StringVar(&config.LogConfig.Type, "log-driver", "json-file", "Default driver for container logs")
flags.Var(opts.NewNamedMapOpts("log-opts", config.LogConfig.Config, nil), "log-opt", "Default log driver options for containers")
flags.StringVar(&config.ClusterAdvertise, "cluster-advertise", "", "Address or interface name to advertise")
flags.StringVar(&config.ClusterStore, "cluster-store", "", "URL of the distributed storage backend")
flags.Var(opts.NewNamedMapOpts("cluster-store-opts", config.ClusterOpts, nil), "cluster-store-opt", "Set cluster store options")
flags.StringVar(&config.CorsHeaders, "api-cors-header", "", "Set CORS headers in the Engine API")
flags.IntVar(&maxConcurrentDownloads, "max-concurrent-downloads", defaultMaxConcurrentDownloads, "Set the max concurrent downloads for each pull")
flags.IntVar(&maxConcurrentUploads, "max-concurrent-uploads", defaultMaxConcurrentUploads, "Set the max concurrent uploads for each push")
flags.IntVar(&config.ShutdownTimeout, "shutdown-timeout", defaultShutdownTimeout, "Set the default shutdown timeout")
flags.StringVar(&config.SwarmDefaultAdvertiseAddr, "swarm-default-advertise-addr", "", "Set default address or interface for swarm advertised address")
flags.BoolVar(&config.Experimental, "experimental", false, "Enable experimental features")
flags.StringVar(&config.MetricsAddress, "metrics-addr", "", "Set default address and port to serve the metrics api on")
config.MaxConcurrentDownloads = &maxConcurrentDownloads
config.MaxConcurrentUploads = &maxConcurrentUploads
}
// IsValueSet returns true if a configuration value
// was explicitly set in the configuration file.
func (config *Config) IsValueSet(name string) bool {
if config.valuesSet == nil {
func (conf *Config) IsValueSet(name string) bool {
if conf.ValuesSet == nil {
return false
}
_, ok := config.valuesSet[name]
_, ok := conf.ValuesSet[name]
return ok
}
// NewConfig returns a new fully initialized Config struct
func NewConfig() *Config {
// New returns a new fully initialized Config struct
func New() *Config {
config := Config{}
config.LogConfig.Config = make(map[string]string)
config.ClusterOpts = make(map[string]string)
@ -222,12 +183,13 @@ func NewConfig() *Config {
return &config
}
func parseClusterAdvertiseSettings(clusterStore, clusterAdvertise string) (string, error) {
// ParseClusterAdvertiseSettings parses the specified advertise settings
func ParseClusterAdvertiseSettings(clusterStore, clusterAdvertise string) (string, error) {
if runtime.GOOS == "solaris" && (clusterAdvertise != "" || clusterStore != "") {
return "", errors.New("Cluster Advertise Settings not supported on Solaris")
}
if clusterAdvertise == "" {
return "", errDiscoveryDisabled
return "", daemondiscovery.ErrDiscoveryDisabled
}
if clusterStore == "" {
return "", errors.New("invalid cluster configuration. --cluster-advertise must be accompanied by --cluster-store configuration")
@ -264,15 +226,15 @@ func GetConflictFreeLabels(labels []string) ([]string, error) {
return newLabels, nil
}
// ReloadConfiguration reads the configuration in the host and reloads the daemon and server.
func ReloadConfiguration(configFile string, flags *pflag.FlagSet, reload func(*Config)) error {
// Reload reads the configuration in the host and reloads the daemon and server.
func Reload(configFile string, flags *pflag.FlagSet, reload func(*Config)) error {
logrus.Infof("Got signal to reload configuration, reloading from: %s", configFile)
newConfig, err := getConflictFreeConfiguration(configFile, flags)
if err != nil {
return err
}
if err := ValidateConfiguration(newConfig); err != nil {
if err := Validate(newConfig); err != nil {
return fmt.Errorf("file configuration validation failed (%v)", err)
}
@ -313,7 +275,7 @@ func MergeDaemonConfigurations(flagsConfig *Config, flags *pflag.FlagSet, config
return nil, err
}
if err := ValidateConfiguration(fileConfig); err != nil {
if err := Validate(fileConfig); err != nil {
return nil, fmt.Errorf("file configuration validation failed (%v)", err)
}
@ -324,7 +286,7 @@ func MergeDaemonConfigurations(flagsConfig *Config, flags *pflag.FlagSet, config
// We need to validate again once both fileConfig and flagsConfig
// have been merged
if err := ValidateConfiguration(fileConfig); err != nil {
if err := Validate(fileConfig); err != nil {
return nil, fmt.Errorf("file configuration validation failed (%v)", err)
}
@ -385,7 +347,7 @@ func getConflictFreeConfiguration(configFile string, flags *pflag.FlagSet) (*Con
})
}
config.valuesSet = configSet
config.ValuesSet = configSet
}
reader = bytes.NewReader(b)
@ -473,10 +435,10 @@ func findConfigurationConflicts(config map[string]interface{}, flags *pflag.Flag
return nil
}
// ValidateConfiguration validates some specific configs.
// Validate validates some specific configs.
// such as config.DNS, config.Labels, config.DNSSearch,
// as well as config.MaxConcurrentDownloads, config.MaxConcurrentUploads.
func ValidateConfiguration(config *Config) error {
func Validate(config *Config) error {
// validate DNS
for _, dns := range config.DNS {
if _, err := opts.ValidateIPAddress(dns); err != nil {
@ -510,12 +472,12 @@ func ValidateConfiguration(config *Config) error {
// validate that "default" runtime is not reset
if runtimes := config.GetAllRuntimes(); len(runtimes) > 0 {
if _, ok := runtimes[stockRuntimeName]; ok {
return fmt.Errorf("runtime name '%s' is reserved", stockRuntimeName)
if _, ok := runtimes[StockRuntimeName]; ok {
return fmt.Errorf("runtime name '%s' is reserved", StockRuntimeName)
}
}
if defaultRuntime := config.GetDefaultRuntimeName(); defaultRuntime != "" && defaultRuntime != stockRuntimeName {
if defaultRuntime := config.GetDefaultRuntimeName(); defaultRuntime != "" && defaultRuntime != StockRuntimeName {
runtimes := config.GetAllRuntimes()
if _, ok := runtimes[defaultRuntime]; !ok {
return fmt.Errorf("specified default runtime '%s' does not exist", defaultRuntime)
@ -526,14 +488,29 @@ func ValidateConfiguration(config *Config) error {
}
// GetAuthorizationPlugins returns daemon's sorted authorization plugins
func (config *Config) GetAuthorizationPlugins() []string {
config.reloadLock.Lock()
defer config.reloadLock.Unlock()
func (conf *Config) GetAuthorizationPlugins() []string {
conf.Lock()
defer conf.Unlock()
authPlugins := make([]string, 0, len(config.AuthorizationPlugins))
for _, p := range config.AuthorizationPlugins {
authPlugins := make([]string, 0, len(conf.AuthorizationPlugins))
for _, p := range conf.AuthorizationPlugins {
authPlugins = append(authPlugins, p)
}
sort.Strings(authPlugins)
return authPlugins
}
// ModifiedDiscoverySettings returns whether the discovery configuration has been modified or not.
func ModifiedDiscoverySettings(config *Config, backendType, advertise string, clusterOpts map[string]string) bool {
if config.ClusterStore != backendType || config.ClusterAdvertise != advertise {
return true
}
if (config.ClusterOpts == nil && clusterOpts == nil) ||
(config.ClusterOpts == nil && len(clusterOpts) == 0) ||
(len(config.ClusterOpts) == 0 && clusterOpts == nil) {
return false
}
return !reflect.DeepEqual(config.ClusterOpts, clusterOpts)
}

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 (
"github.com/spf13/pflag"
@ -20,28 +20,16 @@ type Config struct {
CommonUnixConfig
}
// bridgeConfig stores all the bridge driver specific
// BridgeConfig stores all the bridge driver specific
// configuration.
type bridgeConfig struct {
type BridgeConfig struct {
commonBridgeConfig
// Fields below here are platform specific.
commonUnixBridgeConfig
}
// InstallFlags adds command-line options to the top-level flag parser for
// the current process.
func (config *Config) InstallFlags(flags *pflag.FlagSet) {
// First handle install flags which are consistent cross-platform
config.InstallCommonFlags(flags)
// Then install flags common to unix platforms
config.InstallCommonUnixFlags(flags)
// Then platform-specific install flags
config.attachExperimentalFlags(flags)
}
func (config *Config) isSwarmCompatible() error {
// IsSwarmCompatible defines if swarm mode can be enabled in this config
func (conf *Config) IsSwarmCompatible() error {
return nil
}

View file

@ -1,4 +1,4 @@
package daemon
package config
import (
"io/ioutil"
@ -7,6 +7,7 @@ import (
"strings"
"testing"
"github.com/docker/docker/daemon/discovery"
"github.com/docker/docker/opts"
"github.com/docker/docker/pkg/testutil/assert"
"github.com/spf13/pflag"
@ -39,17 +40,17 @@ func TestParseClusterAdvertiseSettings(t *testing.T) {
if runtime.GOOS == "solaris" {
t.Skip("ClusterSettings not supported on Solaris\n")
}
_, err := parseClusterAdvertiseSettings("something", "")
if err != errDiscoveryDisabled {
_, err := ParseClusterAdvertiseSettings("something", "")
if err != discovery.ErrDiscoveryDisabled {
t.Fatalf("expected discovery disabled error, got %v\n", err)
}
_, err = parseClusterAdvertiseSettings("", "something")
_, err = ParseClusterAdvertiseSettings("", "something")
if err == nil {
t.Fatalf("expected discovery store error, got %v\n", err)
}
_, err = parseClusterAdvertiseSettings("etcd", "127.0.0.1:8080")
_, err = ParseClusterAdvertiseSettings("etcd", "127.0.0.1:8080")
if err != nil {
t.Fatal(err)
}
@ -160,70 +161,175 @@ func TestFindConfigurationConflictsWithMergedValues(t *testing.T) {
}
}
func TestValidateConfiguration(t *testing.T) {
c1 := &Config{
func TestValidateConfigurationErrors(t *testing.T) {
minusNumber := -10
testCases := []struct {
config *Config
}{
{
config: &Config{
CommonConfig: CommonConfig{
Labels: []string{"one"},
},
}
err := ValidateConfiguration(c1)
if err == nil {
t.Fatal("expected error, got nil")
}
c2 := &Config{
CommonConfig: CommonConfig{
Labels: []string{"one=two"},
},
}
err = ValidateConfiguration(c2)
if err != nil {
t.Fatalf("expected no error, got error %v", err)
}
c3 := &Config{
CommonConfig: CommonConfig{
DNS: []string{"1.1.1.1"},
},
}
err = ValidateConfiguration(c3)
if err != nil {
t.Fatalf("expected no error, got error %v", err)
}
c4 := &Config{
{
config: &Config{
CommonConfig: CommonConfig{
Labels: []string{"foo=bar", "one"},
},
},
},
{
config: &Config{
CommonConfig: CommonConfig{
DNS: []string{"1.1.1.1o"},
},
}
err = ValidateConfiguration(c4)
if err == nil {
t.Fatal("expected error, got nil")
}
c5 := &Config{
CommonConfig: CommonConfig{
DNSSearch: []string{"a.b.c"},
},
}
err = ValidateConfiguration(c5)
if err != nil {
t.Fatalf("expected no error, got error %v", err)
}
c6 := &Config{
},
{
config: &Config{
CommonConfig: CommonConfig{
DNS: []string{"2.2.2.2", "1.1.1.1o"},
},
},
},
{
config: &Config{
CommonConfig: CommonConfig{
DNSSearch: []string{"123456"},
},
},
},
{
config: &Config{
CommonConfig: CommonConfig{
DNSSearch: []string{"a.b.c", "123456"},
},
},
},
{
config: &Config{
CommonConfig: CommonConfig{
MaxConcurrentDownloads: &minusNumber,
// This is weird...
ValuesSet: map[string]interface{}{
"max-concurrent-downloads": -1,
},
},
},
},
{
config: &Config{
CommonConfig: CommonConfig{
MaxConcurrentUploads: &minusNumber,
// This is weird...
ValuesSet: map[string]interface{}{
"max-concurrent-uploads": -1,
},
},
},
},
}
err = ValidateConfiguration(c6)
for _, tc := range testCases {
err := Validate(tc.config)
if err == nil {
t.Fatal("expected error, got nil")
t.Fatalf("expected error, got nil for config %v", tc.config)
}
}
}
func TestValidateConfiguration(t *testing.T) {
testCases := []struct {
config *Config
}{
{
config: &Config{
CommonConfig: CommonConfig{
Labels: []string{"one=two"},
},
},
},
{
config: &Config{
CommonConfig: CommonConfig{
DNS: []string{"1.1.1.1"},
},
},
},
{
config: &Config{
CommonConfig: CommonConfig{
DNSSearch: []string{"a.b.c"},
},
},
},
}
for _, tc := range testCases {
err := Validate(tc.config)
if err != nil {
t.Fatalf("expected no error, got error %v", err)
}
}
}
func TestModifiedDiscoverySettings(t *testing.T) {
cases := []struct {
current *Config
modified *Config
expected bool
}{
{
current: discoveryConfig("foo", "bar", map[string]string{}),
modified: discoveryConfig("foo", "bar", map[string]string{}),
expected: false,
},
{
current: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}),
modified: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}),
expected: false,
},
{
current: discoveryConfig("foo", "bar", map[string]string{}),
modified: discoveryConfig("foo", "bar", nil),
expected: false,
},
{
current: discoveryConfig("foo", "bar", nil),
modified: discoveryConfig("foo", "bar", map[string]string{}),
expected: false,
},
{
current: discoveryConfig("foo", "bar", nil),
modified: discoveryConfig("baz", "bar", nil),
expected: true,
},
{
current: discoveryConfig("foo", "bar", nil),
modified: discoveryConfig("foo", "baz", nil),
expected: true,
},
{
current: discoveryConfig("foo", "bar", nil),
modified: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}),
expected: true,
},
}
for _, c := range cases {
got := ModifiedDiscoverySettings(c.current, c.modified.ClusterStore, c.modified.ClusterAdvertise, c.modified.ClusterOpts)
if c.expected != got {
t.Fatalf("expected %v, got %v: current config %v, new config %v", c.expected, got, c.current, c.modified)
}
}
}
func discoveryConfig(backendAddr, advertiseAddr string, opts map[string]string) *Config {
return &Config{
CommonConfig: CommonConfig{
ClusterStore: backendAddr,
ClusterAdvertise: advertiseAddr,
ClusterOpts: opts,
},
}
}

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
package daemon
package config
import (
"io/ioutil"
"runtime"
"testing"
"github.com/docker/docker/pkg/testutil/assert"
"github.com/spf13/pflag"
)
func TestDaemonConfigurationMerge(t *testing.T) {
@ -84,26 +81,6 @@ func TestDaemonConfigurationMerge(t *testing.T) {
}
}
func TestDaemonParseShmSize(t *testing.T) {
if runtime.GOOS == "solaris" {
t.Skip("ShmSize not supported on Solaris\n")
}
flags := pflag.NewFlagSet("test", pflag.ContinueOnError)
config := &Config{}
config.InstallFlags(flags)
// By default `--default-shm-size=64M`
expectedValue := 64 * 1024 * 1024
if config.ShmSize.Value() != int64(expectedValue) {
t.Fatalf("expected default shm size %d, got %d", expectedValue, config.ShmSize.Value())
}
assert.NilError(t, flags.Set("default-shm-size", "128M"))
expectedValue = 128 * 1024 * 1024
if config.ShmSize.Value() != int64(expectedValue) {
t.Fatalf("expected default shm size %d, got %d", expectedValue, config.ShmSize.Value())
}
}
func TestDaemonConfigurationMergeShmSize(t *testing.T) {
if runtime.GOOS == "solaris" {
t.Skip("ShmSize not supported on Solaris\n")

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
package daemon
package config
import (
"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() {
container.NetworkSettings.Bridge = daemon.configStore.bridgeConfig.Iface
container.NetworkSettings.Bridge = daemon.configStore.BridgeConfig.Iface
}
return nil

View file

@ -24,6 +24,8 @@ import (
"github.com/docker/docker/api/types"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/container"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/daemon/discovery"
"github.com/docker/docker/daemon/events"
"github.com/docker/docker/daemon/exec"
// register graph drivers
@ -82,14 +84,14 @@ type Daemon struct {
distributionMetadataStore dmetadata.Store
trustKey libtrust.PrivateKey
idIndex *truncindex.TruncIndex
configStore *Config
configStore *config.Config
statsCollector *stats.Collector
defaultLogConfig containertypes.LogConfig
RegistryService registry.Service
EventsService *events.Events
netController libnetwork.NetworkController
volumes *store.VolumeStore
discoveryWatcher discoveryReloader
discoveryWatcher discovery.Reloader
root string
seccompEnabled bool
apparmorEnabled bool
@ -459,12 +461,12 @@ func (daemon *Daemon) IsSwarmCompatible() error {
if daemon.configStore == nil {
return nil
}
return daemon.configStore.isSwarmCompatible()
return daemon.configStore.IsSwarmCompatible()
}
// NewDaemon sets up everything for the daemon to be able to service
// requests from the webserver.
func NewDaemon(config *Config, registryService registry.Service, containerdRemote libcontainerd.Remote) (daemon *Daemon, err error) {
func NewDaemon(config *config.Config, registryService registry.Service, containerdRemote libcontainerd.Remote) (daemon *Daemon, err error) {
setDefaultMtu(config)
// Ensure that we have a correct root key limit for launching containers.
@ -947,12 +949,12 @@ func (daemon *Daemon) setupInitLayer(initPath string) error {
return initlayer.Setup(initPath, rootUID, rootGID)
}
func setDefaultMtu(config *Config) {
func setDefaultMtu(conf *config.Config) {
// do nothing if the config does not have the default 0 value.
if config.Mtu != 0 {
if conf.Mtu != 0 {
return
}
config.Mtu = defaultNetworkMtu
conf.Mtu = config.DefaultNetworkMtu
}
func (daemon *Daemon) configureVolumes(rootUID, rootGID int) (*store.VolumeStore, error) {
@ -975,17 +977,17 @@ func (daemon *Daemon) IsShuttingDown() bool {
}
// initDiscovery initializes the discovery watcher for this daemon.
func (daemon *Daemon) initDiscovery(config *Config) error {
advertise, err := parseClusterAdvertiseSettings(config.ClusterStore, config.ClusterAdvertise)
func (daemon *Daemon) initDiscovery(conf *config.Config) error {
advertise, err := config.ParseClusterAdvertiseSettings(conf.ClusterStore, conf.ClusterAdvertise)
if err != nil {
if err == errDiscoveryDisabled {
if err == discovery.ErrDiscoveryDisabled {
return nil
}
return err
}
config.ClusterAdvertise = advertise
discoveryWatcher, err := initDiscovery(config.ClusterStore, config.ClusterAdvertise, config.ClusterOpts)
conf.ClusterAdvertise = advertise
discoveryWatcher, err := discovery.Init(conf.ClusterStore, conf.ClusterAdvertise, conf.ClusterOpts)
if err != nil {
return fmt.Errorf("discovery initialization failed (%v)", err)
}
@ -1005,60 +1007,60 @@ func (daemon *Daemon) initDiscovery(config *Config) error {
// - Daemon max concurrent uploads
// - Cluster discovery (reconfigure and restart)
// - Daemon live restore
// - Daemon shutdown timeout (in seconds)
func (daemon *Daemon) Reload(config *Config) (err error) {
// - Daemon shutdown timeout (in seconds).
func (daemon *Daemon) Reload(conf *config.Config) (err error) {
daemon.configStore.reloadLock.Lock()
daemon.configStore.Lock()
attributes := daemon.platformReload(config)
attributes := daemon.platformReload(conf)
defer func() {
// we're unlocking here, because
// LogDaemonEventWithAttributes() -> SystemInfo() -> GetAllRuntimes()
// holds that lock too.
daemon.configStore.reloadLock.Unlock()
daemon.configStore.Unlock()
if err == nil {
daemon.LogDaemonEventWithAttributes("reload", attributes)
}
}()
if err := daemon.reloadClusterDiscovery(config); err != nil {
if err := daemon.reloadClusterDiscovery(conf); err != nil {
return err
}
if config.IsValueSet("labels") {
daemon.configStore.Labels = config.Labels
if conf.IsValueSet("labels") {
daemon.configStore.Labels = conf.Labels
}
if config.IsValueSet("debug") {
daemon.configStore.Debug = config.Debug
if conf.IsValueSet("debug") {
daemon.configStore.Debug = conf.Debug
}
if config.IsValueSet("insecure-registries") {
daemon.configStore.InsecureRegistries = config.InsecureRegistries
if err := daemon.RegistryService.LoadInsecureRegistries(config.InsecureRegistries); err != nil {
if conf.IsValueSet("insecure-registries") {
daemon.configStore.InsecureRegistries = conf.InsecureRegistries
if err := daemon.RegistryService.LoadInsecureRegistries(conf.InsecureRegistries); err != nil {
return err
}
}
if config.IsValueSet("registry-mirrors") {
daemon.configStore.Mirrors = config.Mirrors
if err := daemon.RegistryService.LoadMirrors(config.Mirrors); err != nil {
if conf.IsValueSet("registry-mirrors") {
daemon.configStore.Mirrors = conf.Mirrors
if err := daemon.RegistryService.LoadMirrors(conf.Mirrors); err != nil {
return err
}
}
if config.IsValueSet("live-restore") {
daemon.configStore.LiveRestoreEnabled = config.LiveRestoreEnabled
if err := daemon.containerdRemote.UpdateOptions(libcontainerd.WithLiveRestore(config.LiveRestoreEnabled)); err != nil {
if conf.IsValueSet("live-restore") {
daemon.configStore.LiveRestoreEnabled = conf.LiveRestoreEnabled
if err := daemon.containerdRemote.UpdateOptions(libcontainerd.WithLiveRestore(conf.LiveRestoreEnabled)); err != nil {
return err
}
}
// If no value is set for max-concurrent-downloads we assume it is the default value
// We always "reset" as the cost is lightweight and easy to maintain.
if config.IsValueSet("max-concurrent-downloads") && config.MaxConcurrentDownloads != nil {
*daemon.configStore.MaxConcurrentDownloads = *config.MaxConcurrentDownloads
if conf.IsValueSet("max-concurrent-downloads") && conf.MaxConcurrentDownloads != nil {
*daemon.configStore.MaxConcurrentDownloads = *conf.MaxConcurrentDownloads
} else {
maxConcurrentDownloads := defaultMaxConcurrentDownloads
maxConcurrentDownloads := config.DefaultMaxConcurrentDownloads
daemon.configStore.MaxConcurrentDownloads = &maxConcurrentDownloads
}
logrus.Debugf("Reset Max Concurrent Downloads: %d", *daemon.configStore.MaxConcurrentDownloads)
@ -1068,10 +1070,10 @@ func (daemon *Daemon) Reload(config *Config) (err error) {
// If no value is set for max-concurrent-upload we assume it is the default value
// We always "reset" as the cost is lightweight and easy to maintain.
if config.IsValueSet("max-concurrent-uploads") && config.MaxConcurrentUploads != nil {
*daemon.configStore.MaxConcurrentUploads = *config.MaxConcurrentUploads
if conf.IsValueSet("max-concurrent-uploads") && conf.MaxConcurrentUploads != nil {
*daemon.configStore.MaxConcurrentUploads = *conf.MaxConcurrentUploads
} else {
maxConcurrentUploads := defaultMaxConcurrentUploads
maxConcurrentUploads := config.DefaultMaxConcurrentUploads
daemon.configStore.MaxConcurrentUploads = &maxConcurrentUploads
}
logrus.Debugf("Reset Max Concurrent Uploads: %d", *daemon.configStore.MaxConcurrentUploads)
@ -1079,8 +1081,8 @@ func (daemon *Daemon) Reload(config *Config) (err error) {
daemon.uploadManager.SetConcurrency(*daemon.configStore.MaxConcurrentUploads)
}
if config.IsValueSet("shutdown-timeout") {
daemon.configStore.ShutdownTimeout = config.ShutdownTimeout
if conf.IsValueSet("shutdown-timeout") {
daemon.configStore.ShutdownTimeout = conf.ShutdownTimeout
logrus.Debugf("Reset Shutdown Timeout: %d", daemon.configStore.ShutdownTimeout)
}
@ -1137,52 +1139,52 @@ func (daemon *Daemon) Reload(config *Config) (err error) {
return nil
}
func (daemon *Daemon) reloadClusterDiscovery(config *Config) error {
func (daemon *Daemon) reloadClusterDiscovery(conf *config.Config) error {
var err error
newAdvertise := daemon.configStore.ClusterAdvertise
newClusterStore := daemon.configStore.ClusterStore
if config.IsValueSet("cluster-advertise") {
if config.IsValueSet("cluster-store") {
newClusterStore = config.ClusterStore
if conf.IsValueSet("cluster-advertise") {
if conf.IsValueSet("cluster-store") {
newClusterStore = conf.ClusterStore
}
newAdvertise, err = parseClusterAdvertiseSettings(newClusterStore, config.ClusterAdvertise)
if err != nil && err != errDiscoveryDisabled {
newAdvertise, err = config.ParseClusterAdvertiseSettings(newClusterStore, conf.ClusterAdvertise)
if err != nil && err != discovery.ErrDiscoveryDisabled {
return err
}
}
if daemon.clusterProvider != nil {
if err := config.isSwarmCompatible(); err != nil {
if err := conf.IsSwarmCompatible(); err != nil {
return err
}
}
// check discovery modifications
if !modifiedDiscoverySettings(daemon.configStore, newAdvertise, newClusterStore, config.ClusterOpts) {
if !config.ModifiedDiscoverySettings(daemon.configStore, newAdvertise, newClusterStore, conf.ClusterOpts) {
return nil
}
// enable discovery for the first time if it was not previously enabled
if daemon.discoveryWatcher == nil {
discoveryWatcher, err := initDiscovery(newClusterStore, newAdvertise, config.ClusterOpts)
discoveryWatcher, err := discovery.Init(newClusterStore, newAdvertise, conf.ClusterOpts)
if err != nil {
return fmt.Errorf("discovery initialization failed (%v)", err)
}
daemon.discoveryWatcher = discoveryWatcher
} else {
if err == errDiscoveryDisabled {
if err == discovery.ErrDiscoveryDisabled {
// disable discovery if it was previously enabled and it's disabled now
daemon.discoveryWatcher.Stop()
} else {
// reload discovery
if err = daemon.discoveryWatcher.Reload(config.ClusterStore, newAdvertise, config.ClusterOpts); err != nil {
if err = daemon.discoveryWatcher.Reload(conf.ClusterStore, newAdvertise, conf.ClusterOpts); err != nil {
return err
}
}
}
daemon.configStore.ClusterStore = newClusterStore
daemon.configStore.ClusterOpts = config.ClusterOpts
daemon.configStore.ClusterOpts = conf.ClusterOpts
daemon.configStore.ClusterAdvertise = newAdvertise
if daemon.netController == nil {
@ -1201,11 +1203,11 @@ func (daemon *Daemon) reloadClusterDiscovery(config *Config) error {
return nil
}
func isBridgeNetworkDisabled(config *Config) bool {
return config.bridgeConfig.Iface == disableNetworkBridge
func isBridgeNetworkDisabled(conf *config.Config) bool {
return conf.BridgeConfig.Iface == config.DisableNetworkBridge
}
func (daemon *Daemon) networkOptions(dconfig *Config, pg plugingetter.PluginGetter, activeSandboxes map[string]interface{}) ([]nwconfig.Option, error) {
func (daemon *Daemon) networkOptions(dconfig *config.Config, pg plugingetter.PluginGetter, activeSandboxes map[string]interface{}) ([]nwconfig.Option, error) {
options := []nwconfig.Option{}
if dconfig == nil {
return options, nil
@ -1297,7 +1299,7 @@ func (daemon *Daemon) PluginGetter() *plugin.Store {
}
// CreateDaemonRoot creates the root for the daemon
func CreateDaemonRoot(config *Config) error {
func CreateDaemonRoot(config *config.Config) error {
// get the canonical path to the Docker root directory
var realRoot string
if _, err := os.Stat(config.Root); err != nil && os.IsNotExist(err) {

View file

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

View file

@ -23,6 +23,7 @@ import (
pblkiodev "github.com/docker/docker/api/types/blkiodev"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/container"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/image"
"github.com/docker/docker/opts"
"github.com/docker/docker/pkg/idtools"
@ -256,7 +257,7 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf
hostConfig.MemorySwap = hostConfig.Memory * 2
}
if hostConfig.ShmSize == 0 {
hostConfig.ShmSize = defaultShmSize
hostConfig.ShmSize = config.DefaultShmSize
if daemon.configStore != nil {
hostConfig.ShmSize = int64(daemon.configStore.ShmSize)
}
@ -474,7 +475,7 @@ func (daemon *Daemon) getCgroupDriver() string {
}
// getCD gets the raw value of the native.cgroupdriver option, if set.
func getCD(config *Config) string {
func getCD(config *config.Config) string {
for _, option := range config.ExecOptions {
key, val, err := parsers.ParseKeyValueOpt(option)
if err != nil || !strings.EqualFold(key, "native.cgroupdriver") {
@ -486,7 +487,7 @@ func getCD(config *Config) string {
}
// VerifyCgroupDriver validates native.cgroupdriver
func VerifyCgroupDriver(config *Config) error {
func VerifyCgroupDriver(config *config.Config) error {
cd := getCD(config)
if cd == "" || cd == cgroupFsDriver || cd == cgroupSystemdDriver {
return nil
@ -495,7 +496,7 @@ func VerifyCgroupDriver(config *Config) error {
}
// UsingSystemd returns true if cli option includes native.cgroupdriver=systemd
func UsingSystemd(config *Config) bool {
func UsingSystemd(config *config.Config) bool {
return getCD(config) == cgroupSystemdDriver
}
@ -568,19 +569,19 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
}
// platformReload updates configuration with platform specific options
func (daemon *Daemon) platformReload(config *Config) map[string]string {
if config.IsValueSet("runtimes") {
daemon.configStore.Runtimes = config.Runtimes
func (daemon *Daemon) platformReload(conf *config.Config) map[string]string {
if conf.IsValueSet("runtimes") {
daemon.configStore.Runtimes = conf.Runtimes
// Always set the default one
daemon.configStore.Runtimes[stockRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary}
daemon.configStore.Runtimes[config.StockRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary}
}
if config.DefaultRuntime != "" {
daemon.configStore.DefaultRuntime = config.DefaultRuntime
if conf.DefaultRuntime != "" {
daemon.configStore.DefaultRuntime = conf.DefaultRuntime
}
if config.IsValueSet("default-shm-size") {
daemon.configStore.ShmSize = config.ShmSize
if conf.IsValueSet("default-shm-size") {
daemon.configStore.ShmSize = conf.ShmSize
}
// Update attributes
@ -600,33 +601,33 @@ func (daemon *Daemon) platformReload(config *Config) map[string]string {
}
// verifyDaemonSettings performs validation of daemon config struct
func verifyDaemonSettings(config *Config) error {
func verifyDaemonSettings(conf *config.Config) error {
// Check for mutually incompatible config options
if config.bridgeConfig.Iface != "" && config.bridgeConfig.IP != "" {
if conf.BridgeConfig.Iface != "" && conf.BridgeConfig.IP != "" {
return fmt.Errorf("You specified -b & --bip, mutually exclusive options. Please specify only one")
}
if !config.bridgeConfig.EnableIPTables && !config.bridgeConfig.InterContainerCommunication {
if !conf.BridgeConfig.EnableIPTables && !conf.BridgeConfig.InterContainerCommunication {
return fmt.Errorf("You specified --iptables=false with --icc=false. ICC=false uses iptables to function. Please set --icc or --iptables to true")
}
if !config.bridgeConfig.EnableIPTables && config.bridgeConfig.EnableIPMasq {
config.bridgeConfig.EnableIPMasq = false
if !conf.BridgeConfig.EnableIPTables && conf.BridgeConfig.EnableIPMasq {
conf.BridgeConfig.EnableIPMasq = false
}
if err := VerifyCgroupDriver(config); err != nil {
if err := VerifyCgroupDriver(conf); err != nil {
return err
}
if config.CgroupParent != "" && UsingSystemd(config) {
if len(config.CgroupParent) <= 6 || !strings.HasSuffix(config.CgroupParent, ".slice") {
if conf.CgroupParent != "" && UsingSystemd(conf) {
if len(conf.CgroupParent) <= 6 || !strings.HasSuffix(conf.CgroupParent, ".slice") {
return fmt.Errorf("cgroup-parent for systemd cgroup should be a valid slice named as \"xxx.slice\"")
}
}
if config.DefaultRuntime == "" {
config.DefaultRuntime = stockRuntimeName
if conf.DefaultRuntime == "" {
conf.DefaultRuntime = config.StockRuntimeName
}
if config.Runtimes == nil {
config.Runtimes = make(map[string]types.Runtime)
if conf.Runtimes == nil {
conf.Runtimes = make(map[string]types.Runtime)
}
config.Runtimes[stockRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary}
conf.Runtimes[config.StockRuntimeName] = types.Runtime{Path: DefaultRuntimeBinary}
return nil
}
@ -641,7 +642,7 @@ func checkSystem() error {
// configureMaxThreads sets the Go runtime max threads threshold
// which is 90% of the kernel setting from /proc/sys/kernel/threads-max
func configureMaxThreads(config *Config) error {
func configureMaxThreads(config *config.Config) error {
mt, err := ioutil.ReadFile("/proc/sys/kernel/threads-max")
if err != nil {
return err
@ -688,7 +689,7 @@ func overlaySupportsSelinux() (bool, error) {
}
// configureKernelSecuritySupport configures and validates security support for the kernel
func configureKernelSecuritySupport(config *Config, driverName string) error {
func configureKernelSecuritySupport(config *config.Config, driverName string) error {
if config.EnableSelinuxSupport {
if !selinuxEnabled() {
logrus.Warn("Docker could not enable SELinux on the host system")
@ -713,7 +714,7 @@ func configureKernelSecuritySupport(config *Config, driverName string) error {
return nil
}
func (daemon *Daemon) initNetworkController(config *Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) {
func (daemon *Daemon) initNetworkController(config *config.Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error) {
netOptions, err := daemon.networkOptions(config, daemon.PluginStore, activeSandboxes)
if err != nil {
return nil, err
@ -762,12 +763,12 @@ func (daemon *Daemon) initNetworkController(config *Config, activeSandboxes map[
return controller, nil
}
func driverOptions(config *Config) []nwconfig.Option {
func driverOptions(config *config.Config) []nwconfig.Option {
bridgeConfig := options.Generic{
"EnableIPForwarding": config.bridgeConfig.EnableIPForward,
"EnableIPTables": config.bridgeConfig.EnableIPTables,
"EnableUserlandProxy": config.bridgeConfig.EnableUserlandProxy,
"UserlandProxyPath": config.bridgeConfig.UserlandProxyPath}
"EnableIPForwarding": config.BridgeConfig.EnableIPForward,
"EnableIPTables": config.BridgeConfig.EnableIPTables,
"EnableUserlandProxy": config.BridgeConfig.EnableUserlandProxy,
"UserlandProxyPath": config.BridgeConfig.UserlandProxyPath}
bridgeOption := options.Generic{netlabel.GenericData: bridgeConfig}
dOptions := []nwconfig.Option{}
@ -775,22 +776,22 @@ func driverOptions(config *Config) []nwconfig.Option {
return dOptions
}
func initBridgeDriver(controller libnetwork.NetworkController, config *Config) error {
func initBridgeDriver(controller libnetwork.NetworkController, config *config.Config) error {
bridgeName := bridge.DefaultBridgeName
if config.bridgeConfig.Iface != "" {
bridgeName = config.bridgeConfig.Iface
if config.BridgeConfig.Iface != "" {
bridgeName = config.BridgeConfig.Iface
}
netOption := map[string]string{
bridge.BridgeName: bridgeName,
bridge.DefaultBridge: strconv.FormatBool(true),
netlabel.DriverMTU: strconv.Itoa(config.Mtu),
bridge.EnableIPMasquerade: strconv.FormatBool(config.bridgeConfig.EnableIPMasq),
bridge.EnableICC: strconv.FormatBool(config.bridgeConfig.InterContainerCommunication),
bridge.EnableIPMasquerade: strconv.FormatBool(config.BridgeConfig.EnableIPMasq),
bridge.EnableICC: strconv.FormatBool(config.BridgeConfig.InterContainerCommunication),
}
// --ip processing
if config.bridgeConfig.DefaultIP != nil {
netOption[bridge.DefaultBindingIP] = config.bridgeConfig.DefaultIP.String()
if config.BridgeConfig.DefaultIP != nil {
netOption[bridge.DefaultBindingIP] = config.BridgeConfig.DefaultIP.String()
}
var (
@ -806,8 +807,8 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
}
nw := nwList[0]
if len(nwList) > 1 && config.bridgeConfig.FixedCIDR != "" {
_, fCIDR, err := net.ParseCIDR(config.bridgeConfig.FixedCIDR)
if len(nwList) > 1 && config.BridgeConfig.FixedCIDR != "" {
_, fCIDR, err := net.ParseCIDR(config.BridgeConfig.FixedCIDR)
if err != nil {
return errors.Wrap(err, "parse CIDR failed")
}
@ -826,9 +827,9 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
ipamV4Conf.Gateway = nw.IP.String()
}
if config.bridgeConfig.IP != "" {
ipamV4Conf.PreferredPool = config.bridgeConfig.IP
ip, _, err := net.ParseCIDR(config.bridgeConfig.IP)
if config.BridgeConfig.IP != "" {
ipamV4Conf.PreferredPool = config.BridgeConfig.IP
ip, _, err := net.ParseCIDR(config.BridgeConfig.IP)
if err != nil {
return err
}
@ -837,8 +838,8 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
logrus.Infof("Default bridge (%s) is assigned with an IP address %s. Daemon option --bip can be used to set a preferred IP address", bridgeName, ipamV4Conf.PreferredPool)
}
if config.bridgeConfig.FixedCIDR != "" {
_, fCIDR, err := net.ParseCIDR(config.bridgeConfig.FixedCIDR)
if config.BridgeConfig.FixedCIDR != "" {
_, fCIDR, err := net.ParseCIDR(config.BridgeConfig.FixedCIDR)
if err != nil {
return err
}
@ -846,13 +847,13 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
ipamV4Conf.SubPool = fCIDR.String()
}
if config.bridgeConfig.DefaultGatewayIPv4 != nil {
ipamV4Conf.AuxAddresses["DefaultGatewayIPv4"] = config.bridgeConfig.DefaultGatewayIPv4.String()
if config.BridgeConfig.DefaultGatewayIPv4 != nil {
ipamV4Conf.AuxAddresses["DefaultGatewayIPv4"] = config.BridgeConfig.DefaultGatewayIPv4.String()
}
var deferIPv6Alloc bool
if config.bridgeConfig.FixedCIDRv6 != "" {
_, fCIDRv6, err := net.ParseCIDR(config.bridgeConfig.FixedCIDRv6)
if config.BridgeConfig.FixedCIDRv6 != "" {
_, fCIDRv6, err := net.ParseCIDR(config.BridgeConfig.FixedCIDRv6)
if err != nil {
return err
}
@ -882,11 +883,11 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
}
}
if config.bridgeConfig.DefaultGatewayIPv6 != nil {
if config.BridgeConfig.DefaultGatewayIPv6 != nil {
if ipamV6Conf == nil {
ipamV6Conf = &libnetwork.IpamConf{AuxAddresses: make(map[string]string)}
}
ipamV6Conf.AuxAddresses["DefaultGatewayIPv6"] = config.bridgeConfig.DefaultGatewayIPv6.String()
ipamV6Conf.AuxAddresses["DefaultGatewayIPv6"] = config.BridgeConfig.DefaultGatewayIPv6.String()
}
v4Conf := []*libnetwork.IpamConf{ipamV4Conf}
@ -896,7 +897,7 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e
}
// Initialize default network on "bridge" with the same name
_, err = controller.NewNetwork("bridge", "bridge", "",
libnetwork.NetworkOptionEnableIPv6(config.bridgeConfig.EnableIPv6),
libnetwork.NetworkOptionEnableIPv6(config.BridgeConfig.EnableIPv6),
libnetwork.NetworkOptionDriverOpts(netOption),
libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf, nil),
libnetwork.NetworkOptionDeferIPv6Alloc(deferIPv6Alloc))
@ -1012,7 +1013,7 @@ func parseRemappedRoot(usergrp string) (string, string, error) {
return username, groupname, nil
}
func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error) {
func setupRemappedRoot(config *config.Config) ([]idtools.IDMap, []idtools.IDMap, error) {
if runtime.GOOS != "linux" && config.RemappedRoot != "" {
return nil, nil, fmt.Errorf("User namespaces are only supported on Linux")
}
@ -1045,7 +1046,7 @@ func setupRemappedRoot(config *Config) ([]idtools.IDMap, []idtools.IDMap, error)
return uidMaps, gidMaps, nil
}
func setupDaemonRoot(config *Config, rootDir string, rootUID, rootGID int) error {
func setupDaemonRoot(config *config.Config, rootDir string, rootUID, rootGID int) error {
config.Root = rootDir
// the docker root metadata directory needs to have execute permissions for all users (g+x,o+x)
// so that syscalls executing as non-root, operating on subdirectories of the graph root
@ -1219,7 +1220,7 @@ func rootFSToAPIType(rootfs *image.RootFS) types.RootFS {
}
// setupDaemonProcess sets various settings for the daemon's process
func setupDaemonProcess(config *Config) error {
func setupDaemonProcess(config *config.Config) error {
// setup the daemons oom_score_adj
return setupOOMScoreAdj(config.OOMScoreAdjust)
}

View file

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

View file

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

View file

@ -1,9 +1,8 @@
package daemon
package discovery
import (
"errors"
"fmt"
"reflect"
"strconv"
"time"
@ -21,9 +20,11 @@ const (
defaultDiscoveryTTLFactor = 3
)
var errDiscoveryDisabled = errors.New("discovery is disabled")
// ErrDiscoveryDisabled is an error returned if the discovery is disabled
var ErrDiscoveryDisabled = errors.New("discovery is disabled")
type discoveryReloader interface {
// Reloader is the discovery reloader of the daemon
type Reloader interface {
discovery.Watcher
Stop()
Reload(backend, address string, clusterOpts map[string]string) error
@ -93,9 +94,9 @@ func discoveryOpts(clusterOpts map[string]string) (time.Duration, time.Duration,
return heartbeat, ttl, nil
}
// initDiscovery initializes the nodes discovery subsystem by connecting to the specified backend
// Init initializes the nodes discovery subsystem by connecting to the specified backend
// and starts a registration loop to advertise the current node under the specified address.
func initDiscovery(backendAddress, advertiseAddress string, clusterOpts map[string]string) (discoveryReloader, error) {
func Init(backendAddress, advertiseAddress string, clusterOpts map[string]string) (Reloader, error) {
heartbeat, backend, err := parseDiscoveryOptions(backendAddress, clusterOpts)
if err != nil {
return nil, err
@ -198,18 +199,3 @@ func parseDiscoveryOptions(backendAddress string, clusterOpts map[string]string)
}
return heartbeat, backend, nil
}
// modifiedDiscoverySettings returns whether the discovery configuration has been modified or not.
func modifiedDiscoverySettings(config *Config, backendType, advertise string, clusterOpts map[string]string) bool {
if config.ClusterStore != backendType || config.ClusterAdvertise != advertise {
return true
}
if (config.ClusterOpts == nil && clusterOpts == nil) ||
(config.ClusterOpts == nil && len(clusterOpts) == 0) ||
(len(config.ClusterOpts) == 0 && clusterOpts == nil) {
return false
}
return !reflect.DeepEqual(config.ClusterOpts, clusterOpts)
}

View file

@ -1,4 +1,4 @@
package daemon
package discovery
import (
"testing"
@ -101,64 +101,3 @@ func TestDiscoveryOpts(t *testing.T) {
t.Fatalf("TTL - Expected : %v, Actual : %v", expected, ttl)
}
}
func TestModifiedDiscoverySettings(t *testing.T) {
cases := []struct {
current *Config
modified *Config
expected bool
}{
{
current: discoveryConfig("foo", "bar", map[string]string{}),
modified: discoveryConfig("foo", "bar", map[string]string{}),
expected: false,
},
{
current: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}),
modified: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}),
expected: false,
},
{
current: discoveryConfig("foo", "bar", map[string]string{}),
modified: discoveryConfig("foo", "bar", nil),
expected: false,
},
{
current: discoveryConfig("foo", "bar", nil),
modified: discoveryConfig("foo", "bar", map[string]string{}),
expected: false,
},
{
current: discoveryConfig("foo", "bar", nil),
modified: discoveryConfig("baz", "bar", nil),
expected: true,
},
{
current: discoveryConfig("foo", "bar", nil),
modified: discoveryConfig("foo", "baz", nil),
expected: true,
},
{
current: discoveryConfig("foo", "bar", nil),
modified: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}),
expected: true,
},
}
for _, c := range cases {
got := modifiedDiscoverySettings(c.current, c.modified.ClusterStore, c.modified.ClusterAdvertise, c.modified.ClusterOpts)
if c.expected != got {
t.Fatalf("expected %v, got %v: current config %v, new config %v", c.expected, got, c.current, c.modified)
}
}
}
func discoveryConfig(backendAddr, advertiseAddr string, opts map[string]string) *Config {
return &Config{
CommonConfig: CommonConfig{
ClusterStore: backendAddr,
ClusterAdvertise: advertiseAddr,
ClusterOpts: opts,
},
}
}