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  }