From d66ac3d9bd191df15dea804f3b1d6f14c382a5f3 Mon Sep 17 00:00:00 2001 From: Wang Long Date: Sun, 18 Sep 2016 11:44:17 +0800 Subject: [PATCH] enhance runc delete command This patch enhance the `runc delete` command as following 1) when `runc delete` without one container-id ``` $ runc delete runc: "delete" requires a minimum of 1 argument ``` 2) we can delete more containers at one command for example: ``` $ runc list ID PID STATUS BUNDLE CREATED a 8490 created /mycontainer 2016-09-18T03:49:32.259760434Z b 8520 running /mycontainer 2016-09-18T03:49:36.999299944Z c 8535 created /mycontainer 2016-09-18T03:49:40.975277538Z d 8549 created /mycontainer 2016-09-18T03:49:42.675282602Z e 8562 running /mycontainer 2016-09-18T03:49:44.175400931Z $ runc delete a b cc cannot delete container b that is not stopped: running container cc is not exist $ runc list ID PID STATUS BUNDLE CREATED b 8520 running /mycontainer 2016-09-18T03:49:36.999299944Z c 8535 created /mycontainer 2016-09-18T03:49:40.975277538Z d 8549 created /mycontainer 2016-09-18T03:49:42.675282602Z e 8562 running /mycontainer 2016-09-18T03:49:44.175400931Z $ runc delete -f b c d e $ runc list ID PID STATUS BUNDLE CREATED ``` Signed-off-by: Wang Long --- delete.go | 65 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/delete.go b/delete.go index 803bdcda9..d2e73a72a 100644 --- a/delete.go +++ b/delete.go @@ -27,8 +27,8 @@ func killContainer(container libcontainer.Container) error { var deleteCommand = cli.Command{ Name: "delete", - Usage: "delete any resources held by the container often used with detached containers", - ArgsUsage: ` + Usage: "delete any resources held by one container or more containers often used with detached containers", + ArgsUsage: `container-id [container-id...] Where "" is the name for the instance of the container. @@ -45,32 +45,51 @@ status of "ubuntu01" as "stopped" the following will delete resources held for }, }, Action: func(context *cli.Context) error { - container, err := getContainer(context) - if err != nil { - if lerr, ok := err.(libcontainer.Error); ok && lerr.Code() == libcontainer.ContainerNotExists { - // if there was an aborted start or something of the sort then the container's directory could exist but - // libcontainer does not see it because the state.json file inside that directory was never created. - path := filepath.Join(context.GlobalString("root"), context.Args().First()) - if err := os.RemoveAll(path); err != nil { - return err - } - } - return nil + if !context.Args().Present() { + return fmt.Errorf("runc: \"delete\" requires a minimum of 1 argument") } - s, err := container.Status() + + factory, err := loadFactory(context) if err != nil { return err } - switch s { - case libcontainer.Stopped: - destroy(container) - case libcontainer.Created: - return killContainer(container) - default: - if context.Bool("force") { - return killContainer(container) + for _, id := range context.Args() { + container, err := factory.Load(id) + if err != nil { + if lerr, ok := err.(libcontainer.Error); ok && lerr.Code() == libcontainer.ContainerNotExists { + // if there was an aborted start or something of the sort then the container's directory could exist but + // libcontainer does not see it because the state.json file inside that directory was never created. + path := filepath.Join(context.GlobalString("root"), id) + if err := os.RemoveAll(path); err != nil { + fmt.Fprintf(os.Stderr, "remove %s: %v\n", path, err) + } + fmt.Fprintf(os.Stderr, "container %s is not exist\n", id) + } + continue + } + s, err := container.Status() + if err != nil { + fmt.Fprintf(os.Stderr, "status for %s: %v\n", id, err) + continue + } + switch s { + case libcontainer.Stopped: + destroy(container) + case libcontainer.Created: + err := killContainer(container) + if err != nil { + fmt.Fprintf(os.Stderr, "kill container %s: %v\n", id, err) + } + default: + if context.Bool("force") { + err := killContainer(container) + if err != nil { + fmt.Fprintf(os.Stderr, "kill container %s: %v\n", id, err) + } + } else { + fmt.Fprintf(os.Stderr, "cannot delete container %s that is not stopped: %s\n", id, s) + } } - return fmt.Errorf("cannot delete container that is not stopped: %s", s) } return nil },