github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/list.go (about) 1 // +build linux 2 3 package main 4 5 import ( 6 "fmt" 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 "text/tabwriter" 11 "time" 12 13 "encoding/json" 14 15 "github.com/opencontainers/runc/libcontainer" 16 "github.com/opencontainers/runc/libcontainer/utils" 17 "github.com/urfave/cli" 18 ) 19 20 const formatOptions = `table or json` 21 22 // containerState represents the platform agnostic pieces relating to a 23 // running container's status and state 24 type containerState struct { 25 // Version is the OCI version for the container 26 Version string `json:"ociVersion"` 27 // ID is the container ID 28 ID string `json:"id"` 29 // InitProcessPid is the init process id in the parent namespace 30 InitProcessPid int `json:"pid"` 31 // Status is the current status of the container, running, paused, ... 32 Status string `json:"status"` 33 // Bundle is the path on the filesystem to the bundle 34 Bundle string `json:"bundle"` 35 // Rootfs is a path to a directory containing the container's root filesystem. 36 Rootfs string `json:"rootfs"` 37 // Created is the unix timestamp for the creation time of the container in UTC 38 Created time.Time `json:"created"` 39 // Annotations is the user defined annotations added to the config. 40 Annotations map[string]string `json:"annotations,omitempty"` 41 } 42 43 var listCommand = cli.Command{ 44 Name: "list", 45 Usage: "lists containers started by runc with the given root", 46 ArgsUsage: ` 47 48 Where the given root is specified via the global option "--root" 49 (default: "/run/runc"). 50 51 EXAMPLE 1: 52 To list containers created via the default "--root": 53 # runc list 54 55 EXAMPLE 2: 56 To list containers created using a non-default value for "--root": 57 # runc --root value list`, 58 Flags: []cli.Flag{ 59 cli.StringFlag{ 60 Name: "format, f", 61 Value: "table", 62 Usage: `select one of: ` + formatOptions, 63 }, 64 cli.BoolFlag{ 65 Name: "quiet, q", 66 Usage: "display only container IDs", 67 }, 68 }, 69 Action: func(context *cli.Context) error { 70 s, err := getContainers(context) 71 if err != nil { 72 return err 73 } 74 75 if context.Bool("quiet") { 76 for _, item := range s { 77 fmt.Println(item.ID) 78 } 79 return nil 80 } 81 82 switch context.String("format") { 83 case "table": 84 w := tabwriter.NewWriter(os.Stdout, 12, 1, 3, ' ', 0) 85 fmt.Fprint(w, "ID\tPID\tSTATUS\tBUNDLE\tCREATED\n") 86 for _, item := range s { 87 fmt.Fprintf(w, "%s\t%d\t%s\t%s\t%s\n", 88 item.ID, 89 item.InitProcessPid, 90 item.Status, 91 item.Bundle, 92 item.Created.Format(time.RFC3339Nano)) 93 } 94 if err := w.Flush(); err != nil { 95 return err 96 } 97 case "json": 98 if err := json.NewEncoder(os.Stdout).Encode(s); err != nil { 99 return err 100 } 101 default: 102 return fmt.Errorf("invalid format option") 103 } 104 return nil 105 }, 106 } 107 108 func getContainers(context *cli.Context) ([]containerState, error) { 109 factory, err := loadFactory(context) 110 if err != nil { 111 return nil, err 112 } 113 root := context.GlobalString("root") 114 absRoot, err := filepath.Abs(root) 115 if err != nil { 116 return nil, err 117 } 118 list, err := ioutil.ReadDir(absRoot) 119 if err != nil { 120 fatal(err) 121 } 122 123 var s []containerState 124 for _, item := range list { 125 if item.IsDir() { 126 container, err := factory.Load(item.Name()) 127 if err != nil { 128 fmt.Fprintf(os.Stderr, "load container %s: %v\n", item.Name(), err) 129 continue 130 } 131 containerStatus, err := container.Status() 132 if err != nil { 133 fmt.Fprintf(os.Stderr, "status for %s: %v\n", item.Name(), err) 134 continue 135 } 136 state, err := container.State() 137 if err != nil { 138 fmt.Fprintf(os.Stderr, "state for %s: %v\n", item.Name(), err) 139 continue 140 } 141 pid := state.BaseState.InitProcessPid 142 if containerStatus == libcontainer.Stopped { 143 pid = 0 144 } 145 bundle, annotations := utils.Annotations(state.Config.Labels) 146 s = append(s, containerState{ 147 Version: state.BaseState.Config.Version, 148 ID: state.BaseState.ID, 149 InitProcessPid: pid, 150 Status: containerStatus.String(), 151 Bundle: bundle, 152 Rootfs: state.BaseState.Config.Rootfs, 153 Created: state.BaseState.Created, 154 Annotations: annotations, 155 }) 156 } 157 } 158 return s, nil 159 }