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