Skip to content

Commit d358f20

Browse files
committed
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 <[email protected]>
1 parent 8c8c91c commit d358f20

File tree

1 file changed

+67
-13
lines changed

1 file changed

+67
-13
lines changed

cmd/crictl/container.go

+67-13
Original file line numberDiff line numberDiff line change
@@ -254,26 +254,80 @@ var stopContainerCommand = cli.Command{
254254
}
255255

256256
var removeContainerCommand = cli.Command{
257-
Name: "rm",
258-
Usage: "Remove one or more containers",
259-
ArgsUsage: "CONTAINER-ID [CONTAINER-ID...]",
260-
Action: func(context *cli.Context) error {
261-
if context.NArg() == 0 {
262-
return cli.ShowSubcommandHelp(context)
263-
}
264-
runtimeClient, runtimeConn, err := getRuntimeClient(context)
257+
Name: "rm",
258+
Usage: "Remove one or more containers",
259+
ArgsUsage: "CONTAINER-ID [CONTAINER-ID...]",
260+
SkipArgReorder: true,
261+
UseShortOptionHandling: true,
262+
Flags: []cli.Flag{
263+
cli.BoolFlag{
264+
Name: "force, f",
265+
Usage: "Force removal of the container, disregarding if running",
266+
},
267+
cli.BoolFlag{
268+
Name: "all, a",
269+
Usage: "Remove all containers",
270+
},
271+
},
272+
Action: func(ctx *cli.Context) error {
273+
runtimeClient, runtimeConn, err := getRuntimeClient(ctx)
265274
if err != nil {
266275
return err
267276
}
268-
defer closeConnection(context, runtimeConn)
277+
defer closeConnection(ctx, runtimeConn)
269278

270-
for i := 0; i < context.NArg(); i++ {
271-
containerID := context.Args().Get(i)
272-
err := RemoveContainer(runtimeClient, containerID)
279+
ids := ctx.Args()
280+
if ctx.Bool("all") {
281+
r, err := runtimeClient.ListContainers(context.Background(),
282+
&pb.ListContainersRequest{})
283+
if err != nil {
284+
return err
285+
}
286+
ids = nil
287+
for _, ctr := range r.GetContainers() {
288+
ids = append(ids, ctr.GetId())
289+
}
290+
}
291+
292+
if len(ids) == 0 {
293+
return cli.ShowSubcommandHelp(ctx)
294+
}
295+
296+
errored := false
297+
for _, id := range ids {
298+
resp, err := runtimeClient.ContainerStatus(context.Background(),
299+
&pb.ContainerStatusRequest{ContainerId: id})
300+
if err != nil {
301+
logrus.Error(err)
302+
errored = true
303+
continue
304+
}
305+
if resp.GetStatus().GetState() == pb.ContainerState_CONTAINER_RUNNING {
306+
if ctx.Bool("force") {
307+
if err := RemoveContainer(runtimeClient, id); err != nil {
308+
logrus.Errorf("stopping the container %q failed: %v", id, err)
309+
errored = true
310+
continue
311+
}
312+
continue
313+
} else {
314+
logrus.Errorf("container %q is running, please stop it first", id)
315+
errored = true
316+
continue
317+
}
318+
}
319+
320+
err = RemoveContainer(runtimeClient, id)
273321
if err != nil {
274-
fmt.Printf("Removing the container %q failed: %v\n", containerID, err)
322+
logrus.Errorf("removing container %q failed: %v", id, err)
323+
errored = true
324+
continue
275325
}
276326
}
327+
328+
if errored {
329+
return fmt.Errorf("unable to remove container(s)")
330+
}
277331
return nil
278332
},
279333
}

0 commit comments

Comments
 (0)