Browse code

Migrate rm command to cobra

Signed-off-by: Zhang Wei <zhangwei555@huawei.com>

Zhang Wei authored on 2016/06/07 00:32:38
Showing 7 changed files
... ...
@@ -17,7 +17,6 @@ func (cli *DockerCli) Command(name string) func(...string) error {
17 17
 		"ps":      cli.CmdPs,
18 18
 		"pull":    cli.CmdPull,
19 19
 		"push":    cli.CmdPush,
20
-		"rm":      cli.CmdRm,
21 20
 		"save":    cli.CmdSave,
22 21
 		"stats":   cli.CmdStats,
23 22
 		"tag":     cli.CmdTag,
24 23
new file mode 100644
... ...
@@ -0,0 +1,76 @@
0
+package container
1
+
2
+import (
3
+	"fmt"
4
+	"strings"
5
+
6
+	"golang.org/x/net/context"
7
+
8
+	"github.com/docker/docker/api/client"
9
+	"github.com/docker/docker/cli"
10
+	"github.com/docker/engine-api/types"
11
+	"github.com/spf13/cobra"
12
+)
13
+
14
+type rmOptions struct {
15
+	rmVolumes bool
16
+	rmLink    bool
17
+	force     bool
18
+
19
+	containers []string
20
+}
21
+
22
+// NewRmCommand creats a new cobra.Command for `docker rm`
23
+func NewRmCommand(dockerCli *client.DockerCli) *cobra.Command {
24
+	var opts rmOptions
25
+
26
+	cmd := &cobra.Command{
27
+		Use:   "rm [OPTIONS] CONTAINER [CONTAINER...]",
28
+		Short: "Remove one or more containers",
29
+		Args:  cli.RequiresMinArgs(1),
30
+		RunE: func(cmd *cobra.Command, args []string) error {
31
+			opts.containers = args
32
+			return runRm(dockerCli, &opts)
33
+		},
34
+	}
35
+
36
+	flags := cmd.Flags()
37
+	flags.BoolVarP(&opts.rmVolumes, "volumes", "v", false, "Remove the volumes associated with the container")
38
+	flags.BoolVarP(&opts.rmLink, "link", "l", false, "Remove the specified link")
39
+	flags.BoolVarP(&opts.force, "force", "f", false, "Force the removal of a running container (uses SIGKILL)")
40
+	return cmd
41
+}
42
+
43
+func runRm(dockerCli *client.DockerCli, opts *rmOptions) error {
44
+	ctx := context.Background()
45
+
46
+	var errs []string
47
+	for _, name := range opts.containers {
48
+		if name == "" {
49
+			return fmt.Errorf("Container name cannot be empty")
50
+		}
51
+		name = strings.Trim(name, "/")
52
+
53
+		if err := removeContainer(dockerCli, ctx, name, opts.rmVolumes, opts.rmLink, opts.force); err != nil {
54
+			errs = append(errs, err.Error())
55
+		} else {
56
+			fmt.Fprintf(dockerCli.Out(), "%s\n", name)
57
+		}
58
+	}
59
+	if len(errs) > 0 {
60
+		return fmt.Errorf("%s", strings.Join(errs, "\n"))
61
+	}
62
+	return nil
63
+}
64
+
65
+func removeContainer(dockerCli *client.DockerCli, ctx context.Context, container string, removeVolumes, removeLinks, force bool) error {
66
+	options := types.ContainerRemoveOptions{
67
+		RemoveVolumes: removeVolumes,
68
+		RemoveLinks:   removeLinks,
69
+		Force:         force,
70
+	}
71
+	if err := dockerCli.Client().ContainerRemove(ctx, container, options); err != nil {
72
+		return err
73
+	}
74
+	return nil
75
+}
... ...
@@ -234,7 +234,7 @@ func runRun(dockerCli *client.DockerCli, flags *pflag.FlagSet, opts *runOptions,
234 234
 		defer func() {
235 235
 			// Explicitly not sharing the context as it could be "Done" (by calling cancelFun)
236 236
 			// and thus the container would not be removed.
237
-			if err := dockerCli.RemoveContainer(context.Background(), createResponse.ID, true, false, true); err != nil {
237
+			if err := removeContainer(dockerCli, context.Background(), createResponse.ID, true, false, true); err != nil {
238 238
 				fmt.Fprintf(stderr, "%v\n", err)
239 239
 			}
240 240
 		}()
241 241
deleted file mode 100644
... ...
@@ -1,60 +0,0 @@
1
-package client
2
-
3
-import (
4
-	"fmt"
5
-	"strings"
6
-
7
-	"golang.org/x/net/context"
8
-
9
-	Cli "github.com/docker/docker/cli"
10
-	flag "github.com/docker/docker/pkg/mflag"
11
-	"github.com/docker/engine-api/types"
12
-)
13
-
14
-// CmdRm removes one or more containers.
15
-//
16
-// Usage: docker rm [OPTIONS] CONTAINER [CONTAINER...]
17
-func (cli *DockerCli) CmdRm(args ...string) error {
18
-	cmd := Cli.Subcmd("rm", []string{"CONTAINER [CONTAINER...]"}, Cli.DockerCommands["rm"].Description, true)
19
-	v := cmd.Bool([]string{"v", "-volumes"}, false, "Remove the volumes associated with the container")
20
-	link := cmd.Bool([]string{"l", "-link"}, false, "Remove the specified link")
21
-	force := cmd.Bool([]string{"f", "-force"}, false, "Force the removal of a running container (uses SIGKILL)")
22
-	cmd.Require(flag.Min, 1)
23
-
24
-	cmd.ParseFlags(args, true)
25
-
26
-	ctx := context.Background()
27
-
28
-	var errs []string
29
-	for _, name := range cmd.Args() {
30
-		if name == "" {
31
-			return fmt.Errorf("Container name cannot be empty")
32
-		}
33
-		name = strings.Trim(name, "/")
34
-
35
-		if err := cli.RemoveContainer(ctx, name, *v, *link, *force); err != nil {
36
-			errs = append(errs, err.Error())
37
-		} else {
38
-			fmt.Fprintf(cli.out, "%s\n", name)
39
-		}
40
-	}
41
-	if len(errs) > 0 {
42
-		return fmt.Errorf("%s", strings.Join(errs, "\n"))
43
-	}
44
-	return nil
45
-}
46
-
47
-// RemoveContainer removes a container
48
-// TODO: this can be unexported again once all container commands are under
49
-// api/client/container
50
-func (cli *DockerCli) RemoveContainer(ctx context.Context, container string, removeVolumes, removeLinks, force bool) error {
51
-	options := types.ContainerRemoveOptions{
52
-		RemoveVolumes: removeVolumes,
53
-		RemoveLinks:   removeLinks,
54
-		Force:         force,
55
-	}
56
-	if err := cli.client.ContainerRemove(ctx, container, options); err != nil {
57
-		return err
58
-	}
59
-	return nil
60
-}
... ...
@@ -44,6 +44,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor {
44 44
 		container.NewPortCommand(dockerCli),
45 45
 		container.NewRenameCommand(dockerCli),
46 46
 		container.NewRestartCommand(dockerCli),
47
+		container.NewRmCommand(dockerCli),
47 48
 		container.NewRunCommand(dockerCli),
48 49
 		container.NewStartCommand(dockerCli),
49 50
 		container.NewStopCommand(dockerCli),
... ...
@@ -22,7 +22,6 @@ var DockerCommandUsage = []Command{
22 22
 	{"ps", "List containers"},
23 23
 	{"pull", "Pull an image or a repository from a registry"},
24 24
 	{"push", "Push an image or a repository to a registry"},
25
-	{"rm", "Remove one or more containers"},
26 25
 	{"save", "Save one or more images to a tar archive"},
27 26
 	{"stats", "Display a live stream of container(s) resource usage statistics"},
28 27
 	{"tag", "Tag an image into a repository"},
... ...
@@ -184,7 +184,7 @@ func (s *DockerSuite) TestHelpExitCodesHelpOutput(c *check.C) {
184 184
 	c.Assert(stdout, checker.Equals, "")
185 185
 	// Should not contain full help text but should contain info about
186 186
 	// # of args and Usage line
187
-	c.Assert(stderr, checker.Contains, "requires a minimum", check.Commentf("Missing # of args text from 'docker rm'\n"))
187
+	c.Assert(stderr, checker.Contains, "requires at least 1 argument", check.Commentf("Missing # of args text from 'docker rm'\n"))
188 188
 
189 189
 	// docker rm NoSuchContainer: stdout=empty, stderr=all, rc=0
190 190
 	// testing to make sure no blank line on error