From d358f2085a67bc17f8ce6cd1be4bf603d9a8c488 Mon Sep 17 00:00:00 2001 From: Sascha Grunert Date: Wed, 4 Sep 2019 12:51:29 +0200 Subject: [PATCH] Add container `rm` `--force, -f` and `--all, -a` flags This is the analogous implementation to the `rmp` command, where we're now able to either force container removal, remove them all, or to do both. Signed-off-by: Sascha Grunert --- cmd/crictl/container.go | 80 ++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 13 deletions(-) diff --git a/cmd/crictl/container.go b/cmd/crictl/container.go index aeabf60312..8e5515f187 100644 --- a/cmd/crictl/container.go +++ b/cmd/crictl/container.go @@ -254,26 +254,80 @@ var stopContainerCommand = cli.Command{ } var removeContainerCommand = cli.Command{ - Name: "rm", - Usage: "Remove one or more containers", - ArgsUsage: "CONTAINER-ID [CONTAINER-ID...]", - Action: func(context *cli.Context) error { - if context.NArg() == 0 { - return cli.ShowSubcommandHelp(context) - } - runtimeClient, runtimeConn, err := getRuntimeClient(context) + Name: "rm", + Usage: "Remove one or more containers", + ArgsUsage: "CONTAINER-ID [CONTAINER-ID...]", + SkipArgReorder: true, + UseShortOptionHandling: true, + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "force, f", + Usage: "Force removal of the container, disregarding if running", + }, + cli.BoolFlag{ + Name: "all, a", + Usage: "Remove all containers", + }, + }, + Action: func(ctx *cli.Context) error { + runtimeClient, runtimeConn, err := getRuntimeClient(ctx) if err != nil { return err } - defer closeConnection(context, runtimeConn) + defer closeConnection(ctx, runtimeConn) - for i := 0; i < context.NArg(); i++ { - containerID := context.Args().Get(i) - err := RemoveContainer(runtimeClient, containerID) + ids := ctx.Args() + if ctx.Bool("all") { + r, err := runtimeClient.ListContainers(context.Background(), + &pb.ListContainersRequest{}) + if err != nil { + return err + } + ids = nil + for _, ctr := range r.GetContainers() { + ids = append(ids, ctr.GetId()) + } + } + + if len(ids) == 0 { + return cli.ShowSubcommandHelp(ctx) + } + + errored := false + for _, id := range ids { + resp, err := runtimeClient.ContainerStatus(context.Background(), + &pb.ContainerStatusRequest{ContainerId: id}) + if err != nil { + logrus.Error(err) + errored = true + continue + } + if resp.GetStatus().GetState() == pb.ContainerState_CONTAINER_RUNNING { + if ctx.Bool("force") { + if err := RemoveContainer(runtimeClient, id); err != nil { + logrus.Errorf("stopping the container %q failed: %v", id, err) + errored = true + continue + } + continue + } else { + logrus.Errorf("container %q is running, please stop it first", id) + errored = true + continue + } + } + + err = RemoveContainer(runtimeClient, id) if err != nil { - fmt.Printf("Removing the container %q failed: %v\n", containerID, err) + logrus.Errorf("removing container %q failed: %v", id, err) + errored = true + continue } } + + if errored { + return fmt.Errorf("unable to remove container(s)") + } return nil }, }