From 9454c560c11e418f696b4325322dccc7b27659a8 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 29 Oct 2024 13:06:51 +0100 Subject: [PATCH] cli/command/container: unify completion funcs for create and run Define completion funcs for create and run together with where the flags are defined. Signed-off-by: Sebastiaan van Stijn --- cli/command/container/create.go | 14 ++------------ cli/command/container/opts.go | 17 ++++++++++++++--- cli/command/container/opts_test.go | 12 ++++++++++-- cli/command/container/run.go | 15 +++------------ 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/cli/command/container/create.go b/cli/command/container/create.go index 31ddeaad01..4026b05f23 100644 --- a/cli/command/container/create.go +++ b/cli/command/container/create.go @@ -75,19 +75,9 @@ func NewCreateCommand(dockerCli command.Cli) *cobra.Command { flags.Bool("help", false, "Print usage") command.AddPlatformFlag(flags, &options.platform) - command.AddTrustVerificationFlags(flags, &options.untrusted, dockerCli.ContentTrustEnabled()) - copts = addFlags(flags) - - _ = cmd.RegisterFlagCompletionFunc("cap-add", completeLinuxCapabilityNames) - _ = cmd.RegisterFlagCompletionFunc("cap-drop", completeLinuxCapabilityNames) - _ = cmd.RegisterFlagCompletionFunc("env", completion.EnvVarNames) - _ = cmd.RegisterFlagCompletionFunc("env-file", completion.FileNames) - _ = cmd.RegisterFlagCompletionFunc("network", completion.NetworkNames(dockerCli)) _ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms) - _ = cmd.RegisterFlagCompletionFunc("pull", completion.FromList(PullImageAlways, PullImageMissing, PullImageNever)) - _ = cmd.RegisterFlagCompletionFunc("restart", completeRestartPolicies) - _ = cmd.RegisterFlagCompletionFunc("stop-signal", completeSignals) - _ = cmd.RegisterFlagCompletionFunc("volumes-from", completion.ContainerNames(dockerCli, true)) + command.AddTrustVerificationFlags(flags, &options.untrusted, dockerCli.ContentTrustEnabled()) + copts = addContainerCreateFlags(cmd, dockerCli) return cmd } diff --git a/cli/command/container/opts.go b/cli/command/container/opts.go index 2106884898..21aff2b6c9 100644 --- a/cli/command/container/opts.go +++ b/cli/command/container/opts.go @@ -14,6 +14,7 @@ import ( "time" "github.com/docker/cli/cli/command" + "github.com/docker/cli/cli/command/completion" "github.com/docker/cli/cli/compose/loader" "github.com/docker/cli/opts" "github.com/docker/docker/api/types/container" @@ -24,6 +25,7 @@ import ( "github.com/docker/go-connections/nat" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "github.com/spf13/cobra" "github.com/spf13/pflag" cdi "tags.cncf.io/container-device-interface/pkg/parser" ) @@ -145,8 +147,9 @@ type containerOptions struct { Args []string } -// addFlags adds all command line flags that will be used by parse to the FlagSet -func addFlags(flags *pflag.FlagSet) *containerOptions { +// addContainerCreateFlags adds all command line flags that will be used by parse to the FlagSet +func addContainerCreateFlags(cmd *cobra.Command, dockerCLI completion.APIClientProvider) *containerOptions { + flags := cmd.Flags() copts := &containerOptions{ aliases: opts.NewListOpts(nil), attach: opts.NewListOpts(validateAttach), @@ -190,7 +193,9 @@ func addFlags(flags *pflag.FlagSet) *containerOptions { flags.Var(&copts.gpus, "gpus", "GPU devices to add to the container ('all' to pass all GPUs)") flags.SetAnnotation("gpus", "version", []string{"1.40"}) flags.VarP(&copts.env, "env", "e", "Set environment variables") + _ = cmd.RegisterFlagCompletionFunc("env", completion.EnvVarNames) flags.Var(&copts.envFile, "env-file", "Read in a file of environment variables") + _ = cmd.RegisterFlagCompletionFunc("env-file", completion.FileNames) flags.StringVar(&copts.entrypoint, "entrypoint", "", "Overwrite the default ENTRYPOINT of the image") flags.Var(&copts.groupAdd, "group-add", "Add additional groups to join") flags.StringVarP(&copts.hostname, "hostname", "h", "", "Container host name") @@ -200,7 +205,9 @@ func addFlags(flags *pflag.FlagSet) *containerOptions { flags.Var(&copts.labelsFile, "label-file", "Read in a line delimited file of labels") flags.BoolVar(&copts.readonlyRootfs, "read-only", false, "Mount the container's root filesystem as read only") flags.StringVar(&copts.restartPolicy, "restart", string(container.RestartPolicyDisabled), "Restart policy to apply when a container exits") + _ = cmd.RegisterFlagCompletionFunc("restart", completeRestartPolicies) flags.StringVar(&copts.stopSignal, "stop-signal", "", "Signal to stop the container") + _ = cmd.RegisterFlagCompletionFunc("stop-signal", completeSignals) flags.IntVar(&copts.stopTimeout, "stop-timeout", 0, "Timeout (in seconds) to stop a container") flags.SetAnnotation("stop-timeout", "version", []string{"1.25"}) flags.Var(copts.sysctls, "sysctl", "Sysctl options") @@ -212,7 +219,9 @@ func addFlags(flags *pflag.FlagSet) *containerOptions { // Security flags.Var(&copts.capAdd, "cap-add", "Add Linux capabilities") + _ = cmd.RegisterFlagCompletionFunc("cap-add", completeLinuxCapabilityNames) flags.Var(&copts.capDrop, "cap-drop", "Drop Linux capabilities") + _ = cmd.RegisterFlagCompletionFunc("cap-drop", completeLinuxCapabilityNames) flags.BoolVar(&copts.privileged, "privileged", false, "Give extended privileges to this container") flags.Var(&copts.securityOpt, "security-opt", "Security Options") flags.StringVar(&copts.usernsMode, "userns", "", "User namespace to use") @@ -242,8 +251,9 @@ func addFlags(flags *pflag.FlagSet) *containerOptions { flags.BoolVarP(&copts.publishAll, "publish-all", "P", false, "Publish all exposed ports to random ports") // We allow for both "--net" and "--network", although the latter is the recommended way. flags.Var(&copts.netMode, "net", "Connect a container to a network") + _ = flags.MarkHidden("net") flags.Var(&copts.netMode, "network", "Connect a container to a network") - flags.MarkHidden("net") + _ = cmd.RegisterFlagCompletionFunc("network", completion.NetworkNames(dockerCLI)) // We allow for both "--net-alias" and "--network-alias", although the latter is the recommended way. flags.Var(&copts.aliases, "net-alias", "Add network-scoped alias for the container") flags.Var(&copts.aliases, "network-alias", "Add network-scoped alias for the container") @@ -256,6 +266,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions { flags.Var(&copts.storageOpt, "storage-opt", "Storage driver options for the container") flags.Var(&copts.tmpfs, "tmpfs", "Mount a tmpfs directory") flags.Var(&copts.volumesFrom, "volumes-from", "Mount volumes from the specified container(s)") + _ = cmd.RegisterFlagCompletionFunc("volumes-from", completion.ContainerNames(dockerCLI, true)) flags.VarP(&copts.volumes, "volume", "v", "Bind mount a volume") flags.Var(&copts.mounts, "mount", "Attach a filesystem mount to the container") diff --git a/cli/command/container/opts_test.go b/cli/command/container/opts_test.go index e0ff746bc5..08589c9e2e 100644 --- a/cli/command/container/opts_test.go +++ b/cli/command/container/opts_test.go @@ -9,10 +9,12 @@ import ( "testing" "time" + "github.com/docker/cli/cli/command/completion" "github.com/docker/docker/api/types/container" networktypes "github.com/docker/docker/api/types/network" "github.com/docker/go-connections/nat" "github.com/pkg/errors" + "github.com/spf13/cobra" "github.com/spf13/pflag" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -57,10 +59,16 @@ func parseRun(args []string) (*container.Config, *container.HostConfig, *network } func setupRunFlags() (*pflag.FlagSet, *containerOptions) { - flags := pflag.NewFlagSet("run", pflag.ContinueOnError) + dummyCmd := &cobra.Command{Use: "dummy"} + // This will panic when called, but never called in tests + type dummyCLI struct { + completion.APIClientProvider + } + + flags := dummyCmd.Flags() flags.SetOutput(io.Discard) flags.Usage = nil - copts := addFlags(flags) + copts := addContainerCreateFlags(dummyCmd, dummyCLI{}) return flags, copts } diff --git a/cli/command/container/run.go b/cli/command/container/run.go index a3fc5f983a..c2694839eb 100644 --- a/cli/command/container/run.go +++ b/cli/command/container/run.go @@ -59,6 +59,7 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command { flags.StringVar(&options.name, "name", "", "Assign a name to the container") flags.StringVar(&options.detachKeys, "detach-keys", "", "Override the key sequence for detaching a container") flags.StringVar(&options.pull, "pull", PullImageMissing, `Pull image before running ("`+PullImageAlways+`", "`+PullImageMissing+`", "`+PullImageNever+`")`) + _ = cmd.RegisterFlagCompletionFunc("pull", completion.FromList(PullImageAlways, PullImageMissing, PullImageNever)) flags.BoolVarP(&options.quiet, "quiet", "q", false, "Suppress the pull output") // Add an explicit help that doesn't have a `-h` to prevent the conflict @@ -66,19 +67,9 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command { flags.Bool("help", false, "Print usage") command.AddPlatformFlag(flags, &options.platform) - command.AddTrustVerificationFlags(flags, &options.untrusted, dockerCli.ContentTrustEnabled()) - copts = addFlags(flags) - - _ = cmd.RegisterFlagCompletionFunc("cap-add", completeLinuxCapabilityNames) - _ = cmd.RegisterFlagCompletionFunc("cap-drop", completeLinuxCapabilityNames) - _ = cmd.RegisterFlagCompletionFunc("env", completion.EnvVarNames) - _ = cmd.RegisterFlagCompletionFunc("env-file", completion.FileNames) - _ = cmd.RegisterFlagCompletionFunc("network", completion.NetworkNames(dockerCli)) _ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms) - _ = cmd.RegisterFlagCompletionFunc("pull", completion.FromList(PullImageAlways, PullImageMissing, PullImageNever)) - _ = cmd.RegisterFlagCompletionFunc("restart", completeRestartPolicies) - _ = cmd.RegisterFlagCompletionFunc("stop-signal", completeSignals) - _ = cmd.RegisterFlagCompletionFunc("volumes-from", completion.ContainerNames(dockerCli, true)) + command.AddTrustVerificationFlags(flags, &options.untrusted, dockerCli.ContentTrustEnabled()) + copts = addContainerCreateFlags(cmd, dockerCli) return cmd }