diff --git a/cmd/dockerd/config.go b/cmd/dockerd/config.go index 20cd999e9e..f39ce8ed54 100644 --- a/cmd/dockerd/config.go +++ b/cmd/dockerd/config.go @@ -1,8 +1,6 @@ package main import ( - "runtime" - "github.com/docker/docker/daemon/config" "github.com/docker/docker/opts" "github.com/docker/docker/registry" @@ -15,99 +13,89 @@ const defaultTrustKeyFile = "key.json" // installCommonConfigFlags adds flags to the pflag.FlagSet to configure the daemon func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) error { var maxConcurrentDownloads, maxConcurrentUploads, maxDownloadAttempts int - defaultPidFile, err := getDefaultPidFile() + var err error + conf.Pidfile, err = getDefaultPidFile() if err != nil { return err } - defaultDataRoot, err := getDefaultDataRoot() + conf.Root, err = getDefaultDataRoot() if err != nil { return err } - defaultExecRoot, err := getDefaultExecRoot() + conf.ExecRoot, err = getDefaultExecRoot() if err != nil { return err } - installRegistryServiceFlags(&conf.ServiceOptions, flags) + var ( + allowNonDistributable = opts.NewNamedListOptsRef("allow-nondistributable-artifacts", &conf.AllowNondistributableArtifacts, registry.ValidateIndexName) + registryMirrors = opts.NewNamedListOptsRef("registry-mirrors", &conf.Mirrors, registry.ValidateMirror) + insecureRegistries = opts.NewNamedListOptsRef("insecure-registries", &conf.InsecureRegistries, registry.ValidateIndexName) + ) + flags.Var(allowNonDistributable, "allow-nondistributable-artifacts", "Allow push of nondistributable artifacts to registry") + flags.Var(registryMirrors, "registry-mirror", "Preferred Docker registry mirror") + flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication") 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", defaultDataRoot, "Root of the Docker runtime") - flags.StringVar(&conf.ExecRoot, "exec-root", defaultExecRoot, "Root directory for execution state files") + flags.StringVarP(&conf.Pidfile, "pidfile", "p", conf.Pidfile, "Path to use for daemon PID file") + flags.StringVar(&conf.Root, "data-root", conf.Root, "Root directory of persistent Docker state") + flags.StringVar(&conf.ExecRoot, "exec-root", conf.ExecRoot, "Root directory for execution state files") flags.StringVar(&conf.ContainerdAddr, "containerd", "", "containerd grpc address") flags.BoolVar(&conf.CriContainerd, "cri-containerd", false, "start containerd with cri") - // "--graph" is "soft-deprecated" in favor of "data-root". This flag was added - // before Docker 1.0, so won't be removed, only hidden, to discourage its usage. - _ = flags.MarkHidden("graph") - - flags.StringVar(&conf.Root, "data-root", defaultDataRoot, "Root directory of persistent Docker state") - - 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") - - // Windows doesn't support setting the storage driver - there is no choice as to which ones to use. - if runtime.GOOS != "windows" { - flags.StringVarP(&conf.GraphDriver, "storage-driver", "s", "", "Storage driver to use") - } - flags.IntVar(&conf.Mtu, "mtu", 0, "Set the containers network MTU") + flags.IntVar(&conf.NetworkControlPlaneMTU, "network-control-plane-mtu", config.DefaultNetworkMtu, "Network Control plane MTU") + flags.IntVar(&conf.NetworkDiagnosticPort, "network-diagnostic-port", 0, "TCP port number of the network diagnostic server") + _ = flags.MarkHidden("network-diagnostic-port") + flags.BoolVar(&conf.RawLogs, "raw-logs", false, "Full timestamps without ANSI coloring") 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.NewIPOpt(&conf.HostGatewayIP, ""), "host-gateway-ip", "IP address that the special 'host-gateway' string in --add-host resolves to. Defaults to the IP address of the default bridge") + flags.IPVar(&conf.HostGatewayIP, "host-gateway-ip", nil, "IP address that the special 'host-gateway' string in --add-host resolves to. Defaults to the IP address of the default bridge") 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.MarkDeprecated("cluster-advertise", "Swarm classic is deprecated. Please use Swarm-mode (docker swarm init)") - flags.StringVar(&conf.ClusterStore, "cluster-store", "", "URL of the distributed storage backend") - _ = flags.MarkDeprecated("cluster-store", "Swarm classic is deprecated. Please use Swarm-mode (docker swarm init)") - flags.Var(opts.NewNamedMapOpts("cluster-store-opts", conf.ClusterOpts, nil), "cluster-store-opt", "Set cluster store options") - _ = flags.MarkDeprecated("cluster-store-opt", "Swarm classic is deprecated. Please use Swarm-mode (docker swarm init)") - 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(&maxDownloadAttempts, "max-download-attempts", config.DefaultDownloadAttempts, "Set the max download attempts for each pull") flags.IntVar(&conf.ShutdownTimeout, "shutdown-timeout", config.DefaultShutdownTimeout, "Set the default shutdown timeout") - flags.IntVar(&conf.NetworkDiagnosticPort, "network-diagnostic-port", 0, "TCP port number of the network diagnostic server") - _ = flags.MarkHidden("network-diagnostic-port") 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") - flags.Var(opts.NewNamedListOptsRef("node-generic-resources", &conf.NodeGenericResources, opts.ValidateSingleGenericResource), "node-generic-resource", "Advertise user-defined resource") - flags.IntVar(&conf.NetworkControlPlaneMTU, "network-control-plane-mtu", config.DefaultNetworkMtu, "Network Control plane MTU") - conf.MaxConcurrentDownloads = &maxConcurrentDownloads conf.MaxConcurrentUploads = &maxConcurrentUploads conf.MaxDownloadAttempts = &maxDownloadAttempts flags.StringVar(&conf.ContainerdNamespace, "containerd-namespace", config.DefaultContainersNamespace, "Containerd namespace to use") flags.StringVar(&conf.ContainerdPluginNamespace, "containerd-plugins-namespace", config.DefaultPluginNamespace, "Containerd namespace to use for plugins") - flags.StringVar(&conf.DefaultRuntime, "default-runtime", config.StockRuntimeName, "Default OCI runtime for containers") flags.StringVar(&conf.HTTPProxy, "http-proxy", "", "HTTP proxy URL to use for outgoing traffic") flags.StringVar(&conf.HTTPSProxy, "https-proxy", "", "HTTPS proxy URL to use for outgoing traffic") flags.StringVar(&conf.NoProxy, "no-proxy", "", "Comma-separated list of hosts or IP addresses for which the proxy is skipped") + // Deprecated flags / options + + // "--graph" is "soft-deprecated" in favor of "data-root". This flag was added + // before Docker 1.0, so won't be removed, only hidden, to discourage its usage. + flags.StringVarP(&conf.Root, "graph", "g", conf.Root, "Root of the Docker runtime") + _ = flags.MarkHidden("graph") + 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.StringVar(&conf.ClusterAdvertise, "cluster-advertise", "", "Address or interface name to advertise") + _ = flags.MarkDeprecated("cluster-advertise", "Swarm classic is deprecated. Please use Swarm-mode (docker swarm init)") + flags.StringVar(&conf.ClusterStore, "cluster-store", "", "URL of the distributed storage backend") + _ = flags.MarkDeprecated("cluster-store", "Swarm classic is deprecated. Please use Swarm-mode (docker swarm init)") + flags.Var(opts.NewNamedMapOpts("cluster-store-opts", conf.ClusterOpts, nil), "cluster-store-opt", "Set cluster store options") + _ = flags.MarkDeprecated("cluster-store-opt", "Swarm classic is deprecated. Please use Swarm-mode (docker swarm init)") + return nil } - -func installRegistryServiceFlags(options *registry.ServiceOptions, flags *pflag.FlagSet) { - ana := opts.NewNamedListOptsRef("allow-nondistributable-artifacts", &options.AllowNondistributableArtifacts, registry.ValidateIndexName) - mirrors := opts.NewNamedListOptsRef("registry-mirrors", &options.Mirrors, registry.ValidateMirror) - insecureRegistries := opts.NewNamedListOptsRef("insecure-registries", &options.InsecureRegistries, registry.ValidateIndexName) - - flags.Var(ana, "allow-nondistributable-artifacts", "Allow push of nondistributable artifacts to registry") - flags.Var(mirrors, "registry-mirror", "Preferred Docker registry mirror") - flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication") -} diff --git a/cmd/dockerd/config_common_unix.go b/cmd/dockerd/config_common_unix.go deleted file mode 100644 index dfbc3e2e3d..0000000000 --- a/cmd/dockerd/config_common_unix.go +++ /dev/null @@ -1,63 +0,0 @@ -//go:build linux || freebsd -// +build linux freebsd - -package main - -import ( - "path/filepath" - - "github.com/docker/docker/api/types" - "github.com/docker/docker/daemon/config" - "github.com/docker/docker/opts" - "github.com/docker/docker/pkg/homedir" - "github.com/spf13/pflag" -) - -func getDefaultPidFile() (string, error) { - if !honorXDG { - return "/var/run/docker.pid", nil - } - runtimeDir, err := homedir.GetRuntimeDir() - if err != nil { - return "", err - } - return filepath.Join(runtimeDir, "docker.pid"), nil -} - -func getDefaultDataRoot() (string, error) { - if !honorXDG { - return "/var/lib/docker", nil - } - dataHome, err := homedir.GetDataHome() - if err != nil { - return "", err - } - return filepath.Join(dataHome, "docker"), nil -} - -func getDefaultExecRoot() (string, error) { - if !honorXDG { - return "/var/run/docker", nil - } - runtimeDir, err := homedir.GetRuntimeDir() - if err != nil { - return "", err - } - return filepath.Join(runtimeDir, "docker"), nil -} - -// 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") -} diff --git a/cmd/dockerd/config_unix.go b/cmd/dockerd/config_unix.go index 6bd6f4acc2..6f7d5daee2 100644 --- a/cmd/dockerd/config_unix.go +++ b/cmd/dockerd/config_unix.go @@ -4,10 +4,12 @@ package main import ( + "net" "os/exec" "path/filepath" "github.com/containerd/cgroups" + "github.com/docker/docker/api/types" "github.com/docker/docker/daemon/config" "github.com/docker/docker/opts" "github.com/docker/docker/pkg/homedir" @@ -25,16 +27,17 @@ func installConfigFlags(conf *config.Config, flags *pflag.FlagSet) error { return err } - // Then install flags common to unix platforms - installUnixConfigFlags(conf, flags) - conf.Ulimits = make(map[string]*units.Ulimit) conf.NetworkConfig.DefaultAddressPools = opts.PoolsOpt{} // Set default value for `--default-shm-size` conf.ShmSize = opts.MemBytes(config.DefaultShmSize) + conf.Runtimes = make(map[string]types.Runtime) // Then platform-specific install flags + flags.Var(opts.NewNamedRuntimeOpt("runtimes", &conf.Runtimes, config.StockRuntimeName), "add-runtime", "Register an additional OCI compatible runtime") + flags.StringVarP(&conf.SocketGroup, "group", "G", "docker", "Group for the unix socket") + flags.StringVarP(&conf.GraphDriver, "storage-driver", "s", "", "Storage driver to use") flags.BoolVar(&conf.EnableSelinuxSupport, "selinux-enabled", false, "Enable selinux support") flags.Var(opts.NewNamedUlimitOpt("default-ulimits", &conf.Ulimits), "default-ulimit", "Default ulimits for containers") flags.BoolVar(&conf.BridgeConfig.EnableIPTables, "iptables", true, "Enable addition of iptables rules") @@ -42,7 +45,14 @@ func installConfigFlags(conf *config.Config, flags *pflag.FlagSet) error { 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.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.StringVar(&conf.BridgeConfig.FixedCIDRv6, "fixed-cidr-v6", "", "IPv6 subnet for fixed IPs") + flags.IPVar(&conf.BridgeConfig.DefaultGatewayIPv4, "default-gateway", nil, "Container default gateway IPv4 address") + flags.IPVar(&conf.BridgeConfig.DefaultGatewayIPv6, "default-gateway-v6", nil, "Container default gateway IPv6 address") + flags.BoolVar(&conf.BridgeConfig.InterContainerCommunication, "icc", true, "Enable inter-container communication") + flags.IPVar(&conf.BridgeConfig.DefaultIP, "ip", net.IPv4zero, "Default IP when binding container ports") flags.BoolVar(&conf.BridgeConfig.EnableUserlandProxy, "userland-proxy", true, "Use userland proxy for loopback traffic") defaultUserlandProxyPath := "" if rootless.RunningWithRootlessKit() { @@ -88,3 +98,36 @@ func configureCertsDir() { } } } + +func getDefaultPidFile() (string, error) { + if !honorXDG { + return "/var/run/docker.pid", nil + } + runtimeDir, err := homedir.GetRuntimeDir() + if err != nil { + return "", err + } + return filepath.Join(runtimeDir, "docker.pid"), nil +} + +func getDefaultDataRoot() (string, error) { + if !honorXDG { + return "/var/lib/docker", nil + } + dataHome, err := homedir.GetDataHome() + if err != nil { + return "", err + } + return filepath.Join(dataHome, "docker"), nil +} + +func getDefaultExecRoot() (string, error) { + if !honorXDG { + return "/var/run/docker", nil + } + runtimeDir, err := homedir.GetRuntimeDir() + if err != nil { + return "", err + } + return filepath.Join(runtimeDir, "docker"), nil +} diff --git a/opts/ip.go b/opts/ip.go deleted file mode 100644 index cfbff3a9fd..0000000000 --- a/opts/ip.go +++ /dev/null @@ -1,47 +0,0 @@ -package opts // import "github.com/docker/docker/opts" - -import ( - "fmt" - "net" -) - -// IPOpt holds an IP. It is used to store values from CLI flags. -type IPOpt struct { - *net.IP -} - -// NewIPOpt creates a new IPOpt from a reference net.IP and a -// string representation of an IP. If the string is not a valid -// IP it will fallback to the specified reference. -func NewIPOpt(ref *net.IP, defaultVal string) *IPOpt { - o := &IPOpt{ - IP: ref, - } - o.Set(defaultVal) - return o -} - -// Set sets an IPv4 or IPv6 address from a given string. If the given -// string is not parsable as an IP address it returns an error. -func (o *IPOpt) Set(val string) error { - ip := net.ParseIP(val) - if ip == nil { - return fmt.Errorf("%s is not an ip address", val) - } - *o.IP = ip - return nil -} - -// String returns the IP address stored in the IPOpt. If stored IP is a -// nil pointer, it returns an empty string. -func (o *IPOpt) String() string { - if *o.IP == nil { - return "" - } - return o.IP.String() -} - -// Type returns the type of the option -func (o *IPOpt) Type() string { - return "ip" -} diff --git a/opts/ip_test.go b/opts/ip_test.go deleted file mode 100644 index 966d7f21ec..0000000000 --- a/opts/ip_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package opts // import "github.com/docker/docker/opts" - -import ( - "net" - "testing" -) - -func TestIpOptString(t *testing.T) { - addresses := []string{"", "0.0.0.0"} - var ip net.IP - - for _, address := range addresses { - stringAddress := NewIPOpt(&ip, address).String() - if stringAddress != address { - t.Fatalf("IpOpt string should be `%s`, not `%s`", address, stringAddress) - } - } -} - -func TestNewIpOptInvalidDefaultVal(t *testing.T) { - ip := net.IPv4(127, 0, 0, 1) - defaultVal := "Not an ip" - - ipOpt := NewIPOpt(&ip, defaultVal) - - expected := "127.0.0.1" - if ipOpt.String() != expected { - t.Fatalf("Expected [%v], got [%v]", expected, ipOpt.String()) - } -} - -func TestNewIpOptValidDefaultVal(t *testing.T) { - ip := net.IPv4(127, 0, 0, 1) - defaultVal := "192.168.1.1" - - ipOpt := NewIPOpt(&ip, defaultVal) - - expected := "192.168.1.1" - if ipOpt.String() != expected { - t.Fatalf("Expected [%v], got [%v]", expected, ipOpt.String()) - } -} - -func TestIpOptSetInvalidVal(t *testing.T) { - ip := net.IPv4(127, 0, 0, 1) - ipOpt := &IPOpt{IP: &ip} - - invalidIP := "invalid ip" - expectedError := "invalid ip is not an ip address" - err := ipOpt.Set(invalidIP) - if err == nil || err.Error() != expectedError { - t.Fatalf("Expected an Error with [%v], got [%v]", expectedError, err.Error()) - } -}