github.com/brahmaroutu/docker@v1.2.1-0.20160809185609-eb28dde01f16/api/client/container/ps.go (about) 1 package container 2 3 import ( 4 "golang.org/x/net/context" 5 6 "github.com/docker/docker/api/client" 7 "github.com/docker/docker/api/client/formatter" 8 "github.com/docker/docker/cli" 9 "github.com/docker/engine-api/types" 10 "github.com/docker/engine-api/types/filters" 11 12 "io/ioutil" 13 14 "github.com/docker/docker/utils/templates" 15 "github.com/spf13/cobra" 16 ) 17 18 type psOptions struct { 19 quiet bool 20 size bool 21 all bool 22 noTrunc bool 23 nLatest bool 24 last int 25 format string 26 filter []string 27 } 28 29 // NewPsCommand creates a new cobra.Command for `docker ps` 30 func NewPsCommand(dockerCli *client.DockerCli) *cobra.Command { 31 var opts psOptions 32 33 cmd := &cobra.Command{ 34 Use: "ps [OPTIONS]", 35 Short: "List containers", 36 Args: cli.NoArgs, 37 RunE: func(cmd *cobra.Command, args []string) error { 38 return runPs(dockerCli, &opts) 39 }, 40 } 41 42 flags := cmd.Flags() 43 44 flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only display numeric IDs") 45 flags.BoolVarP(&opts.size, "size", "s", false, "Display total file sizes") 46 flags.BoolVarP(&opts.all, "all", "a", false, "Show all containers (default shows just running)") 47 flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Don't truncate output") 48 flags.BoolVarP(&opts.nLatest, "latest", "l", false, "Show the latest created container (includes all states)") 49 flags.IntVarP(&opts.last, "last", "n", -1, "Show n last created containers (includes all states)") 50 flags.StringVarP(&opts.format, "format", "", "", "Pretty-print containers using a Go template") 51 flags.StringSliceVarP(&opts.filter, "filter", "f", []string{}, "Filter output based on conditions provided") 52 53 return cmd 54 } 55 56 type preProcessor struct { 57 types.Container 58 opts *types.ContainerListOptions 59 } 60 61 // Size sets the size option when called by a template execution. 62 func (p *preProcessor) Size() bool { 63 p.opts.Size = true 64 return true 65 } 66 67 func buildContainerListOptions(opts *psOptions) (*types.ContainerListOptions, error) { 68 69 options := &types.ContainerListOptions{ 70 All: opts.all, 71 Limit: opts.last, 72 Size: opts.size, 73 Filter: filters.NewArgs(), 74 } 75 76 if opts.nLatest && opts.last == -1 { 77 options.Limit = 1 78 } 79 80 for _, f := range opts.filter { 81 var err error 82 options.Filter, err = filters.ParseFlag(f, options.Filter) 83 if err != nil { 84 return nil, err 85 } 86 } 87 88 // Currently only used with Size, so we can determine if the user 89 // put {{.Size}} in their format. 90 pre := &preProcessor{opts: options} 91 tmpl, err := templates.Parse(opts.format) 92 93 if err != nil { 94 return nil, err 95 } 96 97 // This shouldn't error out but swallowing the error makes it harder 98 // to track down if preProcessor issues come up. Ref #24696 99 if err := tmpl.Execute(ioutil.Discard, pre); err != nil { 100 return nil, err 101 } 102 103 return options, nil 104 } 105 106 func runPs(dockerCli *client.DockerCli, opts *psOptions) error { 107 ctx := context.Background() 108 109 listOptions, err := buildContainerListOptions(opts) 110 if err != nil { 111 return err 112 } 113 114 containers, err := dockerCli.Client().ContainerList(ctx, *listOptions) 115 if err != nil { 116 return err 117 } 118 119 f := opts.format 120 if len(f) == 0 { 121 if len(dockerCli.ConfigFile().PsFormat) > 0 && !opts.quiet { 122 f = dockerCli.ConfigFile().PsFormat 123 } else { 124 f = "table" 125 } 126 } 127 128 psCtx := formatter.ContainerContext{ 129 Context: formatter.Context{ 130 Output: dockerCli.Out(), 131 Format: f, 132 Quiet: opts.quiet, 133 Trunc: !opts.noTrunc, 134 }, 135 Size: listOptions.Size, 136 Containers: containers, 137 } 138 139 psCtx.Write() 140 141 return nil 142 }