github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/delete.go (about)

     1  // +build !solaris
     2  
     3  package main
     4  
     5  import (
     6  	"fmt"
     7  	"os"
     8  	"path/filepath"
     9  	"syscall"
    10  	"time"
    11  
    12  	"github.com/opencontainers/runc/libcontainer"
    13  	"github.com/urfave/cli"
    14  )
    15  
    16  func killContainer(container libcontainer.Container) error {
    17  	container.Signal(syscall.SIGKILL, false)
    18  	for i := 0; i < 100; i++ {
    19  		time.Sleep(100 * time.Millisecond)
    20  		if err := container.Signal(syscall.Signal(0), false); err != nil {
    21  			destroy(container)
    22  			return nil
    23  		}
    24  	}
    25  	return fmt.Errorf("container init still running")
    26  }
    27  
    28  var deleteCommand = cli.Command{
    29  	Name:  "delete",
    30  	Usage: "delete any resources held by one or more containers often used with detached containers",
    31  	ArgsUsage: `<container-id> [container-id...]
    32  
    33  Where "<container-id>" is the name for the instance of the container.
    34  
    35  EXAMPLE:
    36  For example, if the container id is "ubuntu01" and runc list currently shows the
    37  status of "ubuntu01" as "stopped" the following will delete resources held for
    38  "ubuntu01" removing "ubuntu01" from the runc list of containers:
    39  
    40         # runc delete ubuntu01`,
    41  	Flags: []cli.Flag{
    42  		cli.BoolFlag{
    43  			Name:  "force, f",
    44  			Usage: "Forcibly deletes the container if it is still running (uses SIGKILL)",
    45  		},
    46  	},
    47  	Action: func(context *cli.Context) error {
    48  		hasError := false
    49  		if !context.Args().Present() {
    50  			return fmt.Errorf("runc: \"delete\" requires a minimum of 1 argument")
    51  		}
    52  
    53  		factory, err := loadFactory(context)
    54  		if err != nil {
    55  			return err
    56  		}
    57  		for _, id := range context.Args() {
    58  			container, err := factory.Load(id)
    59  			if err != nil {
    60  				if lerr, ok := err.(libcontainer.Error); ok && lerr.Code() == libcontainer.ContainerNotExists {
    61  					// if there was an aborted start or something of the sort then the container's directory could exist but
    62  					// libcontainer does not see it because the state.json file inside that directory was never created.
    63  					path := filepath.Join(context.GlobalString("root"), id)
    64  					if err := os.RemoveAll(path); err != nil {
    65  						fmt.Fprintf(os.Stderr, "remove %s: %v\n", path, err)
    66  					}
    67  					fmt.Fprintf(os.Stderr, "container %s does not exist\n", id)
    68  				}
    69  				hasError = true
    70  				continue
    71  			}
    72  			s, err := container.Status()
    73  			if err != nil {
    74  				fmt.Fprintf(os.Stderr, "status for %s: %v\n", id, err)
    75  				hasError = true
    76  				continue
    77  			}
    78  			switch s {
    79  			case libcontainer.Stopped:
    80  				destroy(container)
    81  			case libcontainer.Created:
    82  				err := killContainer(container)
    83  				if err != nil {
    84  					fmt.Fprintf(os.Stderr, "kill container %s: %v\n", id, err)
    85  					hasError = true
    86  				}
    87  			default:
    88  				if context.Bool("force") {
    89  					err := killContainer(container)
    90  					if err != nil {
    91  						fmt.Fprintf(os.Stderr, "kill container %s: %v\n", id, err)
    92  						hasError = true
    93  					}
    94  				} else {
    95  					fmt.Fprintf(os.Stderr, "cannot delete container %s that is not stopped: %s\n", id, s)
    96  					hasError = true
    97  				}
    98  			}
    99  		}
   100  
   101  		if hasError {
   102  			return fmt.Errorf("one or more of the container deletions failed")
   103  		}
   104  		return nil
   105  	},
   106  }