// InstallCommonFlags adds command-line options to the top-level flag parser for // the current process. // Subsequent calls to `flag.Parse` will populate config with values parsed // from the command-line. func (config *Config) InstallCommonFlags(cmd *flag.FlagSet, usageFn func(string) string) { var maxConcurrentDownloads, maxConcurrentUploads int config.ServiceOptions.InstallCliFlags(cmd, usageFn) cmd.Var(opts.NewNamedListOptsRef("storage-opts", &config.GraphOptions, nil), []string{"-storage-opt"}, usageFn("Storage driver options")) cmd.Var(opts.NewNamedListOptsRef("authorization-plugins", &config.AuthorizationPlugins, nil), []string{"-authorization-plugin"}, usageFn("Authorization plugins to load")) cmd.Var(opts.NewNamedListOptsRef("exec-opts", &config.ExecOptions, nil), []string{"-exec-opt"}, usageFn("Runtime execution options")) cmd.StringVar(&config.Pidfile, []string{"p", "-pidfile"}, defaultPidFile, usageFn("Path to use for daemon PID file")) cmd.StringVar(&config.Root, []string{"g", "-graph"}, defaultGraph, usageFn("Root of the Docker runtime")) cmd.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, usageFn("--restart on the daemon has been deprecated in favor of --restart policies on docker run")) cmd.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", usageFn("Storage driver to use")) cmd.IntVar(&config.Mtu, []string{"#mtu", "-mtu"}, 0, usageFn("Set the containers network MTU")) cmd.BoolVar(&config.RawLogs, []string{"-raw-logs"}, false, usageFn("Full timestamps without ANSI coloring")) // FIXME: why the inconsistency between "hosts" and "sockets"? cmd.Var(opts.NewListOptsRef(&config.DNS, opts.ValidateIPAddress), []string{"#dns", "-dns"}, usageFn("DNS server to use")) cmd.Var(opts.NewNamedListOptsRef("dns-opts", &config.DNSOptions, nil), []string{"-dns-opt"}, usageFn("DNS options to use")) cmd.Var(opts.NewListOptsRef(&config.DNSSearch, opts.ValidateDNSSearch), []string{"-dns-search"}, usageFn("DNS search domains to use")) cmd.Var(opts.NewNamedListOptsRef("labels", &config.Labels, opts.ValidateLabel), []string{"-label"}, usageFn("Set key=value labels to the daemon")) cmd.StringVar(&config.LogConfig.Type, []string{"-log-driver"}, "json-file", usageFn("Default driver for container logs")) cmd.Var(opts.NewNamedMapOpts("log-opts", config.LogConfig.Config, nil), []string{"-log-opt"}, usageFn("Default log driver options for containers")) cmd.StringVar(&config.ClusterAdvertise, []string{"-cluster-advertise"}, "", usageFn("Address or interface name to advertise")) cmd.StringVar(&config.ClusterStore, []string{"-cluster-store"}, "", usageFn("URL of the distributed storage backend")) cmd.Var(opts.NewNamedMapOpts("cluster-store-opts", config.ClusterOpts, nil), []string{"-cluster-store-opt"}, usageFn("Set cluster store options")) cmd.StringVar(&config.CorsHeaders, []string{"-api-cors-header"}, "", usageFn("Set CORS headers in the remote API")) cmd.IntVar(&maxConcurrentDownloads, []string{"-max-concurrent-downloads"}, defaultMaxConcurrentDownloads, usageFn("Set the max concurrent downloads for each pull")) cmd.IntVar(&maxConcurrentUploads, []string{"-max-concurrent-uploads"}, defaultMaxConcurrentUploads, usageFn("Set the max concurrent uploads for each push")) config.MaxConcurrentDownloads = &maxConcurrentDownloads config.MaxConcurrentUploads = &maxConcurrentUploads }
// 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 remote 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.StringVar(&config.SwarmDefaultAdvertiseAddr, "swarm-default-advertise-addr", "", "Set default address or interface for swarm advertised address") config.MaxConcurrentDownloads = &maxConcurrentDownloads config.MaxConcurrentUploads = &maxConcurrentUploads }
func TestLoadDaemonConfigWithMapOptions(t *testing.T) { c := &daemon.Config{} common := &cli.CommonFlags{} flags := mflag.NewFlagSet("test", mflag.ContinueOnError) flags.Var(opts.NewNamedMapOpts("cluster-store-opts", c.ClusterOpts, nil), []string{"-cluster-store-opt"}, "") flags.Var(opts.NewNamedMapOpts("log-opts", c.LogConfig.Config, nil), []string{"-log-opt"}, "") f, err := ioutil.TempFile("", "docker-config-") if err != nil { t.Fatal(err) } configFile := f.Name() f.Write([]byte(`{ "cluster-store-opts": {"kv.cacertfile": "/var/lib/docker/discovery_certs/ca.pem"}, "log-opts": {"tag": "test"} }`)) f.Close() loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile) if err != nil { t.Fatal(err) } if loadedConfig == nil { t.Fatal("expected configuration, got nil") } if loadedConfig.ClusterOpts == nil { t.Fatal("expected cluster options, got nil") } expectedPath := "/var/lib/docker/discovery_certs/ca.pem" if caPath := loadedConfig.ClusterOpts["kv.cacertfile"]; caPath != expectedPath { t.Fatalf("expected %s, got %s", expectedPath, caPath) } if loadedConfig.LogConfig.Config == nil { t.Fatal("expected log config options, got nil") } if tag := loadedConfig.LogConfig.Config["tag"]; tag != "test" { t.Fatalf("expected log tag `test`, got %s", tag) } }
// InstallCommonFlags adds command-line options to the top-level flag parser for // the current process. // Subsequent calls to `flag.Parse` will populate config with values parsed // from the command-line. func (config *Config) InstallCommonFlags(cmd *flag.FlagSet, usageFn func(string) string) { cmd.Var(opts.NewNamedListOptsRef("storage-opts", &config.GraphOptions, nil), []string{"-storage-opt"}, usageFn("Set storage driver options")) cmd.Var(opts.NewNamedListOptsRef("authorization-plugins", &config.AuthorizationPlugins, nil), []string{"-authorization-plugin"}, usageFn("List authorization plugins in order from first evaluator to last")) cmd.Var(opts.NewNamedListOptsRef("exec-opts", &config.ExecOptions, nil), []string{"-exec-opt"}, usageFn("Set exec driver options")) cmd.StringVar(&config.Pidfile, []string{"p", "-pidfile"}, defaultPidFile, usageFn("Path to use for daemon PID file")) cmd.StringVar(&config.Root, []string{"g", "-graph"}, defaultGraph, usageFn("Root of the Docker runtime")) cmd.StringVar(&config.ExecRoot, []string{"-exec-root"}, "/var/run/docker", usageFn("Root of the Docker execdriver")) cmd.BoolVar(&config.AutoRestart, []string{"#r", "#-restart"}, true, usageFn("--restart on the daemon has been deprecated in favor of --restart policies on docker run")) cmd.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", usageFn("Storage driver to use")) cmd.IntVar(&config.Mtu, []string{"#mtu", "-mtu"}, 0, usageFn("Set the containers network MTU")) // FIXME: why the inconsistency between "hosts" and "sockets"? cmd.Var(opts.NewListOptsRef(&config.DNS, opts.ValidateIPAddress), []string{"#dns", "-dns"}, usageFn("DNS server to use")) cmd.Var(opts.NewNamedListOptsRef("dns-opts", &config.DNSOptions, nil), []string{"-dns-opt"}, usageFn("DNS options to use")) cmd.Var(opts.NewListOptsRef(&config.DNSSearch, opts.ValidateDNSSearch), []string{"-dns-search"}, usageFn("DNS search domains to use")) cmd.Var(opts.NewNamedListOptsRef("labels", &config.Labels, opts.ValidateLabel), []string{"-label"}, usageFn("Set key=value labels to the daemon")) cmd.StringVar(&config.LogConfig.Type, []string{"-log-driver"}, "json-file", usageFn("Default driver for container logs")) cmd.Var(opts.NewNamedMapOpts("log-opts", config.LogConfig.Config, nil), []string{"-log-opt"}, usageFn("Set log driver options")) cmd.StringVar(&config.ClusterAdvertise, []string{"-cluster-advertise"}, "", usageFn("Address or interface name to advertise")) cmd.StringVar(&config.ClusterStore, []string{"-cluster-store"}, "", usageFn("Set the cluster store")) cmd.Var(opts.NewNamedMapOpts("cluster-store-opts", config.ClusterOpts, nil), []string{"-cluster-store-opt"}, usageFn("Set cluster store options")) }
func TestLoadDaemonCliConfigWithDaemonFlags(t *testing.T) { c := &daemon.Config{} common := &cli.CommonFlags{ Debug: true, LogLevel: "info", } f, err := ioutil.TempFile("", "docker-config-") if err != nil { t.Fatal(err) } configFile := f.Name() f.Write([]byte(`{"log-opts": {"max-size": "1k"}}`)) f.Close() flags := mflag.NewFlagSet("test", mflag.ContinueOnError) flags.String([]string{daemonConfigFileFlag}, "", "") flags.BoolVar(&c.EnableSelinuxSupport, []string{"-selinux-enabled"}, true, "") flags.StringVar(&c.LogConfig.Type, []string{"-log-driver"}, "json-file", "") flags.Var(opts.NewNamedMapOpts("log-opts", c.LogConfig.Config, nil), []string{"-log-opt"}, "") flags.Set(daemonConfigFileFlag, configFile) loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile) if err != nil { t.Fatal(err) } if loadedConfig == nil { t.Fatalf("expected configuration %v, got nil", c) } if !loadedConfig.Debug { t.Fatalf("expected debug mode, got false") } if loadedConfig.LogLevel != "info" { t.Fatalf("expected info log level, got %v", loadedConfig.LogLevel) } if !loadedConfig.EnableSelinuxSupport { t.Fatalf("expected enabled selinux support, got disabled") } if loadedConfig.LogConfig.Type != "json-file" { t.Fatalf("expected LogConfig type json-file, got %v", loadedConfig.LogConfig.Type) } if maxSize := loadedConfig.LogConfig.Config["max-size"]; maxSize != "1k" { t.Fatalf("expected log max-size `1k`, got %s", maxSize) } }