github.com/kim0/docker@v0.6.2-0.20161130212042-4addda3f07e7/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  // Networks does nothing but return true.
    74  // It is needed to avoid the template check to fail as this field
    75  // doesn't exist in `types.Container`
    76  func (p *preProcessor) Networks() bool {
    77  	return true
    78  }
    79  
    80  func buildContainerListOptions(opts *psOptions) (*types.ContainerListOptions, error) {
    81  	options := &types.ContainerListOptions{
    82  		All:    opts.all,
    83  		Limit:  opts.last,
    84  		Size:   opts.size,
    85  		Filter: opts.filter.Value(),
    86  	}
    87  
    88  	if opts.nLatest && opts.last == -1 {
    89  		options.Limit = 1
    90  	}
    91  
    92  	// Currently only used with Size, so we can determine if the user
    93  	// put {{.Size}} in their format.
    94  	pre := &preProcessor{opts: options}
    95  	tmpl, err := templates.Parse(opts.format)
    96  
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  
   101  	// This shouldn't error out but swallowing the error makes it harder
   102  	// to track down if preProcessor issues come up. Ref #24696
   103  	if err := tmpl.Execute(ioutil.Discard, pre); err != nil {
   104  		return nil, err
   105  	}
   106  
   107  	return options, nil
   108  }
   109  
   110  func runPs(dockerCli *command.DockerCli, opts *psOptions) error {
   111  	ctx := context.Background()
   112  
   113  	listOptions, err := buildContainerListOptions(opts)
   114  	if err != nil {
   115  		return err
   116  	}
   117  
   118  	containers, err := dockerCli.Client().ContainerList(ctx, *listOptions)
   119  	if err != nil {
   120  		return err
   121  	}
   122  
   123  	format := opts.format
   124  	if len(format) == 0 {
   125  		if len(dockerCli.ConfigFile().PsFormat) > 0 && !opts.quiet {
   126  			format = dockerCli.ConfigFile().PsFormat
   127  		} else {
   128  			format = formatter.TableFormatKey
   129  		}
   130  	}
   131  
   132  	containerCtx := formatter.Context{
   133  		Output: dockerCli.Out(),
   134  		Format: formatter.NewContainerFormat(format, opts.quiet, listOptions.Size),
   135  		Trunc:  !opts.noTrunc,
   136  	}
   137  	return formatter.ContainerWrite(containerCtx, containers)
   138  }