Use spf13/cobra for docker rmi
Moves image command rmi to `api/client/image/remove.go` and use cobra :) Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
parent
b259558336
commit
60e48bd6bd
6 changed files with 73 additions and 71 deletions
|
@ -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,
|
||||
|
|
70
api/client/image/remove.go
Normal file
70
api/client/image/remove.go
Normal file
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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),
|
||||
)
|
||||
|
|
|
@ -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"},
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue