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  }