1 //go:build windows 2 3 package main 4 5 import ( 6 "fmt" 7 "os" 8 "text/tabwriter" 9 "time" 10 11 "encoding/json" 12 13 "github.com/Microsoft/hcsshim/internal/appargs" 14 "github.com/Microsoft/hcsshim/internal/runhcs" 15 "github.com/urfave/cli" 16 ) 17 18 const formatOptions = `table or json` 19 20 var listCommand = cli.Command{ 21 Name: "list", 22 Usage: "lists containers started by runhcs with the given root", 23 ArgsUsage: ` 24 25 Where the given root is specified via the global option "--root" 26 (default: "/run/runhcs"). 27 28 EXAMPLE 1: 29 To list containers created via the default "--root": 30 # runhcs list 31 32 EXAMPLE 2: 33 To list containers created using a non-default value for "--root": 34 # runhcs --root value list`, 35 Flags: []cli.Flag{ 36 cli.StringFlag{ 37 Name: "format, f", 38 Value: "table", 39 Usage: `select one of: ` + formatOptions, 40 }, 41 cli.BoolFlag{ 42 Name: "quiet, q", 43 Usage: "display only container IDs", 44 }, 45 }, 46 Before: appargs.Validate(), 47 Action: func(context *cli.Context) error { 48 s, err := getContainers(context) 49 if err != nil { 50 return err 51 } 52 53 if context.Bool("quiet") { 54 for _, item := range s { 55 fmt.Println(item.ID) 56 } 57 return nil 58 } 59 60 switch context.String("format") { 61 case "table": 62 w := tabwriter.NewWriter(os.Stdout, 12, 1, 3, ' ', 0) 63 fmt.Fprint(w, "ID\tPID\tSTATUS\tBUNDLE\tCREATED\tOWNER\n") 64 for _, item := range s { 65 fmt.Fprintf(w, "%s\t%d\t%s\t%s\t%s\t%s\n", 66 item.ID, 67 item.InitProcessPid, 68 item.Status, 69 item.Bundle, 70 item.Created.Format(time.RFC3339Nano), 71 item.Owner) 72 } 73 if err := w.Flush(); err != nil { 74 return err 75 } 76 case "json": 77 if err := json.NewEncoder(os.Stdout).Encode(s); err != nil { 78 return err 79 } 80 default: 81 return fmt.Errorf("invalid format option") 82 } 83 return nil 84 }, 85 } 86 87 func getContainers(context *cli.Context) ([]runhcs.ContainerState, error) { 88 ids, err := stateKey.Enumerate() 89 if err != nil { 90 return nil, err 91 } 92 93 var s []runhcs.ContainerState 94 for _, id := range ids { 95 c, err := getContainer(id, false) 96 if err != nil { 97 fmt.Fprintf(os.Stderr, "reading state for %s: %v\n", id, err) 98 continue 99 } 100 status, err := c.Status() 101 if err != nil { 102 fmt.Fprintf(os.Stderr, "reading status for %s: %v\n", id, err) 103 } 104 105 s = append(s, runhcs.ContainerState{ 106 ID: id, 107 Version: c.Spec.Version, 108 InitProcessPid: c.ShimPid, 109 Status: string(status), 110 Bundle: c.Bundle, 111 Rootfs: c.Rootfs, 112 Created: c.Created, 113 Annotations: c.Spec.Annotations, 114 }) 115 c.Close() 116 } 117 return s, nil 118 } 119