mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #23242 from vdemeester/migrate-rmi-to-cobra
Use spf13/cobra for docker rmi
This commit is contained in:
commit
e94be2f639
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,
|
"rename": cli.CmdRename,
|
||||||
"restart": cli.CmdRestart,
|
"restart": cli.CmdRestart,
|
||||||
"rm": cli.CmdRm,
|
"rm": cli.CmdRm,
|
||||||
"rmi": cli.CmdRmi,
|
|
||||||
"save": cli.CmdSave,
|
"save": cli.CmdSave,
|
||||||
"start": cli.CmdStart,
|
"start": cli.CmdStart,
|
||||||
"stats": cli.CmdStats,
|
"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.NewExportCommand(dockerCli),
|
||||||
container.NewRunCommand(dockerCli),
|
container.NewRunCommand(dockerCli),
|
||||||
container.NewStopCommand(dockerCli),
|
container.NewStopCommand(dockerCli),
|
||||||
|
image.NewRemoveCommand(dockerCli),
|
||||||
image.NewSearchCommand(dockerCli),
|
image.NewSearchCommand(dockerCli),
|
||||||
volume.NewVolumeCommand(dockerCli),
|
volume.NewVolumeCommand(dockerCli),
|
||||||
)
|
)
|
||||||
|
|
|
@ -34,7 +34,6 @@ var DockerCommandUsage = []Command{
|
||||||
{"rename", "Rename a container"},
|
{"rename", "Rename a container"},
|
||||||
{"restart", "Restart a container"},
|
{"restart", "Restart a container"},
|
||||||
{"rm", "Remove one or more containers"},
|
{"rm", "Remove one or more containers"},
|
||||||
{"rmi", "Remove one or more images"},
|
|
||||||
{"save", "Save one or more images to a tar archive"},
|
{"save", "Save one or more images to a tar archive"},
|
||||||
{"start", "Start one or more stopped containers"},
|
{"start", "Start one or more stopped containers"},
|
||||||
{"stats", "Display a live stream of container(s) resource usage statistics"},
|
{"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) {
|
func (s *DockerSuite) TestRmiBlank(c *check.C) {
|
||||||
// try to delete a blank image name
|
out, _, err := dockerCmdWithError("rmi", " ")
|
||||||
out, _, err := dockerCmdWithError("rmi", "")
|
// Should have failed to delete ' ' image
|
||||||
// Should have failed to delete '' image
|
|
||||||
c.Assert(err, checker.NotNil)
|
c.Assert(err, checker.NotNil)
|
||||||
// Wrong error message generated
|
// Wrong error message generated
|
||||||
c.Assert(out, checker.Not(checker.Contains), "no such id", check.Commentf("out: %s", out))
|
c.Assert(out, checker.Not(checker.Contains), "no such id", check.Commentf("out: %s", out))
|
||||||
// Expected error message not generated
|
// Expected error message not generated
|
||||||
c.Assert(out, checker.Contains, "image name cannot be blank", check.Commentf("out: %s", out))
|
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) {
|
func (s *DockerSuite) TestRmiContainerImageNotFound(c *check.C) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue