mirror of
https://github.com/opencontainers/runc.git
synced 2025-09-26 19:41:35 +08:00

The only implementation of these is linuxContainer. It does not make sense to have an interface with a single implementation, and we do not foresee other types of containers being added to runc. Remove BaseContainer and Container interfaces, moving their methods documentation to linuxContainer. Rename linuxContainer to Container. Adopt users from using interface to using struct. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
88 lines
2.2 KiB
Go
88 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/opencontainers/runc/libcontainer"
|
|
"github.com/urfave/cli"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
func killContainer(container *libcontainer.Container) error {
|
|
_ = container.Signal(unix.SIGKILL, false)
|
|
for i := 0; i < 100; i++ {
|
|
time.Sleep(100 * time.Millisecond)
|
|
if err := container.Signal(unix.Signal(0), false); err != nil {
|
|
destroy(container)
|
|
return nil
|
|
}
|
|
}
|
|
return errors.New("container init still running")
|
|
}
|
|
|
|
var deleteCommand = cli.Command{
|
|
Name: "delete",
|
|
Usage: "delete any resources held by the container often used with detached container",
|
|
ArgsUsage: `<container-id>
|
|
|
|
Where "<container-id>" is the name for the instance of the container.
|
|
|
|
EXAMPLE:
|
|
For example, if the container id is "ubuntu01" and runc list currently shows the
|
|
status of "ubuntu01" as "stopped" the following will delete resources held for
|
|
"ubuntu01" removing "ubuntu01" from the runc list of containers:
|
|
|
|
# runc delete ubuntu01`,
|
|
Flags: []cli.Flag{
|
|
cli.BoolFlag{
|
|
Name: "force, f",
|
|
Usage: "Forcibly deletes the container if it is still running (uses SIGKILL)",
|
|
},
|
|
},
|
|
Action: func(context *cli.Context) error {
|
|
if err := checkArgs(context, 1, exactArgs); err != nil {
|
|
return err
|
|
}
|
|
|
|
id := context.Args().First()
|
|
force := context.Bool("force")
|
|
container, err := getContainer(context)
|
|
if err != nil {
|
|
if errors.Is(err, libcontainer.ErrNotExist) {
|
|
// 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 e := os.RemoveAll(path); e != nil {
|
|
fmt.Fprintf(os.Stderr, "remove %s: %v\n", path, e)
|
|
}
|
|
if force {
|
|
return nil
|
|
}
|
|
}
|
|
return err
|
|
}
|
|
s, err := container.Status()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
switch s {
|
|
case libcontainer.Stopped:
|
|
destroy(container)
|
|
case libcontainer.Created:
|
|
return killContainer(container)
|
|
default:
|
|
if force {
|
|
return killContainer(container)
|
|
}
|
|
return fmt.Errorf("cannot delete container %s that is not stopped: %s", id, s)
|
|
}
|
|
|
|
return nil
|
|
},
|
|
}
|