From 60e48bd6bd24c559ed92c7217cd7798c85cbb644 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Sun, 5 Jun 2016 22:40:35 +0200 Subject: [PATCH] Use spf13/cobra for docker rmi Moves image command rmi to `api/client/image/remove.go` and use cobra :) Signed-off-by: Vincent Demeester --- api/client/commands.go | 1 - api/client/image/remove.go | 70 ++++++++++++++++++++++++++ api/client/rmi.go | 60 ---------------------- cli/cobraadaptor/adaptor.go | 1 + cli/usage.go | 1 - integration-cli/docker_cli_rmi_test.go | 11 +--- 6 files changed, 73 insertions(+), 71 deletions(-) create mode 100644 api/client/image/remove.go delete mode 100644 api/client/rmi.go diff --git a/api/client/commands.go b/api/client/commands.go index d7833726c0..71229cc24d 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -35,7 +35,6 @@ func (cli *DockerCli) Command(name string) func(...string) error { "rename": cli.CmdRename, "restart": cli.CmdRestart, "rm": cli.CmdRm, - "rmi": cli.CmdRmi, "save": cli.CmdSave, "start": cli.CmdStart, "stats": cli.CmdStats, diff --git a/api/client/image/remove.go b/api/client/image/remove.go new file mode 100644 index 0000000000..c7c8322b89 --- /dev/null +++ b/api/client/image/remove.go @@ -0,0 +1,70 @@ +package image + +import ( + "fmt" + "strings" + + "golang.org/x/net/context" + + "github.com/docker/docker/api/client" + "github.com/docker/docker/cli" + "github.com/docker/engine-api/types" + "github.com/spf13/cobra" +) + +type removeOptions struct { + force bool + noPrune bool +} + +// NewRemoveCommand create a new `docker remove` command +func NewRemoveCommand(dockerCli *client.DockerCli) *cobra.Command { + var opts removeOptions + + cmd := &cobra.Command{ + Use: "rmi [OPTIONS] IMAGE [IMAGE...]", + Short: "Remove one or more images", + Args: cli.RequiresMinArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + return runRemove(dockerCli, opts, args) + }, + } + + flags := cmd.Flags() + + flags.BoolVarP(&opts.force, "force", "f", false, "Force removal of the image") + flags.BoolVar(&opts.noPrune, "no-prune", false, "Do not delete untagged parents") + + return cmd +} + +func runRemove(dockerCli *client.DockerCli, opts removeOptions, images []string) error { + client := dockerCli.Client() + ctx := context.Background() + + options := types.ImageRemoveOptions{ + Force: opts.force, + PruneChildren: !opts.noPrune, + } + + var errs []string + for _, image := range images { + dels, err := client.ImageRemove(ctx, image, options) + if err != nil { + errs = append(errs, err.Error()) + } else { + for _, del := range dels { + if del.Deleted != "" { + fmt.Fprintf(dockerCli.Out(), "Deleted: %s\n", del.Deleted) + } else { + fmt.Fprintf(dockerCli.Out(), "Untagged: %s\n", del.Untagged) + } + } + } + } + + if len(errs) > 0 { + return fmt.Errorf("%s", strings.Join(errs, "\n")) + } + return nil +} diff --git a/api/client/rmi.go b/api/client/rmi.go deleted file mode 100644 index 65e5e13a17..0000000000 --- a/api/client/rmi.go +++ /dev/null @@ -1,60 +0,0 @@ -package client - -import ( - "fmt" - "net/url" - "strings" - - "golang.org/x/net/context" - - Cli "github.com/docker/docker/cli" - flag "github.com/docker/docker/pkg/mflag" - "github.com/docker/engine-api/types" -) - -// CmdRmi removes all images with the specified name(s). -// -// Usage: docker rmi [OPTIONS] IMAGE [IMAGE...] -func (cli *DockerCli) CmdRmi(args ...string) error { - cmd := Cli.Subcmd("rmi", []string{"IMAGE [IMAGE...]"}, Cli.DockerCommands["rmi"].Description, true) - force := cmd.Bool([]string{"f", "-force"}, false, "Force removal of the image") - noprune := cmd.Bool([]string{"-no-prune"}, false, "Do not delete untagged parents") - cmd.Require(flag.Min, 1) - - cmd.ParseFlags(args, true) - - v := url.Values{} - if *force { - v.Set("force", "1") - } - if *noprune { - v.Set("noprune", "1") - } - - ctx := context.Background() - - var errs []string - for _, image := range cmd.Args() { - options := types.ImageRemoveOptions{ - Force: *force, - PruneChildren: !*noprune, - } - - dels, err := cli.client.ImageRemove(ctx, image, options) - if err != nil { - errs = append(errs, err.Error()) - } else { - for _, del := range dels { - if del.Deleted != "" { - fmt.Fprintf(cli.out, "Deleted: %s\n", del.Deleted) - } else { - fmt.Fprintf(cli.out, "Untagged: %s\n", del.Untagged) - } - } - } - } - if len(errs) > 0 { - return fmt.Errorf("%s", strings.Join(errs, "\n")) - } - return nil -} diff --git a/cli/cobraadaptor/adaptor.go b/cli/cobraadaptor/adaptor.go index cc74cce34c..139b9b1ec4 100644 --- a/cli/cobraadaptor/adaptor.go +++ b/cli/cobraadaptor/adaptor.go @@ -37,6 +37,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor { container.NewExportCommand(dockerCli), container.NewRunCommand(dockerCli), container.NewStopCommand(dockerCli), + image.NewRemoveCommand(dockerCli), image.NewSearchCommand(dockerCli), volume.NewVolumeCommand(dockerCli), ) diff --git a/cli/usage.go b/cli/usage.go index 86bd1fcec4..1bcce75a3d 100644 --- a/cli/usage.go +++ b/cli/usage.go @@ -34,7 +34,6 @@ var DockerCommandUsage = []Command{ {"rename", "Rename a container"}, {"restart", "Restart a container"}, {"rm", "Remove one or more containers"}, - {"rmi", "Remove one or more images"}, {"save", "Save one or more images to a tar archive"}, {"start", "Start one or more stopped containers"}, {"stats", "Display a live stream of container(s) resource usage statistics"}, diff --git a/integration-cli/docker_cli_rmi_test.go b/integration-cli/docker_cli_rmi_test.go index bce58ee126..8c9e2af07e 100644 --- a/integration-cli/docker_cli_rmi_test.go +++ b/integration-cli/docker_cli_rmi_test.go @@ -226,20 +226,13 @@ func (s *DockerSuite) TestRmiForceWithMultipleRepositories(c *check.C) { } func (s *DockerSuite) TestRmiBlank(c *check.C) { - // try to delete a blank image name - out, _, err := dockerCmdWithError("rmi", "") - // Should have failed to delete '' image + out, _, err := dockerCmdWithError("rmi", " ") + // Should have failed to delete ' ' image c.Assert(err, checker.NotNil) // Wrong error message generated c.Assert(out, checker.Not(checker.Contains), "no such id", check.Commentf("out: %s", out)) // Expected error message not generated c.Assert(out, checker.Contains, "image name cannot be blank", check.Commentf("out: %s", out)) - - out, _, err = dockerCmdWithError("rmi", " ") - // Should have failed to delete ' ' image - c.Assert(err, checker.NotNil) - // Expected error message not generated - c.Assert(out, checker.Contains, "image name cannot be blank", check.Commentf("out: %s", out)) } func (s *DockerSuite) TestRmiContainerImageNotFound(c *check.C) {