Cleanup cobra integration
Update windows files for cobra and pflags
Cleanup SetupRootcmd, and remove unnecessary SetFlagErrorFunc.
Use cobra command traversal
Signed-off-by: Daniel Nephin <dnephin@docker.com>
... | ... |
@@ -6,6 +6,7 @@ import ( |
6 | 6 |
"io" |
7 | 7 |
"net/http" |
8 | 8 |
"os" |
9 |
+ "path/filepath" |
|
9 | 10 |
"runtime" |
10 | 11 |
|
11 | 12 |
"github.com/docker/docker/api" |
... | ... |
@@ -164,22 +165,23 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions) error { |
164 | 164 |
if cli.out != nil { |
165 | 165 |
cli.outFd, cli.isTerminalOut = term.GetFdInfo(cli.out) |
166 | 166 |
} |
167 |
+ |
|
168 |
+ if opts.Common.TrustKey == "" { |
|
169 |
+ cli.keyFile = filepath.Join(cliconfig.ConfigDir(), cliflags.DefaultTrustKeyFile) |
|
170 |
+ } else { |
|
171 |
+ cli.keyFile = opts.Common.TrustKey |
|
172 |
+ } |
|
173 |
+ |
|
167 | 174 |
return nil |
168 | 175 |
} |
169 | 176 |
|
170 | 177 |
// NewDockerCli returns a DockerCli instance with IO output and error streams set by in, out and err. |
171 |
-// The key file, protocol (i.e. unix) and address are passed in as strings, along with the tls.Config. If the tls.Config |
|
172 |
-// is set the client scheme will be set to https. |
|
173 |
-// The client will be given a 32-second timeout (see https://github.com/docker/docker/pull/8035). |
|
174 |
-func NewDockerCli(in io.ReadCloser, out, err io.Writer, clientOpts *cliflags.ClientOptions) *DockerCli { |
|
175 |
- cli := &DockerCli{ |
|
178 |
+func NewDockerCli(in io.ReadCloser, out, err io.Writer) *DockerCli { |
|
179 |
+ return &DockerCli{ |
|
176 | 180 |
in: in, |
177 | 181 |
out: out, |
178 | 182 |
err: err, |
179 |
- // TODO: just pass trustKey, not the entire opts struct |
|
180 |
- keyFile: clientOpts.Common.TrustKey, |
|
181 | 183 |
} |
182 |
- return cli |
|
183 | 184 |
} |
184 | 185 |
|
185 | 186 |
// LoadDefaultConfigFile attempts to load the default config file and returns |
... | ... |
@@ -36,7 +36,6 @@ func NewAttachCommand(dockerCli *client.DockerCli) *cobra.Command { |
36 | 36 |
return runAttach(dockerCli, &opts) |
37 | 37 |
}, |
38 | 38 |
} |
39 |
- cmd.SetFlagErrorFunc(flagErrorFunc) |
|
40 | 39 |
|
41 | 40 |
flags := cmd.Flags() |
42 | 41 |
flags.BoolVar(&opts.noStdin, "no-stdin", false, "Do not attach STDIN") |
... | ... |
@@ -19,7 +19,7 @@ type diffOptions struct { |
19 | 19 |
func NewDiffCommand(dockerCli *client.DockerCli) *cobra.Command { |
20 | 20 |
var opts diffOptions |
21 | 21 |
|
22 |
- cmd := &cobra.Command{ |
|
22 |
+ return &cobra.Command{ |
|
23 | 23 |
Use: "diff CONTAINER", |
24 | 24 |
Short: "Inspect changes on a container's filesystem", |
25 | 25 |
Args: cli.ExactArgs(1), |
... | ... |
@@ -28,9 +28,6 @@ func NewDiffCommand(dockerCli *client.DockerCli) *cobra.Command { |
28 | 28 |
return runDiff(dockerCli, &opts) |
29 | 29 |
}, |
30 | 30 |
} |
31 |
- cmd.SetFlagErrorFunc(flagErrorFunc) |
|
32 |
- |
|
33 |
- return cmd |
|
34 | 31 |
} |
35 | 32 |
|
36 | 33 |
func runDiff(dockerCli *client.DockerCli, opts *diffOptions) error { |
... | ... |
@@ -19,7 +19,7 @@ type pauseOptions struct { |
19 | 19 |
func NewPauseCommand(dockerCli *client.DockerCli) *cobra.Command { |
20 | 20 |
var opts pauseOptions |
21 | 21 |
|
22 |
- cmd := &cobra.Command{ |
|
22 |
+ return &cobra.Command{ |
|
23 | 23 |
Use: "pause CONTAINER [CONTAINER...]", |
24 | 24 |
Short: "Pause all processes within one or more containers", |
25 | 25 |
Args: cli.RequiresMinArgs(1), |
... | ... |
@@ -28,9 +28,6 @@ func NewPauseCommand(dockerCli *client.DockerCli) *cobra.Command { |
28 | 28 |
return runPause(dockerCli, &opts) |
29 | 29 |
}, |
30 | 30 |
} |
31 |
- cmd.SetFlagErrorFunc(flagErrorFunc) |
|
32 |
- |
|
33 |
- return cmd |
|
34 | 31 |
} |
35 | 32 |
|
36 | 33 |
func runPause(dockerCli *client.DockerCli, opts *pauseOptions) error { |
... | ... |
@@ -14,6 +14,7 @@ import ( |
14 | 14 |
"github.com/Sirupsen/logrus" |
15 | 15 |
"github.com/docker/docker/api/client" |
16 | 16 |
"github.com/docker/docker/cli" |
17 |
+ "github.com/docker/docker/cli/cobraadaptor" |
|
17 | 18 |
opttypes "github.com/docker/docker/opts" |
18 | 19 |
"github.com/docker/docker/pkg/promise" |
19 | 20 |
"github.com/docker/docker/pkg/signal" |
... | ... |
@@ -48,7 +49,6 @@ func NewRunCommand(dockerCli *client.DockerCli) *cobra.Command { |
48 | 48 |
return runRun(dockerCli, cmd.Flags(), &opts, copts) |
49 | 49 |
}, |
50 | 50 |
} |
51 |
- cmd.SetFlagErrorFunc(flagErrorFunc) |
|
52 | 51 |
|
53 | 52 |
flags := cmd.Flags() |
54 | 53 |
flags.SetInterspersed(false) |
... | ... |
@@ -70,7 +70,7 @@ func NewRunCommand(dockerCli *client.DockerCli) *cobra.Command { |
70 | 70 |
|
71 | 71 |
func flagErrorFunc(cmd *cobra.Command, err error) error { |
72 | 72 |
return cli.StatusError{ |
73 |
- Status: cli.FlagErrorFunc(cmd, err).Error(), |
|
73 |
+ Status: cobraadaptor.FlagErrorFunc(cmd, err).Error(), |
|
74 | 74 |
StatusCode: 125, |
75 | 75 |
} |
76 | 76 |
} |
... | ... |
@@ -37,7 +37,6 @@ func NewStartCommand(dockerCli *client.DockerCli) *cobra.Command { |
37 | 37 |
return runStart(dockerCli, &opts) |
38 | 38 |
}, |
39 | 39 |
} |
40 |
- cmd.SetFlagErrorFunc(flagErrorFunc) |
|
41 | 40 |
|
42 | 41 |
flags := cmd.Flags() |
43 | 42 |
flags.BoolVarP(&opts.attach, "attach", "a", false, "Attach STDOUT/STDERR and forward signals") |
... | ... |
@@ -31,7 +31,6 @@ func NewStopCommand(dockerCli *client.DockerCli) *cobra.Command { |
31 | 31 |
return runStop(dockerCli, &opts) |
32 | 32 |
}, |
33 | 33 |
} |
34 |
- cmd.SetFlagErrorFunc(flagErrorFunc) |
|
35 | 34 |
|
36 | 35 |
flags := cmd.Flags() |
37 | 36 |
flags.IntVarP(&opts.time, "time", "t", 10, "Seconds to wait for stop before killing it") |
... | ... |
@@ -1,81 +1,17 @@ |
1 | 1 |
package cobraadaptor |
2 | 2 |
|
3 | 3 |
import ( |
4 |
- "github.com/docker/docker/api/client" |
|
5 |
- "github.com/docker/docker/api/client/container" |
|
6 |
- "github.com/docker/docker/api/client/image" |
|
7 |
- "github.com/docker/docker/api/client/network" |
|
8 |
- "github.com/docker/docker/api/client/node" |
|
9 |
- "github.com/docker/docker/api/client/plugin" |
|
10 |
- "github.com/docker/docker/api/client/registry" |
|
11 |
- "github.com/docker/docker/api/client/service" |
|
12 |
- "github.com/docker/docker/api/client/stack" |
|
13 |
- "github.com/docker/docker/api/client/swarm" |
|
14 |
- "github.com/docker/docker/api/client/system" |
|
15 |
- "github.com/docker/docker/api/client/volume" |
|
16 |
- "github.com/docker/docker/cli" |
|
4 |
+ "fmt" |
|
5 |
+ |
|
17 | 6 |
"github.com/spf13/cobra" |
18 | 7 |
) |
19 | 8 |
|
20 | 9 |
// SetupRootCommand sets default usage, help, and error handling for the |
21 | 10 |
// root command. |
22 |
-// TODO: move to cmd/docker/docker? |
|
23 |
-// TODO: split into common setup and client setup |
|
24 |
-func SetupRootCommand(rootCmd *cobra.Command, dockerCli *client.DockerCli) { |
|
11 |
+func SetupRootCommand(rootCmd *cobra.Command) { |
|
25 | 12 |
rootCmd.SetUsageTemplate(usageTemplate) |
26 | 13 |
rootCmd.SetHelpTemplate(helpTemplate) |
27 |
- rootCmd.SetFlagErrorFunc(cli.FlagErrorFunc) |
|
28 |
- rootCmd.SetOutput(dockerCli.Out()) |
|
29 |
- rootCmd.AddCommand( |
|
30 |
- node.NewNodeCommand(dockerCli), |
|
31 |
- service.NewServiceCommand(dockerCli), |
|
32 |
- stack.NewStackCommand(dockerCli), |
|
33 |
- stack.NewTopLevelDeployCommand(dockerCli), |
|
34 |
- swarm.NewSwarmCommand(dockerCli), |
|
35 |
- container.NewAttachCommand(dockerCli), |
|
36 |
- container.NewCommitCommand(dockerCli), |
|
37 |
- container.NewCopyCommand(dockerCli), |
|
38 |
- container.NewCreateCommand(dockerCli), |
|
39 |
- container.NewDiffCommand(dockerCli), |
|
40 |
- container.NewExecCommand(dockerCli), |
|
41 |
- container.NewExportCommand(dockerCli), |
|
42 |
- container.NewKillCommand(dockerCli), |
|
43 |
- container.NewLogsCommand(dockerCli), |
|
44 |
- container.NewPauseCommand(dockerCli), |
|
45 |
- container.NewPortCommand(dockerCli), |
|
46 |
- container.NewPsCommand(dockerCli), |
|
47 |
- container.NewRenameCommand(dockerCli), |
|
48 |
- container.NewRestartCommand(dockerCli), |
|
49 |
- container.NewRmCommand(dockerCli), |
|
50 |
- container.NewRunCommand(dockerCli), |
|
51 |
- container.NewStartCommand(dockerCli), |
|
52 |
- container.NewStatsCommand(dockerCli), |
|
53 |
- container.NewStopCommand(dockerCli), |
|
54 |
- container.NewTopCommand(dockerCli), |
|
55 |
- container.NewUnpauseCommand(dockerCli), |
|
56 |
- container.NewUpdateCommand(dockerCli), |
|
57 |
- container.NewWaitCommand(dockerCli), |
|
58 |
- image.NewBuildCommand(dockerCli), |
|
59 |
- image.NewHistoryCommand(dockerCli), |
|
60 |
- image.NewImagesCommand(dockerCli), |
|
61 |
- image.NewLoadCommand(dockerCli), |
|
62 |
- image.NewRemoveCommand(dockerCli), |
|
63 |
- image.NewSaveCommand(dockerCli), |
|
64 |
- image.NewPullCommand(dockerCli), |
|
65 |
- image.NewPushCommand(dockerCli), |
|
66 |
- image.NewSearchCommand(dockerCli), |
|
67 |
- image.NewImportCommand(dockerCli), |
|
68 |
- image.NewTagCommand(dockerCli), |
|
69 |
- network.NewNetworkCommand(dockerCli), |
|
70 |
- system.NewEventsCommand(dockerCli), |
|
71 |
- system.NewInspectCommand(dockerCli), |
|
72 |
- registry.NewLoginCommand(dockerCli), |
|
73 |
- registry.NewLogoutCommand(dockerCli), |
|
74 |
- system.NewVersionCommand(dockerCli), |
|
75 |
- volume.NewVolumeCommand(dockerCli), |
|
76 |
- system.NewInfoCommand(dockerCli), |
|
77 |
- ) |
|
78 |
- plugin.NewPluginCommand(rootCmd, dockerCli) |
|
14 |
+ rootCmd.SetFlagErrorFunc(FlagErrorFunc) |
|
79 | 15 |
|
80 | 16 |
rootCmd.PersistentFlags().BoolP("help", "h", false, "Print usage") |
81 | 17 |
rootCmd.PersistentFlags().MarkShorthandDeprecated("help", "please use --help") |
... | ... |
@@ -87,6 +23,20 @@ func (c CobraAdaptor) GetRootCommand() *cobra.Command { |
87 | 87 |
return c.rootCmd |
88 | 88 |
} |
89 | 89 |
|
90 |
+// FlagErrorFunc prints an error messages which matches the format of the |
|
91 |
+// docker/docker/cli error messages |
|
92 |
+func FlagErrorFunc(cmd *cobra.Command, err error) error { |
|
93 |
+ if err == nil { |
|
94 |
+ return err |
|
95 |
+ } |
|
96 |
+ |
|
97 |
+ usage := "" |
|
98 |
+ if cmd.HasSubCommands() { |
|
99 |
+ usage = "\n\n" + cmd.UsageString() |
|
100 |
+ } |
|
101 |
+ return fmt.Errorf("%s\nSee '%s --help'.%s", err, cmd.CommandPath(), usage) |
|
102 |
+} |
|
103 |
+ |
|
90 | 104 |
var usageTemplate = `Usage: {{if not .HasSubCommands}}{{.UseLine}}{{end}}{{if .HasSubCommands}}{{ .CommandPath}} COMMAND{{end}} |
91 | 105 |
|
92 | 106 |
{{ .Short | trim }}{{if gt .Aliases 0}} |
93 | 107 |
deleted file mode 100644 |
... | ... |
@@ -1,21 +0,0 @@ |
1 |
-package cli |
|
2 |
- |
|
3 |
-import ( |
|
4 |
- "fmt" |
|
5 |
- |
|
6 |
- "github.com/spf13/cobra" |
|
7 |
-) |
|
8 |
- |
|
9 |
-// FlagErrorFunc prints an error messages which matches the format of the |
|
10 |
-// docker/docker/cli error messages |
|
11 |
-func FlagErrorFunc(cmd *cobra.Command, err error) error { |
|
12 |
- if err == nil { |
|
13 |
- return err |
|
14 |
- } |
|
15 |
- |
|
16 |
- usage := "" |
|
17 |
- if cmd.HasSubCommands() { |
|
18 |
- usage = "\n\n" + cmd.UsageString() |
|
19 |
- } |
|
20 |
- return fmt.Errorf("%s\nSee '%s --help'.%s", err, cmd.CommandPath(), usage) |
|
21 |
-} |
... | ... |
@@ -43,9 +43,7 @@ type CommonOptions struct { |
43 | 43 |
|
44 | 44 |
// NewCommonOptions returns a new CommonOptions |
45 | 45 |
func NewCommonOptions() *CommonOptions { |
46 |
- return &CommonOptions{ |
|
47 |
- TLSOptions: &tlsconfig.Options{}, |
|
48 |
- } |
|
46 |
+ return &CommonOptions{} |
|
49 | 47 |
} |
50 | 48 |
|
51 | 49 |
// InstallFlags adds flags for the common options on the FlagSet |
... | ... |
@@ -61,13 +59,14 @@ func (commonOpts *CommonOptions) InstallFlags(flags *pflag.FlagSet) { |
61 | 61 |
|
62 | 62 |
// TODO use flag flags.String("identity"}, "i", "", "Path to libtrust key file") |
63 | 63 |
|
64 |
+ commonOpts.TLSOptions = &tlsconfig.Options{} |
|
64 | 65 |
tlsOptions := commonOpts.TLSOptions |
65 | 66 |
flags.StringVar(&tlsOptions.CAFile, "tlscacert", filepath.Join(dockerCertPath, DefaultCaFile), "Trust certs signed only by this CA") |
66 | 67 |
flags.StringVar(&tlsOptions.CertFile, "tlscert", filepath.Join(dockerCertPath, DefaultCertFile), "Path to TLS certificate file") |
67 | 68 |
flags.StringVar(&tlsOptions.KeyFile, "tlskey", filepath.Join(dockerCertPath, DefaultKeyFile), "Path to TLS key file") |
68 | 69 |
|
69 | 70 |
hostOpt := opts.NewNamedListOptsRef("hosts", &commonOpts.Hosts, opts.ValidateHost) |
70 |
- flags.VarP(hostOpt, "-host", "H", "Daemon socket(s) to connect to") |
|
71 |
+ flags.VarP(hostOpt, "host", "H", "Daemon socket(s) to connect to") |
|
71 | 72 |
} |
72 | 73 |
|
73 | 74 |
// SetDefaultOptions sets default values for options after flag parsing is |
... | ... |
@@ -3,10 +3,20 @@ package main |
3 | 3 |
import ( |
4 | 4 |
"fmt" |
5 | 5 |
"os" |
6 |
- "path/filepath" |
|
7 | 6 |
|
8 | 7 |
"github.com/Sirupsen/logrus" |
9 | 8 |
"github.com/docker/docker/api/client" |
9 |
+ "github.com/docker/docker/api/client/container" |
|
10 |
+ "github.com/docker/docker/api/client/image" |
|
11 |
+ "github.com/docker/docker/api/client/network" |
|
12 |
+ "github.com/docker/docker/api/client/node" |
|
13 |
+ "github.com/docker/docker/api/client/plugin" |
|
14 |
+ "github.com/docker/docker/api/client/registry" |
|
15 |
+ "github.com/docker/docker/api/client/service" |
|
16 |
+ "github.com/docker/docker/api/client/stack" |
|
17 |
+ "github.com/docker/docker/api/client/swarm" |
|
18 |
+ "github.com/docker/docker/api/client/system" |
|
19 |
+ "github.com/docker/docker/api/client/volume" |
|
10 | 20 |
"github.com/docker/docker/cli" |
11 | 21 |
"github.com/docker/docker/cli/cobraadaptor" |
12 | 22 |
cliflags "github.com/docker/docker/cli/flags" |
... | ... |
@@ -18,13 +28,15 @@ import ( |
18 | 18 |
"github.com/spf13/pflag" |
19 | 19 |
) |
20 | 20 |
|
21 |
-func newDockerCommand(dockerCli *client.DockerCli, opts *cliflags.ClientOptions) *cobra.Command { |
|
21 |
+func newDockerCommand(dockerCli *client.DockerCli) *cobra.Command { |
|
22 |
+ opts := cliflags.NewClientOptions() |
|
22 | 23 |
cmd := &cobra.Command{ |
23 |
- Use: "docker [OPTIONS] COMMAND [arg...]", |
|
24 |
- Short: "A self-sufficient runtime for containers.", |
|
25 |
- SilenceUsage: true, |
|
26 |
- SilenceErrors: true, |
|
27 |
- Args: cli.NoArgs, |
|
24 |
+ Use: "docker [OPTIONS] COMMAND [arg...]", |
|
25 |
+ Short: "A self-sufficient runtime for containers.", |
|
26 |
+ SilenceUsage: true, |
|
27 |
+ SilenceErrors: true, |
|
28 |
+ TraverseChildren: true, |
|
29 |
+ Args: cli.NoArgs, |
|
28 | 30 |
RunE: func(cmd *cobra.Command, args []string) error { |
29 | 31 |
if opts.Version { |
30 | 32 |
showVersion() |
... | ... |
@@ -38,13 +50,66 @@ func newDockerCommand(dockerCli *client.DockerCli, opts *cliflags.ClientOptions) |
38 | 38 |
return dockerCli.Initialize(opts) |
39 | 39 |
}, |
40 | 40 |
} |
41 |
- cobraadaptor.SetupRootCommand(cmd, dockerCli) |
|
41 |
+ cobraadaptor.SetupRootCommand(cmd) |
|
42 | 42 |
|
43 | 43 |
flags := cmd.Flags() |
44 | 44 |
flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit") |
45 | 45 |
flags.StringVar(&opts.ConfigDir, "config", cliconfig.ConfigDir(), "Location of client config files") |
46 | 46 |
opts.Common.InstallFlags(flags) |
47 | 47 |
|
48 |
+ cmd.SetOutput(dockerCli.Out()) |
|
49 |
+ cmd.AddCommand( |
|
50 |
+ newDaemonCommand(), |
|
51 |
+ node.NewNodeCommand(dockerCli), |
|
52 |
+ service.NewServiceCommand(dockerCli), |
|
53 |
+ stack.NewStackCommand(dockerCli), |
|
54 |
+ stack.NewTopLevelDeployCommand(dockerCli), |
|
55 |
+ swarm.NewSwarmCommand(dockerCli), |
|
56 |
+ container.NewAttachCommand(dockerCli), |
|
57 |
+ container.NewCommitCommand(dockerCli), |
|
58 |
+ container.NewCopyCommand(dockerCli), |
|
59 |
+ container.NewCreateCommand(dockerCli), |
|
60 |
+ container.NewDiffCommand(dockerCli), |
|
61 |
+ container.NewExecCommand(dockerCli), |
|
62 |
+ container.NewExportCommand(dockerCli), |
|
63 |
+ container.NewKillCommand(dockerCli), |
|
64 |
+ container.NewLogsCommand(dockerCli), |
|
65 |
+ container.NewPauseCommand(dockerCli), |
|
66 |
+ container.NewPortCommand(dockerCli), |
|
67 |
+ container.NewPsCommand(dockerCli), |
|
68 |
+ container.NewRenameCommand(dockerCli), |
|
69 |
+ container.NewRestartCommand(dockerCli), |
|
70 |
+ container.NewRmCommand(dockerCli), |
|
71 |
+ container.NewRunCommand(dockerCli), |
|
72 |
+ container.NewStartCommand(dockerCli), |
|
73 |
+ container.NewStatsCommand(dockerCli), |
|
74 |
+ container.NewStopCommand(dockerCli), |
|
75 |
+ container.NewTopCommand(dockerCli), |
|
76 |
+ container.NewUnpauseCommand(dockerCli), |
|
77 |
+ container.NewUpdateCommand(dockerCli), |
|
78 |
+ container.NewWaitCommand(dockerCli), |
|
79 |
+ image.NewBuildCommand(dockerCli), |
|
80 |
+ image.NewHistoryCommand(dockerCli), |
|
81 |
+ image.NewImagesCommand(dockerCli), |
|
82 |
+ image.NewLoadCommand(dockerCli), |
|
83 |
+ image.NewRemoveCommand(dockerCli), |
|
84 |
+ image.NewSaveCommand(dockerCli), |
|
85 |
+ image.NewPullCommand(dockerCli), |
|
86 |
+ image.NewPushCommand(dockerCli), |
|
87 |
+ image.NewSearchCommand(dockerCli), |
|
88 |
+ image.NewImportCommand(dockerCli), |
|
89 |
+ image.NewTagCommand(dockerCli), |
|
90 |
+ network.NewNetworkCommand(dockerCli), |
|
91 |
+ system.NewEventsCommand(dockerCli), |
|
92 |
+ system.NewInspectCommand(dockerCli), |
|
93 |
+ registry.NewLoginCommand(dockerCli), |
|
94 |
+ registry.NewLogoutCommand(dockerCli), |
|
95 |
+ system.NewVersionCommand(dockerCli), |
|
96 |
+ volume.NewVolumeCommand(dockerCli), |
|
97 |
+ system.NewInfoCommand(dockerCli), |
|
98 |
+ ) |
|
99 |
+ plugin.NewPluginCommand(cmd, dockerCli) |
|
100 |
+ |
|
48 | 101 |
return cmd |
49 | 102 |
} |
50 | 103 |
|
... | ... |
@@ -53,9 +118,8 @@ func main() { |
53 | 53 |
stdin, stdout, stderr := term.StdStreams() |
54 | 54 |
logrus.SetOutput(stderr) |
55 | 55 |
|
56 |
- opts := cliflags.NewClientOptions() |
|
57 |
- dockerCli := client.NewDockerCli(stdin, stdout, stderr, opts) |
|
58 |
- cmd := newDockerCommand(dockerCli, opts) |
|
56 |
+ dockerCli := client.NewDockerCli(stdin, stdout, stderr) |
|
57 |
+ cmd := newDockerCommand(dockerCli) |
|
59 | 58 |
|
60 | 59 |
if err := cmd.Execute(); err != nil { |
61 | 60 |
if sterr, ok := err.(cli.StatusError); ok { |
... | ... |
@@ -86,17 +150,10 @@ func dockerPreRun(flags *pflag.FlagSet, opts *cliflags.ClientOptions) { |
86 | 86 |
opts.Common.SetDefaultOptions(flags) |
87 | 87 |
cliflags.SetDaemonLogLevel(opts.Common.LogLevel) |
88 | 88 |
|
89 |
- // TODO: remove this, set a default in New, and pass it in opts |
|
90 | 89 |
if opts.ConfigDir != "" { |
91 | 90 |
cliconfig.SetConfigDir(opts.ConfigDir) |
92 | 91 |
} |
93 | 92 |
|
94 |
- if opts.Common.TrustKey == "" { |
|
95 |
- opts.Common.TrustKey = filepath.Join( |
|
96 |
- cliconfig.ConfigDir(), |
|
97 |
- cliflags.DefaultTrustKeyFile) |
|
98 |
- } |
|
99 |
- |
|
100 | 93 |
if opts.Common.Debug { |
101 | 94 |
utils.EnableDebug() |
102 | 95 |
} |
... | ... |
@@ -8,16 +8,14 @@ import ( |
8 | 8 |
"github.com/docker/docker/utils" |
9 | 9 |
|
10 | 10 |
"github.com/docker/docker/api/client" |
11 |
- cliflags "github.com/docker/docker/cli/flags" |
|
12 | 11 |
) |
13 | 12 |
|
14 | 13 |
func TestClientDebugEnabled(t *testing.T) { |
15 | 14 |
defer utils.DisableDebug() |
16 | 15 |
|
17 |
- opts := cliflags.NewClientOptions() |
|
18 |
- cmd := newDockerCommand(&client.DockerCli{}, opts) |
|
16 |
+ cmd := newDockerCommand(&client.DockerCli{}) |
|
17 |
+ cmd.Flags().Set("debug", "true") |
|
19 | 18 |
|
20 |
- opts.Common.Debug = true |
|
21 | 19 |
if err := cmd.PersistentPreRunE(cmd, []string{}); err != nil { |
22 | 20 |
t.Fatalf("Unexpected error: %s", err.Error()) |
23 | 21 |
} |
... | ... |
@@ -1,290 +1,145 @@ |
1 | 1 |
package main |
2 | 2 |
|
3 | 3 |
import ( |
4 |
- "io/ioutil" |
|
5 |
- "os" |
|
6 |
- "strings" |
|
7 | 4 |
"testing" |
8 | 5 |
|
9 | 6 |
"github.com/Sirupsen/logrus" |
10 | 7 |
cliflags "github.com/docker/docker/cli/flags" |
11 | 8 |
"github.com/docker/docker/daemon" |
12 |
- "github.com/docker/docker/opts" |
|
13 |
- "github.com/docker/docker/pkg/mflag" |
|
14 |
- "github.com/docker/go-connections/tlsconfig" |
|
9 |
+ "github.com/docker/docker/pkg/testutil/assert" |
|
10 |
+ "github.com/docker/docker/pkg/testutil/tempfile" |
|
11 |
+ "github.com/spf13/pflag" |
|
15 | 12 |
) |
16 | 13 |
|
14 |
+func defaultOptions(configFile string) daemonOptions { |
|
15 |
+ opts := daemonOptions{ |
|
16 |
+ daemonConfig: &daemon.Config{}, |
|
17 |
+ flags: &pflag.FlagSet{}, |
|
18 |
+ common: cliflags.NewCommonOptions(), |
|
19 |
+ } |
|
20 |
+ opts.common.InstallFlags(opts.flags) |
|
21 |
+ opts.daemonConfig.InstallFlags(opts.flags) |
|
22 |
+ opts.flags.StringVar(&opts.configFile, flagDaemonConfigFile, defaultDaemonConfigFile, "") |
|
23 |
+ opts.configFile = configFile |
|
24 |
+ return opts |
|
25 |
+} |
|
26 |
+ |
|
17 | 27 |
func TestLoadDaemonCliConfigWithoutOverriding(t *testing.T) { |
18 |
- c := &daemon.Config{} |
|
19 |
- common := &cliflags.CommonFlags{ |
|
20 |
- Debug: true, |
|
21 |
- } |
|
28 |
+ opts := defaultOptions("") |
|
29 |
+ opts.common.Debug = true |
|
22 | 30 |
|
23 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
24 |
- loadedConfig, err := loadDaemonCliConfig(c, flags, common, "/tmp/fooobarbaz") |
|
25 |
- if err != nil { |
|
26 |
- t.Fatal(err) |
|
27 |
- } |
|
28 |
- if loadedConfig == nil { |
|
29 |
- t.Fatalf("expected configuration %v, got nil", c) |
|
30 |
- } |
|
31 |
+ loadedConfig, err := loadDaemonCliConfig(opts) |
|
32 |
+ assert.NilError(t, err) |
|
33 |
+ assert.NotNil(t, loadedConfig) |
|
31 | 34 |
if !loadedConfig.Debug { |
32 | 35 |
t.Fatalf("expected debug to be copied from the common flags, got false") |
33 | 36 |
} |
34 | 37 |
} |
35 | 38 |
|
36 | 39 |
func TestLoadDaemonCliConfigWithTLS(t *testing.T) { |
37 |
- c := &daemon.Config{} |
|
38 |
- common := &cliflags.CommonFlags{ |
|
39 |
- TLS: true, |
|
40 |
- TLSOptions: &tlsconfig.Options{ |
|
41 |
- CAFile: "/tmp/ca.pem", |
|
42 |
- }, |
|
43 |
- } |
|
44 |
- |
|
45 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
46 |
- loadedConfig, err := loadDaemonCliConfig(c, flags, common, "/tmp/fooobarbaz") |
|
47 |
- if err != nil { |
|
48 |
- t.Fatal(err) |
|
49 |
- } |
|
50 |
- if loadedConfig == nil { |
|
51 |
- t.Fatalf("expected configuration %v, got nil", c) |
|
52 |
- } |
|
53 |
- if loadedConfig.CommonTLSOptions.CAFile != "/tmp/ca.pem" { |
|
54 |
- t.Fatalf("expected /tmp/ca.pem, got %s: %q", loadedConfig.CommonTLSOptions.CAFile, loadedConfig) |
|
55 |
- } |
|
40 |
+ opts := defaultOptions("") |
|
41 |
+ opts.common.TLSOptions.CAFile = "/tmp/ca.pem" |
|
42 |
+ opts.common.TLS = true |
|
43 |
+ |
|
44 |
+ loadedConfig, err := loadDaemonCliConfig(opts) |
|
45 |
+ assert.NilError(t, err) |
|
46 |
+ assert.NotNil(t, loadedConfig) |
|
47 |
+ assert.Equal(t, loadedConfig.CommonTLSOptions.CAFile, "/tmp/ca.pem") |
|
56 | 48 |
} |
57 | 49 |
|
58 | 50 |
func TestLoadDaemonCliConfigWithConflicts(t *testing.T) { |
59 |
- c := &daemon.Config{} |
|
60 |
- common := &cliflags.CommonFlags{} |
|
61 |
- f, err := ioutil.TempFile("", "docker-config-") |
|
62 |
- if err != nil { |
|
63 |
- t.Fatal(err) |
|
64 |
- } |
|
65 |
- configFile := f.Name() |
|
66 |
- defer os.Remove(configFile) |
|
67 |
- |
|
68 |
- f.Write([]byte(`{"labels": ["l3=foo"]}`)) |
|
69 |
- f.Close() |
|
70 |
- |
|
71 |
- var labels []string |
|
51 |
+ tempFile := tempfile.NewTempFile(t, "config", `{"labels": ["l3=foo"]}`) |
|
52 |
+ defer tempFile.Remove() |
|
53 |
+ configFile := tempFile.Name() |
|
72 | 54 |
|
73 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
74 |
- flags.String([]string{daemonConfigFileFlag}, "", "") |
|
75 |
- flags.Var(opts.NewNamedListOptsRef("labels", &labels, opts.ValidateLabel), []string{"-label"}, "") |
|
55 |
+ opts := defaultOptions(configFile) |
|
56 |
+ flags := opts.flags |
|
76 | 57 |
|
77 |
- flags.Set(daemonConfigFileFlag, configFile) |
|
78 |
- if err := flags.Set("-label", "l1=bar"); err != nil { |
|
79 |
- t.Fatal(err) |
|
80 |
- } |
|
81 |
- if err := flags.Set("-label", "l2=baz"); err != nil { |
|
82 |
- t.Fatal(err) |
|
83 |
- } |
|
58 |
+ assert.NilError(t, flags.Set(flagDaemonConfigFile, configFile)) |
|
59 |
+ assert.NilError(t, flags.Set("label", "l1=bar")) |
|
60 |
+ assert.NilError(t, flags.Set("label", "l2=baz")) |
|
84 | 61 |
|
85 |
- _, err = loadDaemonCliConfig(c, flags, common, configFile) |
|
86 |
- if err == nil { |
|
87 |
- t.Fatalf("expected configuration error, got nil") |
|
88 |
- } |
|
89 |
- if !strings.Contains(err.Error(), "labels") { |
|
90 |
- t.Fatalf("expected labels conflict, got %v", err) |
|
91 |
- } |
|
62 |
+ _, err := loadDaemonCliConfig(opts) |
|
63 |
+ assert.Error(t, err, "as a flag and in the configuration file: labels") |
|
92 | 64 |
} |
93 | 65 |
|
94 | 66 |
func TestLoadDaemonCliConfigWithTLSVerify(t *testing.T) { |
95 |
- c := &daemon.Config{} |
|
96 |
- common := &cliflags.CommonFlags{ |
|
97 |
- TLSOptions: &tlsconfig.Options{ |
|
98 |
- CAFile: "/tmp/ca.pem", |
|
99 |
- }, |
|
100 |
- } |
|
101 |
- |
|
102 |
- f, err := ioutil.TempFile("", "docker-config-") |
|
103 |
- if err != nil { |
|
104 |
- t.Fatal(err) |
|
105 |
- } |
|
106 |
- configFile := f.Name() |
|
107 |
- defer os.Remove(configFile) |
|
108 |
- |
|
109 |
- f.Write([]byte(`{"tlsverify": true}`)) |
|
110 |
- f.Close() |
|
67 |
+ tempFile := tempfile.NewTempFile(t, "config", `{"tlsverify": true}`) |
|
68 |
+ defer tempFile.Remove() |
|
111 | 69 |
|
112 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
113 |
- flags.Bool([]string{"-tlsverify"}, false, "") |
|
114 |
- loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile) |
|
115 |
- if err != nil { |
|
116 |
- t.Fatal(err) |
|
117 |
- } |
|
118 |
- if loadedConfig == nil { |
|
119 |
- t.Fatalf("expected configuration %v, got nil", c) |
|
120 |
- } |
|
70 |
+ opts := defaultOptions(tempFile.Name()) |
|
71 |
+ opts.common.TLSOptions.CAFile = "/tmp/ca.pem" |
|
121 | 72 |
|
122 |
- if !loadedConfig.TLS { |
|
123 |
- t.Fatalf("expected TLS enabled, got %q", loadedConfig) |
|
124 |
- } |
|
73 |
+ loadedConfig, err := loadDaemonCliConfig(opts) |
|
74 |
+ assert.NilError(t, err) |
|
75 |
+ assert.NotNil(t, loadedConfig) |
|
76 |
+ assert.Equal(t, loadedConfig.TLS, true) |
|
125 | 77 |
} |
126 | 78 |
|
127 | 79 |
func TestLoadDaemonCliConfigWithExplicitTLSVerifyFalse(t *testing.T) { |
128 |
- c := &daemon.Config{} |
|
129 |
- common := &cliflags.CommonFlags{ |
|
130 |
- TLSOptions: &tlsconfig.Options{ |
|
131 |
- CAFile: "/tmp/ca.pem", |
|
132 |
- }, |
|
133 |
- } |
|
80 |
+ tempFile := tempfile.NewTempFile(t, "config", `{"tlsverify": false}`) |
|
81 |
+ defer tempFile.Remove() |
|
134 | 82 |
|
135 |
- f, err := ioutil.TempFile("", "docker-config-") |
|
136 |
- if err != nil { |
|
137 |
- t.Fatal(err) |
|
138 |
- } |
|
139 |
- configFile := f.Name() |
|
140 |
- defer os.Remove(configFile) |
|
141 |
- |
|
142 |
- f.Write([]byte(`{"tlsverify": false}`)) |
|
143 |
- f.Close() |
|
144 |
- |
|
145 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
146 |
- flags.Bool([]string{"-tlsverify"}, false, "") |
|
147 |
- loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile) |
|
148 |
- if err != nil { |
|
149 |
- t.Fatal(err) |
|
150 |
- } |
|
151 |
- if loadedConfig == nil { |
|
152 |
- t.Fatalf("expected configuration %v, got nil", c) |
|
153 |
- } |
|
83 |
+ opts := defaultOptions(tempFile.Name()) |
|
84 |
+ opts.common.TLSOptions.CAFile = "/tmp/ca.pem" |
|
154 | 85 |
|
155 |
- if !loadedConfig.TLS { |
|
156 |
- t.Fatalf("expected TLS enabled, got %q", loadedConfig) |
|
157 |
- } |
|
86 |
+ loadedConfig, err := loadDaemonCliConfig(opts) |
|
87 |
+ assert.NilError(t, err) |
|
88 |
+ assert.NotNil(t, loadedConfig) |
|
89 |
+ assert.Equal(t, loadedConfig.TLS, true) |
|
158 | 90 |
} |
159 | 91 |
|
160 | 92 |
func TestLoadDaemonCliConfigWithoutTLSVerify(t *testing.T) { |
161 |
- c := &daemon.Config{} |
|
162 |
- common := &cliflags.CommonFlags{ |
|
163 |
- TLSOptions: &tlsconfig.Options{ |
|
164 |
- CAFile: "/tmp/ca.pem", |
|
165 |
- }, |
|
166 |
- } |
|
167 |
- |
|
168 |
- f, err := ioutil.TempFile("", "docker-config-") |
|
169 |
- if err != nil { |
|
170 |
- t.Fatal(err) |
|
171 |
- } |
|
172 |
- configFile := f.Name() |
|
173 |
- defer os.Remove(configFile) |
|
93 |
+ tempFile := tempfile.NewTempFile(t, "config", `{}`) |
|
94 |
+ defer tempFile.Remove() |
|
174 | 95 |
|
175 |
- f.Write([]byte(`{}`)) |
|
176 |
- f.Close() |
|
96 |
+ opts := defaultOptions(tempFile.Name()) |
|
97 |
+ opts.common.TLSOptions.CAFile = "/tmp/ca.pem" |
|
177 | 98 |
|
178 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
179 |
- loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile) |
|
180 |
- if err != nil { |
|
181 |
- t.Fatal(err) |
|
182 |
- } |
|
183 |
- if loadedConfig == nil { |
|
184 |
- t.Fatalf("expected configuration %v, got nil", c) |
|
185 |
- } |
|
186 |
- |
|
187 |
- if loadedConfig.TLS { |
|
188 |
- t.Fatalf("expected TLS disabled, got %q", loadedConfig) |
|
189 |
- } |
|
99 |
+ loadedConfig, err := loadDaemonCliConfig(opts) |
|
100 |
+ assert.NilError(t, err) |
|
101 |
+ assert.NotNil(t, loadedConfig) |
|
102 |
+ assert.Equal(t, loadedConfig.TLS, false) |
|
190 | 103 |
} |
191 | 104 |
|
192 | 105 |
func TestLoadDaemonCliConfigWithLogLevel(t *testing.T) { |
193 |
- c := &daemon.Config{} |
|
194 |
- common := &cliflags.CommonFlags{} |
|
195 |
- |
|
196 |
- f, err := ioutil.TempFile("", "docker-config-") |
|
197 |
- if err != nil { |
|
198 |
- t.Fatal(err) |
|
199 |
- } |
|
200 |
- configFile := f.Name() |
|
201 |
- defer os.Remove(configFile) |
|
202 |
- |
|
203 |
- f.Write([]byte(`{"log-level": "warn"}`)) |
|
204 |
- f.Close() |
|
205 |
- |
|
206 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
207 |
- flags.String([]string{"-log-level"}, "", "") |
|
208 |
- loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile) |
|
209 |
- if err != nil { |
|
210 |
- t.Fatal(err) |
|
211 |
- } |
|
212 |
- if loadedConfig == nil { |
|
213 |
- t.Fatalf("expected configuration %v, got nil", c) |
|
214 |
- } |
|
215 |
- if loadedConfig.LogLevel != "warn" { |
|
216 |
- t.Fatalf("expected warn log level, got %v", loadedConfig.LogLevel) |
|
217 |
- } |
|
218 |
- |
|
219 |
- if logrus.GetLevel() != logrus.WarnLevel { |
|
220 |
- t.Fatalf("expected warn log level, got %v", logrus.GetLevel()) |
|
221 |
- } |
|
106 |
+ tempFile := tempfile.NewTempFile(t, "config", `{"log-level": "warn"}`) |
|
107 |
+ defer tempFile.Remove() |
|
108 |
+ |
|
109 |
+ opts := defaultOptions(tempFile.Name()) |
|
110 |
+ loadedConfig, err := loadDaemonCliConfig(opts) |
|
111 |
+ assert.NilError(t, err) |
|
112 |
+ assert.NotNil(t, loadedConfig) |
|
113 |
+ assert.Equal(t, loadedConfig.LogLevel, "warn") |
|
114 |
+ assert.Equal(t, logrus.GetLevel(), logrus.WarnLevel) |
|
222 | 115 |
} |
223 | 116 |
|
224 | 117 |
func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) { |
225 |
- c := &daemon.Config{} |
|
226 |
- common := &cliflags.CommonFlags{} |
|
227 |
- |
|
228 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
229 |
- flags.String([]string{"-tlscacert"}, "", "") |
|
230 |
- flags.String([]string{"-log-driver"}, "", "") |
|
231 |
- |
|
232 |
- f, err := ioutil.TempFile("", "docker-config-") |
|
233 |
- if err != nil { |
|
234 |
- t.Fatal(err) |
|
235 |
- } |
|
236 |
- configFile := f.Name() |
|
237 |
- defer os.Remove(configFile) |
|
238 |
- |
|
239 |
- f.Write([]byte(`{"tlscacert": "/etc/certs/ca.pem", "log-driver": "syslog"}`)) |
|
240 |
- f.Close() |
|
241 |
- |
|
242 |
- loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile) |
|
243 |
- if err != nil { |
|
244 |
- t.Fatal(err) |
|
245 |
- } |
|
246 |
- if loadedConfig == nil { |
|
247 |
- t.Fatal("expected configuration, got nil") |
|
248 |
- } |
|
249 |
- if loadedConfig.CommonTLSOptions.CAFile != "/etc/certs/ca.pem" { |
|
250 |
- t.Fatalf("expected CA file path /etc/certs/ca.pem, got %v", loadedConfig.CommonTLSOptions.CAFile) |
|
251 |
- } |
|
252 |
- if loadedConfig.LogConfig.Type != "syslog" { |
|
253 |
- t.Fatalf("expected LogConfig type syslog, got %v", loadedConfig.LogConfig.Type) |
|
254 |
- } |
|
118 |
+ content := `{"tlscacert": "/etc/certs/ca.pem", "log-driver": "syslog"}` |
|
119 |
+ tempFile := tempfile.NewTempFile(t, "config", content) |
|
120 |
+ defer tempFile.Remove() |
|
121 |
+ |
|
122 |
+ opts := defaultOptions(tempFile.Name()) |
|
123 |
+ loadedConfig, err := loadDaemonCliConfig(opts) |
|
124 |
+ assert.NilError(t, err) |
|
125 |
+ assert.NotNil(t, loadedConfig) |
|
126 |
+ assert.Equal(t, loadedConfig.CommonTLSOptions.CAFile, "/etc/certs/ca.pem") |
|
127 |
+ assert.Equal(t, loadedConfig.LogConfig.Type, "syslog") |
|
255 | 128 |
} |
256 | 129 |
|
257 | 130 |
func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) { |
258 |
- c := &daemon.Config{} |
|
259 |
- common := &cliflags.CommonFlags{} |
|
260 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
261 |
- c.ServiceOptions.InstallCliFlags(flags, absentFromHelp) |
|
262 |
- |
|
263 |
- f, err := ioutil.TempFile("", "docker-config-") |
|
264 |
- if err != nil { |
|
265 |
- t.Fatal(err) |
|
266 |
- } |
|
267 |
- configFile := f.Name() |
|
268 |
- defer os.Remove(configFile) |
|
269 |
- |
|
270 |
- f.Write([]byte(`{"registry-mirrors": ["https://mirrors.docker.com"], "insecure-registries": ["https://insecure.docker.com"]}`)) |
|
271 |
- f.Close() |
|
272 |
- |
|
273 |
- loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile) |
|
274 |
- if err != nil { |
|
275 |
- t.Fatal(err) |
|
276 |
- } |
|
277 |
- if loadedConfig == nil { |
|
278 |
- t.Fatal("expected configuration, got nil") |
|
279 |
- } |
|
280 |
- |
|
281 |
- m := loadedConfig.Mirrors |
|
282 |
- if len(m) != 1 { |
|
283 |
- t.Fatalf("expected 1 mirror, got %d", len(m)) |
|
284 |
- } |
|
285 |
- |
|
286 |
- r := loadedConfig.InsecureRegistries |
|
287 |
- if len(r) != 1 { |
|
288 |
- t.Fatalf("expected 1 insecure registries, got %d", len(r)) |
|
289 |
- } |
|
131 |
+ content := `{ |
|
132 |
+ "registry-mirrors": ["https://mirrors.docker.com"], |
|
133 |
+ "insecure-registries": ["https://insecure.docker.com"], |
|
134 |
+ }` |
|
135 |
+ tempFile := tempfile.NewTempFile(t, "config", content) |
|
136 |
+ defer tempFile.Remove() |
|
137 |
+ |
|
138 |
+ opts := defaultOptions(tempFile.Name()) |
|
139 |
+ loadedConfig, err := loadDaemonCliConfig(opts) |
|
140 |
+ assert.NilError(t, err) |
|
141 |
+ assert.NotNil(t, loadedConfig) |
|
142 |
+ |
|
143 |
+ assert.Equal(t, len(loadedConfig.Mirrors), 1) |
|
144 |
+ assert.Equal(t, len(loadedConfig.InsecureRegistries), 1) |
|
290 | 145 |
} |
... | ... |
@@ -7,209 +7,98 @@ import ( |
7 | 7 |
"os" |
8 | 8 |
"testing" |
9 | 9 |
|
10 |
- cliflags "github.com/docker/docker/cli/flags" |
|
11 | 10 |
"github.com/docker/docker/daemon" |
12 |
- "github.com/docker/docker/opts" |
|
13 |
- "github.com/docker/docker/pkg/mflag" |
|
11 |
+ "github.com/docker/docker/pkg/testutil/assert" |
|
12 |
+ "github.com/docker/docker/pkg/testutil/tempfile" |
|
14 | 13 |
) |
15 | 14 |
|
16 | 15 |
func TestLoadDaemonCliConfigWithDaemonFlags(t *testing.T) { |
17 |
- c := &daemon.Config{} |
|
18 |
- common := &cliflags.CommonFlags{ |
|
19 |
- Debug: true, |
|
20 |
- LogLevel: "info", |
|
21 |
- } |
|
22 |
- |
|
23 |
- f, err := ioutil.TempFile("", "docker-config-") |
|
24 |
- if err != nil { |
|
25 |
- t.Fatal(err) |
|
26 |
- } |
|
27 |
- |
|
28 |
- configFile := f.Name() |
|
29 |
- f.Write([]byte(`{"log-opts": {"max-size": "1k"}}`)) |
|
30 |
- f.Close() |
|
31 |
- |
|
32 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
33 |
- flags.String([]string{daemonConfigFileFlag}, "", "") |
|
34 |
- flags.BoolVar(&c.EnableSelinuxSupport, []string{"-selinux-enabled"}, true, "") |
|
35 |
- flags.StringVar(&c.LogConfig.Type, []string{"-log-driver"}, "json-file", "") |
|
36 |
- flags.Var(opts.NewNamedMapOpts("log-opts", c.LogConfig.Config, nil), []string{"-log-opt"}, "") |
|
37 |
- flags.Set(daemonConfigFileFlag, configFile) |
|
38 |
- |
|
39 |
- loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile) |
|
40 |
- if err != nil { |
|
41 |
- t.Fatal(err) |
|
42 |
- } |
|
43 |
- if loadedConfig == nil { |
|
44 |
- t.Fatalf("expected configuration %v, got nil", c) |
|
45 |
- } |
|
46 |
- if !loadedConfig.Debug { |
|
47 |
- t.Fatalf("expected debug mode, got false") |
|
48 |
- } |
|
49 |
- if loadedConfig.LogLevel != "info" { |
|
50 |
- t.Fatalf("expected info log level, got %v", loadedConfig.LogLevel) |
|
51 |
- } |
|
52 |
- if !loadedConfig.EnableSelinuxSupport { |
|
53 |
- t.Fatalf("expected enabled selinux support, got disabled") |
|
54 |
- } |
|
55 |
- if loadedConfig.LogConfig.Type != "json-file" { |
|
56 |
- t.Fatalf("expected LogConfig type json-file, got %v", loadedConfig.LogConfig.Type) |
|
57 |
- } |
|
58 |
- if maxSize := loadedConfig.LogConfig.Config["max-size"]; maxSize != "1k" { |
|
59 |
- t.Fatalf("expected log max-size `1k`, got %s", maxSize) |
|
60 |
- } |
|
16 |
+ content := `{"log-opts": {"max-size": "1k"}}` |
|
17 |
+ tempFile := tempfile.NewTempFile(t, "config", content) |
|
18 |
+ defer tempFile.Remove() |
|
19 |
+ |
|
20 |
+ opts := defaultOptions(tempFile.Name()) |
|
21 |
+ opts.common.Debug = true |
|
22 |
+ opts.common.LogLevel = "info" |
|
23 |
+ assert.NilError(t, opts.flags.Set("selinux-enabled", "true")) |
|
24 |
+ |
|
25 |
+ loadedConfig, err := loadDaemonCliConfig(opts) |
|
26 |
+ assert.NilError(t, err) |
|
27 |
+ assert.NotNil(t, loadedConfig) |
|
28 |
+ |
|
29 |
+ assert.Equal(t, loadedConfig.Debug, true) |
|
30 |
+ assert.Equal(t, loadedConfig.LogLevel, "info") |
|
31 |
+ assert.Equal(t, loadedConfig.EnableSelinuxSupport, true) |
|
32 |
+ assert.Equal(t, loadedConfig.LogConfig.Type, "json-file") |
|
33 |
+ assert.Equal(t, loadedConfig.LogConfig.Config["max-size"], "1k") |
|
61 | 34 |
} |
62 | 35 |
|
63 | 36 |
func TestLoadDaemonConfigWithNetwork(t *testing.T) { |
64 |
- c := &daemon.Config{} |
|
65 |
- common := &cliflags.CommonFlags{} |
|
66 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
67 |
- flags.String([]string{"-bip"}, "", "") |
|
68 |
- flags.String([]string{"-ip"}, "", "") |
|
69 |
- |
|
70 |
- f, err := ioutil.TempFile("", "docker-config-") |
|
71 |
- if err != nil { |
|
72 |
- t.Fatal(err) |
|
73 |
- } |
|
37 |
+ content := `{"bip": "127.0.0.2", "ip": "127.0.0.1"}` |
|
38 |
+ tempFile := tempfile.NewTempFile(t, "config", content) |
|
39 |
+ defer tempFile.Remove() |
|
74 | 40 |
|
75 |
- configFile := f.Name() |
|
76 |
- f.Write([]byte(`{"bip": "127.0.0.2", "ip": "127.0.0.1"}`)) |
|
77 |
- f.Close() |
|
41 |
+ opts := defaultOptions(tempFile.Name()) |
|
42 |
+ loadedConfig, err := loadDaemonCliConfig(opts) |
|
43 |
+ assert.NilError(t, err) |
|
44 |
+ assert.NotNil(t, loadedConfig) |
|
78 | 45 |
|
79 |
- loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile) |
|
80 |
- if err != nil { |
|
81 |
- t.Fatal(err) |
|
82 |
- } |
|
83 |
- if loadedConfig == nil { |
|
84 |
- t.Fatalf("expected configuration %v, got nil", c) |
|
85 |
- } |
|
86 |
- if loadedConfig.IP != "127.0.0.2" { |
|
87 |
- t.Fatalf("expected IP 127.0.0.2, got %v", loadedConfig.IP) |
|
88 |
- } |
|
89 |
- if loadedConfig.DefaultIP.String() != "127.0.0.1" { |
|
90 |
- t.Fatalf("expected DefaultIP 127.0.0.1, got %s", loadedConfig.DefaultIP) |
|
91 |
- } |
|
46 |
+ assert.Equal(t, loadedConfig.IP, "127.0.0.2") |
|
47 |
+ assert.Equal(t, loadedConfig.DefaultIP.String(), "127.0.0.1") |
|
92 | 48 |
} |
93 | 49 |
|
94 | 50 |
func TestLoadDaemonConfigWithMapOptions(t *testing.T) { |
95 |
- c := &daemon.Config{} |
|
96 |
- common := &cliflags.CommonFlags{} |
|
97 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
98 |
- |
|
99 |
- flags.Var(opts.NewNamedMapOpts("cluster-store-opts", c.ClusterOpts, nil), []string{"-cluster-store-opt"}, "") |
|
100 |
- flags.Var(opts.NewNamedMapOpts("log-opts", c.LogConfig.Config, nil), []string{"-log-opt"}, "") |
|
101 |
- |
|
102 |
- f, err := ioutil.TempFile("", "docker-config-") |
|
103 |
- if err != nil { |
|
104 |
- t.Fatal(err) |
|
105 |
- } |
|
106 |
- |
|
107 |
- configFile := f.Name() |
|
108 |
- f.Write([]byte(`{ |
|
51 |
+ content := `{ |
|
109 | 52 |
"cluster-store-opts": {"kv.cacertfile": "/var/lib/docker/discovery_certs/ca.pem"}, |
110 | 53 |
"log-opts": {"tag": "test"} |
111 |
-}`)) |
|
112 |
- f.Close() |
|
54 |
+}` |
|
55 |
+ tempFile := tempfile.NewTempFile(t, "config", content) |
|
56 |
+ defer tempFile.Remove() |
|
113 | 57 |
|
114 |
- loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile) |
|
115 |
- if err != nil { |
|
116 |
- t.Fatal(err) |
|
117 |
- } |
|
118 |
- if loadedConfig == nil { |
|
119 |
- t.Fatal("expected configuration, got nil") |
|
120 |
- } |
|
121 |
- if loadedConfig.ClusterOpts == nil { |
|
122 |
- t.Fatal("expected cluster options, got nil") |
|
123 |
- } |
|
58 |
+ opts := defaultOptions(tempFile.Name()) |
|
59 |
+ loadedConfig, err := loadDaemonCliConfig(opts) |
|
60 |
+ assert.NilError(t, err) |
|
61 |
+ assert.NotNil(t, loadedConfig) |
|
62 |
+ assert.NotNil(t, loadedConfig.ClusterOpts) |
|
124 | 63 |
|
125 | 64 |
expectedPath := "/var/lib/docker/discovery_certs/ca.pem" |
126 |
- if caPath := loadedConfig.ClusterOpts["kv.cacertfile"]; caPath != expectedPath { |
|
127 |
- t.Fatalf("expected %s, got %s", expectedPath, caPath) |
|
128 |
- } |
|
129 |
- |
|
130 |
- if loadedConfig.LogConfig.Config == nil { |
|
131 |
- t.Fatal("expected log config options, got nil") |
|
132 |
- } |
|
133 |
- if tag := loadedConfig.LogConfig.Config["tag"]; tag != "test" { |
|
134 |
- t.Fatalf("expected log tag `test`, got %s", tag) |
|
135 |
- } |
|
65 |
+ assert.Equal(t, loadedConfig.ClusterOpts["kv.cacertfile"], expectedPath) |
|
66 |
+ assert.NotNil(t, loadedConfig.LogConfig.Config) |
|
67 |
+ assert.Equal(t, loadedConfig.LogConfig.Config["tag"], "test") |
|
136 | 68 |
} |
137 | 69 |
|
138 | 70 |
func TestLoadDaemonConfigWithTrueDefaultValues(t *testing.T) { |
139 |
- c := &daemon.Config{} |
|
140 |
- common := &cliflags.CommonFlags{} |
|
141 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
142 |
- flags.BoolVar(&c.EnableUserlandProxy, []string{"-userland-proxy"}, true, "") |
|
143 |
- |
|
144 |
- f, err := ioutil.TempFile("", "docker-config-") |
|
145 |
- if err != nil { |
|
146 |
- t.Fatal(err) |
|
147 |
- } |
|
148 |
- |
|
149 |
- if err := flags.ParseFlags([]string{}, false); err != nil { |
|
150 |
- t.Fatal(err) |
|
151 |
- } |
|
71 |
+ content := `{ "userland-proxy": false }` |
|
72 |
+ tempFile := tempfile.NewTempFile(t, "config", content) |
|
73 |
+ defer tempFile.Remove() |
|
152 | 74 |
|
153 |
- configFile := f.Name() |
|
154 |
- f.Write([]byte(`{ |
|
155 |
- "userland-proxy": false |
|
156 |
-}`)) |
|
157 |
- f.Close() |
|
158 |
- |
|
159 |
- loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile) |
|
160 |
- if err != nil { |
|
161 |
- t.Fatal(err) |
|
162 |
- } |
|
163 |
- if loadedConfig == nil { |
|
164 |
- t.Fatal("expected configuration, got nil") |
|
165 |
- } |
|
75 |
+ opts := defaultOptions(tempFile.Name()) |
|
76 |
+ loadedConfig, err := loadDaemonCliConfig(opts) |
|
77 |
+ assert.NilError(t, err) |
|
78 |
+ assert.NotNil(t, loadedConfig) |
|
79 |
+ assert.NotNil(t, loadedConfig.ClusterOpts) |
|
166 | 80 |
|
167 |
- if loadedConfig.EnableUserlandProxy { |
|
168 |
- t.Fatal("expected userland proxy to be disabled, got enabled") |
|
169 |
- } |
|
81 |
+ assert.Equal(t, loadedConfig.EnableUserlandProxy, false) |
|
170 | 82 |
|
171 | 83 |
// make sure reloading doesn't generate configuration |
172 | 84 |
// conflicts after normalizing boolean values. |
173 |
- err = daemon.ReloadConfiguration(configFile, flags, func(reloadedConfig *daemon.Config) { |
|
174 |
- if reloadedConfig.EnableUserlandProxy { |
|
175 |
- t.Fatal("expected userland proxy to be disabled, got enabled") |
|
176 |
- } |
|
177 |
- }) |
|
178 |
- if err != nil { |
|
179 |
- t.Fatal(err) |
|
85 |
+ reload := func(reloadedConfig *daemon.Config) { |
|
86 |
+ assert.Equal(t, reloadedConfig.EnableUserlandProxy, false) |
|
180 | 87 |
} |
88 |
+ assert.NilError(t, daemon.ReloadConfiguration(opts.configFile, opts.flags, reload)) |
|
181 | 89 |
} |
182 | 90 |
|
183 | 91 |
func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) { |
184 |
- c := &daemon.Config{} |
|
185 |
- common := &cliflags.CommonFlags{} |
|
186 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
187 |
- flags.BoolVar(&c.EnableUserlandProxy, []string{"-userland-proxy"}, true, "") |
|
188 |
- |
|
189 |
- f, err := ioutil.TempFile("", "docker-config-") |
|
190 |
- if err != nil { |
|
191 |
- t.Fatal(err) |
|
192 |
- } |
|
92 |
+ tempFile := tempfile.NewTempFile(t, "config", `{}`) |
|
93 |
+ defer tempFile.Remove() |
|
193 | 94 |
|
194 |
- if err := flags.ParseFlags([]string{}, false); err != nil { |
|
195 |
- t.Fatal(err) |
|
196 |
- } |
|
197 |
- |
|
198 |
- configFile := f.Name() |
|
199 |
- f.Write([]byte(`{}`)) |
|
200 |
- f.Close() |
|
201 |
- |
|
202 |
- loadedConfig, err := loadDaemonCliConfig(c, flags, common, configFile) |
|
203 |
- if err != nil { |
|
204 |
- t.Fatal(err) |
|
205 |
- } |
|
206 |
- if loadedConfig == nil { |
|
207 |
- t.Fatal("expected configuration, got nil") |
|
208 |
- } |
|
95 |
+ opts := defaultOptions(tempFile.Name()) |
|
96 |
+ loadedConfig, err := loadDaemonCliConfig(opts) |
|
97 |
+ assert.NilError(t, err) |
|
98 |
+ assert.NotNil(t, loadedConfig) |
|
99 |
+ assert.NotNil(t, loadedConfig.ClusterOpts) |
|
209 | 100 |
|
210 |
- if !loadedConfig.EnableUserlandProxy { |
|
211 |
- t.Fatal("expected userland proxy to be enabled, got disabled") |
|
212 |
- } |
|
101 |
+ assert.Equal(t, loadedConfig.EnableUserlandProxy, true) |
|
213 | 102 |
} |
214 | 103 |
|
215 | 104 |
func TestLoadDaemonConfigWithLegacyRegistryOptions(t *testing.T) { |
... | ... |
@@ -5,6 +5,7 @@ import ( |
5 | 5 |
|
6 | 6 |
"github.com/Sirupsen/logrus" |
7 | 7 |
"github.com/docker/docker/cli" |
8 |
+ "github.com/docker/docker/cli/cobraadaptor" |
|
8 | 9 |
cliflags "github.com/docker/docker/cli/flags" |
9 | 10 |
"github.com/docker/docker/daemon" |
10 | 11 |
"github.com/docker/docker/dockerversion" |
... | ... |
@@ -40,15 +41,14 @@ func newDaemonCommand() *cobra.Command { |
40 | 40 |
return runDaemon(opts) |
41 | 41 |
}, |
42 | 42 |
} |
43 |
- // TODO: SetUsageTemplate, SetHelpTemplate, SetFlagErrorFunc |
|
43 |
+ cobraadaptor.SetupRootCommand(cmd) |
|
44 | 44 |
|
45 | 45 |
flags := cmd.Flags() |
46 |
- flags.BoolP("help", "h", false, "Print usage") |
|
47 |
- flags.MarkShorthandDeprecated("help", "please use --help") |
|
48 | 46 |
flags.BoolVarP(&opts.version, "version", "v", false, "Print version information and quit") |
49 | 47 |
flags.StringVar(&opts.configFile, flagDaemonConfigFile, defaultDaemonConfigFile, "Daemon configuration file") |
50 | 48 |
opts.common.InstallFlags(flags) |
51 | 49 |
opts.daemonConfig.InstallFlags(flags) |
50 |
+ installServiceFlags(flags) |
|
52 | 51 |
|
53 | 52 |
return cmd |
54 | 53 |
} |
... | ... |
@@ -3,6 +3,7 @@ package main |
3 | 3 |
import ( |
4 | 4 |
"bytes" |
5 | 5 |
"errors" |
6 |
+ "flag" |
|
6 | 7 |
"fmt" |
7 | 8 |
"io/ioutil" |
8 | 9 |
"os" |
... | ... |
@@ -11,7 +12,7 @@ import ( |
11 | 11 |
"syscall" |
12 | 12 |
|
13 | 13 |
"github.com/Sirupsen/logrus" |
14 |
- flag "github.com/docker/docker/pkg/mflag" |
|
14 |
+ "github.com/spf13/pflag" |
|
15 | 15 |
"golang.org/x/sys/windows" |
16 | 16 |
"golang.org/x/sys/windows/svc" |
17 | 17 |
"golang.org/x/sys/windows/svc/debug" |
... | ... |
@@ -20,10 +21,10 @@ import ( |
20 | 20 |
) |
21 | 21 |
|
22 | 22 |
var ( |
23 |
- flServiceName = flag.String([]string{"-service-name"}, "docker", "Set the Windows service name") |
|
24 |
- flRegisterService = flag.Bool([]string{"-register-service"}, false, "Register the service and exit") |
|
25 |
- flUnregisterService = flag.Bool([]string{"-unregister-service"}, false, "Unregister the service and exit") |
|
26 |
- flRunService = flag.Bool([]string{"-run-service"}, false, "") |
|
23 |
+ flServiceName *string |
|
24 |
+ flRegisterService *bool |
|
25 |
+ flUnregisterService *bool |
|
26 |
+ flRunService *bool |
|
27 | 27 |
|
28 | 28 |
setStdHandle = syscall.NewLazyDLL("kernel32.dll").NewProc("SetStdHandle") |
29 | 29 |
oldStderr syscall.Handle |
... | ... |
@@ -44,6 +45,13 @@ const ( |
44 | 44 |
eventExtraOffset = 10 // Add this to any event to get a string that supports extended data |
45 | 45 |
) |
46 | 46 |
|
47 |
+func installServiceFlags(flags *pflag.FlagSet) { |
|
48 |
+ flServiceName = flags.String("service-name", "docker", "Set the Windows service name") |
|
49 |
+ flRegisterService = flags.Bool("register-service", false, "Register the service and exit") |
|
50 |
+ flUnregisterService = flags.Bool("unregister-service", false, "Unregister the service and exit") |
|
51 |
+ flRunService = flags.Bool("run-service", false, "") |
|
52 |
+} |
|
53 |
+ |
|
47 | 54 |
type handler struct { |
48 | 55 |
tosvc chan bool |
49 | 56 |
fromsvc chan error |
... | ... |
@@ -158,7 +158,7 @@ func (config *Config) InstallCommonFlags(flags *pflag.FlagSet) { |
158 | 158 |
flags.StringVarP(&config.Pidfile, "pidfile", "p", defaultPidFile, "Path to use for daemon PID file") |
159 | 159 |
flags.StringVarP(&config.Root, "graph", "g", defaultGraph, "Root of the Docker runtime") |
160 | 160 |
flags.BoolVarP(&config.AutoRestart, "restart", "r", true, "--restart on the daemon has been deprecated in favor of --restart policies on docker run") |
161 |
- flags.MarkDeprecated("restart", "Please use a restart policy on ducker run") |
|
161 |
+ flags.MarkDeprecated("restart", "Please use a restart policy on docker run") |
|
162 | 162 |
flags.StringVarP(&config.GraphDriver, "storage-driver", "s", "", "Storage driver to use") |
163 | 163 |
flags.IntVar(&config.Mtu, "mtu", 0, "Set the containers network MTU") |
164 | 164 |
flags.BoolVar(&config.RawLogs, "raw-logs", false, "Full timestamps without ANSI coloring") |
... | ... |
@@ -300,7 +300,7 @@ func getConflictFreeConfiguration(configFile string, flags *pflag.FlagSet) (*Con |
300 | 300 |
// TODO: Rewrite configuration logic to avoid same issue with other nullable values, like numbers. |
301 | 301 |
namedOptions := make(map[string]interface{}) |
302 | 302 |
for key, value := range configSet { |
303 |
- f := flags.Lookup("-" + key) |
|
303 |
+ f := flags.Lookup(key) |
|
304 | 304 |
if f == nil { // ignore named flags that don't match |
305 | 305 |
namedOptions[key] = value |
306 | 306 |
continue |
... | ... |
@@ -354,8 +354,7 @@ func findConfigurationConflicts(config map[string]interface{}, flags *pflag.Flag |
354 | 354 |
// 1. Search keys from the file that we don't recognize as flags. |
355 | 355 |
unknownKeys := make(map[string]interface{}) |
356 | 356 |
for key, value := range config { |
357 |
- flagName := "-" + key |
|
358 |
- if flag := flags.Lookup(flagName); flag == nil { |
|
357 |
+ if flag := flags.Lookup(key); flag == nil { |
|
359 | 358 |
unknownKeys[key] = value |
360 | 359 |
} |
361 | 360 |
} |
... | ... |
@@ -396,8 +395,6 @@ func findConfigurationConflicts(config map[string]interface{}, flags *pflag.Flag |
396 | 396 |
} else { |
397 | 397 |
// search flag name in the json configuration payload |
398 | 398 |
for _, name := range []string{f.Name, f.Shorthand} { |
399 |
- name = strings.TrimLeft(name, "-") |
|
400 |
- |
|
401 | 399 |
if value, ok := config[name]; ok { |
402 | 400 |
conflicts = append(conflicts, printConflict(name, f.Value.String(), value)) |
403 | 401 |
break |
... | ... |
@@ -7,7 +7,8 @@ import ( |
7 | 7 |
"testing" |
8 | 8 |
|
9 | 9 |
"github.com/docker/docker/opts" |
10 |
- "github.com/docker/docker/pkg/mflag" |
|
10 |
+ "github.com/docker/docker/pkg/testutil/assert" |
|
11 |
+ "github.com/spf13/pflag" |
|
11 | 12 |
) |
12 | 13 |
|
13 | 14 |
func TestDaemonConfigurationMerge(t *testing.T) { |
... | ... |
@@ -87,42 +88,26 @@ func TestParseClusterAdvertiseSettings(t *testing.T) { |
87 | 87 |
|
88 | 88 |
func TestFindConfigurationConflicts(t *testing.T) { |
89 | 89 |
config := map[string]interface{}{"authorization-plugins": "foobar"} |
90 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
90 |
+ flags := pflag.NewFlagSet("test", pflag.ContinueOnError) |
|
91 | 91 |
|
92 |
- flags.String([]string{"-authorization-plugins"}, "", "") |
|
93 |
- if err := flags.Set("-authorization-plugins", "asdf"); err != nil { |
|
94 |
- t.Fatal(err) |
|
95 |
- } |
|
92 |
+ flags.String("authorization-plugins", "", "") |
|
93 |
+ assert.NilError(t, flags.Set("authorization-plugins", "asdf")) |
|
96 | 94 |
|
97 |
- err := findConfigurationConflicts(config, flags) |
|
98 |
- if err == nil { |
|
99 |
- t.Fatal("expected error, got nil") |
|
100 |
- } |
|
101 |
- if !strings.Contains(err.Error(), "authorization-plugins: (from flag: asdf, from file: foobar)") { |
|
102 |
- t.Fatalf("expected authorization-plugins conflict, got %v", err) |
|
103 |
- } |
|
95 |
+ assert.Error(t, |
|
96 |
+ findConfigurationConflicts(config, flags), |
|
97 |
+ "authorization-plugins: (from flag: asdf, from file: foobar)") |
|
104 | 98 |
} |
105 | 99 |
|
106 | 100 |
func TestFindConfigurationConflictsWithNamedOptions(t *testing.T) { |
107 | 101 |
config := map[string]interface{}{"hosts": []string{"qwer"}} |
108 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
102 |
+ flags := pflag.NewFlagSet("test", pflag.ContinueOnError) |
|
109 | 103 |
|
110 | 104 |
var hosts []string |
111 |
- flags.Var(opts.NewNamedListOptsRef("hosts", &hosts, opts.ValidateHost), []string{"H", "-host"}, "Daemon socket(s) to connect to") |
|
112 |
- if err := flags.Set("-host", "tcp://127.0.0.1:4444"); err != nil { |
|
113 |
- t.Fatal(err) |
|
114 |
- } |
|
115 |
- if err := flags.Set("H", "unix:///var/run/docker.sock"); err != nil { |
|
116 |
- t.Fatal(err) |
|
117 |
- } |
|
105 |
+ flags.VarP(opts.NewNamedListOptsRef("hosts", &hosts, opts.ValidateHost), "host", "H", "Daemon socket(s) to connect to") |
|
106 |
+ assert.NilError(t, flags.Set("host", "tcp://127.0.0.1:4444")) |
|
107 |
+ assert.NilError(t, flags.Set("host", "unix:///var/run/docker.sock")) |
|
118 | 108 |
|
119 |
- err := findConfigurationConflicts(config, flags) |
|
120 |
- if err == nil { |
|
121 |
- t.Fatal("expected error, got nil") |
|
122 |
- } |
|
123 |
- if !strings.Contains(err.Error(), "hosts") { |
|
124 |
- t.Fatalf("expected hosts conflict, got %v", err) |
|
125 |
- } |
|
109 |
+ assert.Error(t, findConfigurationConflicts(config, flags), "hosts") |
|
126 | 110 |
} |
127 | 111 |
|
128 | 112 |
func TestDaemonConfigurationMergeConflicts(t *testing.T) { |
... | ... |
@@ -135,8 +120,8 @@ func TestDaemonConfigurationMergeConflicts(t *testing.T) { |
135 | 135 |
f.Write([]byte(`{"debug": true}`)) |
136 | 136 |
f.Close() |
137 | 137 |
|
138 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
139 |
- flags.Bool([]string{"debug"}, false, "") |
|
138 |
+ flags := pflag.NewFlagSet("test", pflag.ContinueOnError) |
|
139 |
+ flags.Bool("debug", false, "") |
|
140 | 140 |
flags.Set("debug", "false") |
141 | 141 |
|
142 | 142 |
_, err = MergeDaemonConfigurations(&Config{}, flags, configFile) |
... | ... |
@@ -158,8 +143,8 @@ func TestDaemonConfigurationMergeConflictsWithInnerStructs(t *testing.T) { |
158 | 158 |
f.Write([]byte(`{"tlscacert": "/etc/certificates/ca.pem"}`)) |
159 | 159 |
f.Close() |
160 | 160 |
|
161 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
162 |
- flags.String([]string{"tlscacert"}, "", "") |
|
161 |
+ flags := pflag.NewFlagSet("test", pflag.ContinueOnError) |
|
162 |
+ flags.String("tlscacert", "", "") |
|
163 | 163 |
flags.Set("tlscacert", "~/.docker/ca.pem") |
164 | 164 |
|
165 | 165 |
_, err = MergeDaemonConfigurations(&Config{}, flags, configFile) |
... | ... |
@@ -173,9 +158,9 @@ func TestDaemonConfigurationMergeConflictsWithInnerStructs(t *testing.T) { |
173 | 173 |
|
174 | 174 |
func TestFindConfigurationConflictsWithUnknownKeys(t *testing.T) { |
175 | 175 |
config := map[string]interface{}{"tls-verify": "true"} |
176 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
176 |
+ flags := pflag.NewFlagSet("test", pflag.ContinueOnError) |
|
177 | 177 |
|
178 |
- flags.Bool([]string{"-tlsverify"}, false, "") |
|
178 |
+ flags.Bool("tlsverify", false, "") |
|
179 | 179 |
err := findConfigurationConflicts(config, flags) |
180 | 180 |
if err == nil { |
181 | 181 |
t.Fatal("expected error, got nil") |
... | ... |
@@ -188,18 +173,15 @@ func TestFindConfigurationConflictsWithUnknownKeys(t *testing.T) { |
188 | 188 |
func TestFindConfigurationConflictsWithMergedValues(t *testing.T) { |
189 | 189 |
var hosts []string |
190 | 190 |
config := map[string]interface{}{"hosts": "tcp://127.0.0.1:2345"} |
191 |
- base := mflag.NewFlagSet("base", mflag.ContinueOnError) |
|
192 |
- base.Var(opts.NewNamedListOptsRef("hosts", &hosts, nil), []string{"H", "-host"}, "") |
|
193 |
- |
|
194 |
- flags := mflag.NewFlagSet("test", mflag.ContinueOnError) |
|
195 |
- mflag.Merge(flags, base) |
|
191 |
+ flags := pflag.NewFlagSet("base", pflag.ContinueOnError) |
|
192 |
+ flags.VarP(opts.NewNamedListOptsRef("hosts", &hosts, nil), "host", "H", "") |
|
196 | 193 |
|
197 | 194 |
err := findConfigurationConflicts(config, flags) |
198 | 195 |
if err != nil { |
199 | 196 |
t.Fatal(err) |
200 | 197 |
} |
201 | 198 |
|
202 |
- flags.Set("-host", "unix:///var/run/docker.sock") |
|
199 |
+ flags.Set("host", "unix:///var/run/docker.sock") |
|
203 | 200 |
err = findConfigurationConflicts(config, flags) |
204 | 201 |
if err == nil { |
205 | 202 |
t.Fatal("expected error, got nil") |
... | ... |
@@ -3,8 +3,8 @@ package daemon |
3 | 3 |
import ( |
4 | 4 |
"os" |
5 | 5 |
|
6 |
- flag "github.com/docker/docker/pkg/mflag" |
|
7 | 6 |
"github.com/docker/engine-api/types" |
7 |
+ "github.com/spf13/pflag" |
|
8 | 8 |
) |
9 | 9 |
|
10 | 10 |
var ( |
... | ... |
@@ -28,18 +28,15 @@ type Config struct { |
28 | 28 |
// for the Windows daemon.) |
29 | 29 |
} |
30 | 30 |
|
31 |
-// InstallFlags adds command-line options to the top-level flag parser for |
|
32 |
-// the current process. |
|
33 |
-// Subsequent calls to `flag.Parse` will populate config with values parsed |
|
34 |
-// from the command-line. |
|
35 |
-func (config *Config) InstallFlags(cmd *flag.FlagSet, usageFn func(string) string) { |
|
31 |
+// InstallFlags adds flags to the pflag.FlagSet to configure the daemon |
|
32 |
+func (config *Config) InstallFlags(flags *pflag.FlagSet) { |
|
36 | 33 |
// First handle install flags which are consistent cross-platform |
37 |
- config.InstallCommonFlags(cmd, usageFn) |
|
34 |
+ config.InstallCommonFlags(flags) |
|
38 | 35 |
|
39 | 36 |
// Then platform-specific install flags. |
40 |
- cmd.StringVar(&config.bridgeConfig.FixedCIDR, []string{"-fixed-cidr"}, "", usageFn("IPv4 subnet for fixed IPs")) |
|
41 |
- cmd.StringVar(&config.bridgeConfig.Iface, []string{"b", "-bridge"}, "", "Attach containers to a virtual switch") |
|
42 |
- cmd.StringVar(&config.SocketGroup, []string{"G", "-group"}, "", usageFn("Users or groups that can access the named pipe")) |
|
37 |
+ flags.StringVar(&config.bridgeConfig.FixedCIDR, "fixed-cidr", "", "IPv4 subnet for fixed IPs") |
|
38 |
+ flags.StringVarP(&config.bridgeConfig.Iface, "bridge", "b", "", "Attach containers to a virtual switch") |
|
39 |
+ flags.StringVarP(&config.SocketGroup, "group", "G", "", "Users or groups that can access the named pipe") |
|
43 | 40 |
} |
44 | 41 |
|
45 | 42 |
// GetRuntime returns the runtime path and arguments for a given |