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 |