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:
parent
41650df87e
commit
db63f9370e
32 changed files with 900 additions and 748 deletions
52
cmd/dockerd/config.go
Normal file
52
cmd/dockerd/config.go
Normal 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
|
||||||
|
}
|
34
cmd/dockerd/config_common_unix.go
Normal file
34
cmd/dockerd/config_common_unix.go
Normal 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")
|
||||||
|
|
||||||
|
}
|
9
cmd/dockerd/config_experimental.go
Normal file
9
cmd/dockerd/config_experimental.go
Normal 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) {
|
||||||
|
}
|
19
cmd/dockerd/config_solaris.go
Normal file
19
cmd/dockerd/config_solaris.go
Normal 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)
|
||||||
|
}
|
51
cmd/dockerd/config_unix.go
Normal file
51
cmd/dockerd/config_unix.go
Normal 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)
|
||||||
|
}
|
32
cmd/dockerd/config_unix_test.go
Normal file
32
cmd/dockerd/config_unix_test.go
Normal 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())
|
||||||
|
}
|
||||||
|
}
|
25
cmd/dockerd/config_windows.go
Normal file
25
cmd/dockerd/config_windows.go
Normal 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")
|
||||||
|
}
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
70
daemon/config/config_common_unix.go
Normal file
70
daemon/config/config_common_unix.go
Normal 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
|
||||||
|
}
|
43
daemon/config/config_common_unix_test.go
Normal file
43
daemon/config/config_common_unix_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
}
|
}
|
|
@ -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
|
||||||
CommonConfig: CommonConfig{
|
testCases := []struct {
|
||||||
Labels: []string{"one"},
|
config *Config
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
config: &Config{
|
||||||
|
CommonConfig: CommonConfig{
|
||||||
|
Labels: []string{"one"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: &Config{
|
||||||
|
CommonConfig: CommonConfig{
|
||||||
|
Labels: []string{"foo=bar", "one"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: &Config{
|
||||||
|
CommonConfig: CommonConfig{
|
||||||
|
DNS: []string{"1.1.1.1o"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: &Config{
|
||||||
|
CommonConfig: CommonConfig{
|
||||||
|
DNS: []string{"2.2.2.2", "1.1.1.1o"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: &Config{
|
||||||
|
CommonConfig: CommonConfig{
|
||||||
|
DNSSearch: []string{"123456"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: &Config{
|
||||||
|
CommonConfig: CommonConfig{
|
||||||
|
DNSSearch: []string{"a.b.c", "123456"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: &Config{
|
||||||
|
CommonConfig: CommonConfig{
|
||||||
|
MaxConcurrentDownloads: &minusNumber,
|
||||||
|
// This is weird...
|
||||||
|
ValuesSet: map[string]interface{}{
|
||||||
|
"max-concurrent-downloads": -1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: &Config{
|
||||||
|
CommonConfig: CommonConfig{
|
||||||
|
MaxConcurrentUploads: &minusNumber,
|
||||||
|
// This is weird...
|
||||||
|
ValuesSet: map[string]interface{}{
|
||||||
|
"max-concurrent-uploads": -1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
err := ValidateConfiguration(c1)
|
err := Validate(tc.config)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error, got nil")
|
t.Fatalf("expected error, got nil for config %v", tc.config)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
c2 := &Config{
|
}
|
||||||
CommonConfig: CommonConfig{
|
|
||||||
Labels: []string{"one=two"},
|
func TestValidateConfiguration(t *testing.T) {
|
||||||
},
|
testCases := []struct {
|
||||||
}
|
config *Config
|
||||||
|
}{
|
||||||
err = ValidateConfiguration(c2)
|
{
|
||||||
if err != nil {
|
config: &Config{
|
||||||
t.Fatalf("expected no error, got error %v", err)
|
CommonConfig: CommonConfig{
|
||||||
}
|
Labels: []string{"one=two"},
|
||||||
|
},
|
||||||
c3 := &Config{
|
},
|
||||||
CommonConfig: CommonConfig{
|
},
|
||||||
DNS: []string{"1.1.1.1"},
|
{
|
||||||
},
|
config: &Config{
|
||||||
}
|
CommonConfig: CommonConfig{
|
||||||
|
DNS: []string{"1.1.1.1"},
|
||||||
err = ValidateConfiguration(c3)
|
},
|
||||||
if err != nil {
|
},
|
||||||
t.Fatalf("expected no error, got error %v", err)
|
},
|
||||||
}
|
{
|
||||||
|
config: &Config{
|
||||||
c4 := &Config{
|
CommonConfig: CommonConfig{
|
||||||
CommonConfig: CommonConfig{
|
DNSSearch: []string{"a.b.c"},
|
||||||
DNS: []string{"1.1.1.1o"},
|
},
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
}
|
||||||
err = ValidateConfiguration(c4)
|
for _, tc := range testCases {
|
||||||
if err == nil {
|
err := Validate(tc.config)
|
||||||
t.Fatal("expected error, got nil")
|
if err != nil {
|
||||||
}
|
t.Fatalf("expected no error, got error %v", err)
|
||||||
|
}
|
||||||
c5 := &Config{
|
}
|
||||||
CommonConfig: CommonConfig{
|
}
|
||||||
DNSSearch: []string{"a.b.c"},
|
|
||||||
},
|
func TestModifiedDiscoverySettings(t *testing.T) {
|
||||||
}
|
cases := []struct {
|
||||||
|
current *Config
|
||||||
err = ValidateConfiguration(c5)
|
modified *Config
|
||||||
if err != nil {
|
expected bool
|
||||||
t.Fatalf("expected no error, got error %v", err)
|
}{
|
||||||
}
|
{
|
||||||
|
current: discoveryConfig("foo", "bar", map[string]string{}),
|
||||||
c6 := &Config{
|
modified: discoveryConfig("foo", "bar", map[string]string{}),
|
||||||
CommonConfig: CommonConfig{
|
expected: false,
|
||||||
DNSSearch: []string{"123456"},
|
},
|
||||||
},
|
{
|
||||||
}
|
current: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}),
|
||||||
|
modified: discoveryConfig("foo", "bar", map[string]string{"foo": "bar"}),
|
||||||
err = ValidateConfiguration(c6)
|
expected: false,
|
||||||
if err == nil {
|
},
|
||||||
t.Fatal("expected error, got nil")
|
{
|
||||||
|
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,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
62
daemon/config/config_unix.go
Normal file
62
daemon/config/config_unix.go
Normal 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
|
||||||
|
}
|
|
@ -1,15 +1,12 @@
|
||||||
// +build !windows
|
// +build !windows
|
||||||
|
|
||||||
package daemon
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/testutil/assert"
|
|
||||||
"github.com/spf13/pflag"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDaemonConfigurationMerge(t *testing.T) {
|
func TestDaemonConfigurationMerge(t *testing.T) {
|
||||||
|
@ -84,26 +81,6 @@ func TestDaemonConfigurationMerge(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDaemonParseShmSize(t *testing.T) {
|
|
||||||
if runtime.GOOS == "solaris" {
|
|
||||||
t.Skip("ShmSize not supported on Solaris\n")
|
|
||||||
}
|
|
||||||
flags := pflag.NewFlagSet("test", pflag.ContinueOnError)
|
|
||||||
|
|
||||||
config := &Config{}
|
|
||||||
config.InstallFlags(flags)
|
|
||||||
// By default `--default-shm-size=64M`
|
|
||||||
expectedValue := 64 * 1024 * 1024
|
|
||||||
if config.ShmSize.Value() != int64(expectedValue) {
|
|
||||||
t.Fatalf("expected default shm size %d, got %d", expectedValue, config.ShmSize.Value())
|
|
||||||
}
|
|
||||||
assert.NilError(t, flags.Set("default-shm-size", "128M"))
|
|
||||||
expectedValue = 128 * 1024 * 1024
|
|
||||||
if config.ShmSize.Value() != int64(expectedValue) {
|
|
||||||
t.Fatalf("expected default shm size %d, got %d", expectedValue, config.ShmSize.Value())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDaemonConfigurationMergeShmSize(t *testing.T) {
|
func TestDaemonConfigurationMergeShmSize(t *testing.T) {
|
||||||
if runtime.GOOS == "solaris" {
|
if runtime.GOOS == "solaris" {
|
||||||
t.Skip("ShmSize not supported on Solaris\n")
|
t.Skip("ShmSize not supported on Solaris\n")
|
52
daemon/config/config_windows.go
Normal file
52
daemon/config/config_windows.go
Normal 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
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package daemon
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
|
@ -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
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package daemon
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/spf13/pflag"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (config *Config) attachExperimentalFlags(cmd *pflag.FlagSet) {
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
|
112
daemon/daemon.go
112
daemon/daemon.go
|
@ -24,6 +24,8 @@ import (
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
containertypes "github.com/docker/docker/api/types/container"
|
containertypes "github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/container"
|
"github.com/docker/docker/container"
|
||||||
|
"github.com/docker/docker/daemon/config"
|
||||||
|
"github.com/docker/docker/daemon/discovery"
|
||||||
"github.com/docker/docker/daemon/events"
|
"github.com/docker/docker/daemon/events"
|
||||||
"github.com/docker/docker/daemon/exec"
|
"github.com/docker/docker/daemon/exec"
|
||||||
// register graph drivers
|
// register graph drivers
|
||||||
|
@ -82,14 +84,14 @@ type Daemon struct {
|
||||||
distributionMetadataStore dmetadata.Store
|
distributionMetadataStore dmetadata.Store
|
||||||
trustKey libtrust.PrivateKey
|
trustKey libtrust.PrivateKey
|
||||||
idIndex *truncindex.TruncIndex
|
idIndex *truncindex.TruncIndex
|
||||||
configStore *Config
|
configStore *config.Config
|
||||||
statsCollector *stats.Collector
|
statsCollector *stats.Collector
|
||||||
defaultLogConfig containertypes.LogConfig
|
defaultLogConfig containertypes.LogConfig
|
||||||
RegistryService registry.Service
|
RegistryService registry.Service
|
||||||
EventsService *events.Events
|
EventsService *events.Events
|
||||||
netController libnetwork.NetworkController
|
netController libnetwork.NetworkController
|
||||||
volumes *store.VolumeStore
|
volumes *store.VolumeStore
|
||||||
discoveryWatcher discoveryReloader
|
discoveryWatcher discovery.Reloader
|
||||||
root string
|
root string
|
||||||
seccompEnabled bool
|
seccompEnabled bool
|
||||||
apparmorEnabled bool
|
apparmorEnabled bool
|
||||||
|
@ -459,12 +461,12 @@ func (daemon *Daemon) IsSwarmCompatible() error {
|
||||||
if daemon.configStore == nil {
|
if daemon.configStore == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return daemon.configStore.isSwarmCompatible()
|
return daemon.configStore.IsSwarmCompatible()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDaemon sets up everything for the daemon to be able to service
|
// NewDaemon sets up everything for the daemon to be able to service
|
||||||
// requests from the webserver.
|
// requests from the webserver.
|
||||||
func NewDaemon(config *Config, registryService registry.Service, containerdRemote libcontainerd.Remote) (daemon *Daemon, err error) {
|
func NewDaemon(config *config.Config, registryService registry.Service, containerdRemote libcontainerd.Remote) (daemon *Daemon, err error) {
|
||||||
setDefaultMtu(config)
|
setDefaultMtu(config)
|
||||||
|
|
||||||
// Ensure that we have a correct root key limit for launching containers.
|
// Ensure that we have a correct root key limit for launching containers.
|
||||||
|
@ -947,12 +949,12 @@ func (daemon *Daemon) setupInitLayer(initPath string) error {
|
||||||
return initlayer.Setup(initPath, rootUID, rootGID)
|
return initlayer.Setup(initPath, rootUID, rootGID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setDefaultMtu(config *Config) {
|
func setDefaultMtu(conf *config.Config) {
|
||||||
// do nothing if the config does not have the default 0 value.
|
// do nothing if the config does not have the default 0 value.
|
||||||
if config.Mtu != 0 {
|
if conf.Mtu != 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
config.Mtu = defaultNetworkMtu
|
conf.Mtu = config.DefaultNetworkMtu
|
||||||
}
|
}
|
||||||
|
|
||||||
func (daemon *Daemon) configureVolumes(rootUID, rootGID int) (*store.VolumeStore, error) {
|
func (daemon *Daemon) configureVolumes(rootUID, rootGID int) (*store.VolumeStore, error) {
|
||||||
|
@ -975,17 +977,17 @@ func (daemon *Daemon) IsShuttingDown() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// initDiscovery initializes the discovery watcher for this daemon.
|
// initDiscovery initializes the discovery watcher for this daemon.
|
||||||
func (daemon *Daemon) initDiscovery(config *Config) error {
|
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) {
|
||||||
|
|
|
@ -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{
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package daemon
|
package discovery
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -21,9 +20,11 @@ const (
|
||||||
defaultDiscoveryTTLFactor = 3
|
defaultDiscoveryTTLFactor = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
var errDiscoveryDisabled = errors.New("discovery is disabled")
|
// ErrDiscoveryDisabled is an error returned if the discovery is disabled
|
||||||
|
var ErrDiscoveryDisabled = errors.New("discovery is disabled")
|
||||||
|
|
||||||
type discoveryReloader interface {
|
// Reloader is the discovery reloader of the daemon
|
||||||
|
type Reloader interface {
|
||||||
discovery.Watcher
|
discovery.Watcher
|
||||||
Stop()
|
Stop()
|
||||||
Reload(backend, address string, clusterOpts map[string]string) error
|
Reload(backend, address string, clusterOpts map[string]string) error
|
||||||
|
@ -93,9 +94,9 @@ func discoveryOpts(clusterOpts map[string]string) (time.Duration, time.Duration,
|
||||||
return heartbeat, ttl, nil
|
return heartbeat, ttl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// initDiscovery initializes the nodes discovery subsystem by connecting to the specified backend
|
// Init initializes the nodes discovery subsystem by connecting to the specified backend
|
||||||
// and starts a registration loop to advertise the current node under the specified address.
|
// and starts a registration loop to advertise the current node under the specified address.
|
||||||
func initDiscovery(backendAddress, advertiseAddress string, clusterOpts map[string]string) (discoveryReloader, error) {
|
func Init(backendAddress, advertiseAddress string, clusterOpts map[string]string) (Reloader, error) {
|
||||||
heartbeat, backend, err := parseDiscoveryOptions(backendAddress, clusterOpts)
|
heartbeat, backend, err := parseDiscoveryOptions(backendAddress, clusterOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -198,18 +199,3 @@ func parseDiscoveryOptions(backendAddress string, clusterOpts map[string]string)
|
||||||
}
|
}
|
||||||
return heartbeat, backend, nil
|
return heartbeat, backend, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// modifiedDiscoverySettings returns whether the discovery configuration has been modified or not.
|
|
||||||
func modifiedDiscoverySettings(config *Config, backendType, advertise string, clusterOpts map[string]string) bool {
|
|
||||||
if config.ClusterStore != backendType || config.ClusterAdvertise != advertise {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.ClusterOpts == nil && clusterOpts == nil) ||
|
|
||||||
(config.ClusterOpts == nil && len(clusterOpts) == 0) ||
|
|
||||||
(len(config.ClusterOpts) == 0 && clusterOpts == nil) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return !reflect.DeepEqual(config.ClusterOpts, clusterOpts)
|
|
||||||
}
|
|
|
@ -1,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,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue