示例#1
0
func runEvents(dockerCli *client.DockerCli, opts *eventsOptions) error {
	eventFilterArgs := filters.NewArgs()

	// Consolidate all filter flags, and sanity check them early.
	// They'll get process in the daemon/server.
	for _, f := range opts.filter {
		var err error
		eventFilterArgs, err = filters.ParseFlag(f, eventFilterArgs)
		if err != nil {
			return err
		}
	}

	options := types.EventsOptions{
		Since:   opts.since,
		Until:   opts.until,
		Filters: eventFilterArgs,
	}

	responseBody, err := dockerCli.Client().Events(context.Background(), options)
	if err != nil {
		return err
	}
	defer responseBody.Close()

	return streamEvents(responseBody, dockerCli.Out())
}
示例#2
0
func cleanContainers(c *check.C) *docker.Project {
	client, err := dockerclient.NewEnvClient()
	c.Assert(err, check.IsNil)

	filterArgs := filters.NewArgs()
	filterArgs, err = filters.ParseFlag(d.KermitLabelFilter, filterArgs)
	c.Assert(err, check.IsNil)

	containers, err := client.ContainerList(context.Background(), types.ContainerListOptions{
		All:    true,
		Filter: filterArgs,
	})
	c.Assert(err, check.IsNil)

	for _, container := range containers {
		c.Logf("cleaning container %s…", container.ID)
		if err := client.ContainerRemove(context.Background(), container.ID, types.ContainerRemoveOptions{
			Force: true,
		}); err != nil {
			c.Errorf("Error while removing container %s : %v\n", container.ID, err)
		}
	}

	return docker.NewProject(client)
}
示例#3
0
func cleanContainers(t *testing.T) *docker.Project {
	client, err := dockerclient.NewEnvClient()
	if err != nil {
		t.Fatal(err)
	}

	filterArgs := filters.NewArgs()
	if filterArgs, err = filters.ParseFlag(docker.KermitLabelFilter, filterArgs); err != nil {
		t.Fatal(err)
	}

	containers, err := client.ContainerList(context.Background(), types.ContainerListOptions{
		All:    true,
		Filter: filterArgs,
	})
	if err != nil {
		t.Fatal(err)
	}

	for _, container := range containers {
		t.Logf("cleaning container %s…", container.ID)
		if err := client.ContainerRemove(context.Background(), container.ID, types.ContainerRemoveOptions{
			Force: true,
		}); err != nil {
			t.Errorf("Error while removing container %s : %v\n", container.ID, err)
		}
	}

	return docker.NewProject(client)
}
示例#4
0
文件: network.go 项目: kjplatz/vic
// CmdNetworkLs lists all the networks managed by docker daemon
//
// Usage: docker network ls [OPTIONS]
func (cli *DockerCli) CmdNetworkLs(args ...string) error {
	cmd := Cli.Subcmd("network ls", nil, "Lists networks", true)
	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs")
	noTrunc := cmd.Bool([]string{"-no-trunc"}, false, "Do not truncate the output")

	flFilter := opts.NewListOpts(nil)
	cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")

	cmd.Require(flag.Exact, 0)
	err := cmd.ParseFlags(args, true)
	if err != nil {
		return err
	}

	// Consolidate all filter flags, and sanity check them early.
	// They'll get process after get response from server.
	netFilterArgs := filters.NewArgs()
	for _, f := range flFilter.GetAll() {
		if netFilterArgs, err = filters.ParseFlag(f, netFilterArgs); err != nil {
			return err
		}
	}

	options := types.NetworkListOptions{
		Filters: netFilterArgs,
	}

	networkResources, err := cli.client.NetworkList(context.Background(), options)
	if err != nil {
		return err
	}

	wr := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)

	// unless quiet (-q) is specified, print field titles
	if !*quiet {
		fmt.Fprintln(wr, "NETWORK ID\tNAME\tDRIVER")
	}
	sort.Sort(byNetworkName(networkResources))
	for _, networkResource := range networkResources {
		ID := networkResource.ID
		netName := networkResource.Name
		if !*noTrunc {
			ID = stringid.TruncateID(ID)
		}
		if *quiet {
			fmt.Fprintln(wr, ID)
			continue
		}
		driver := networkResource.Driver
		fmt.Fprintf(wr, "%s\t%s\t%s\t",
			ID,
			netName,
			driver)
		fmt.Fprint(wr, "\n")
	}
	wr.Flush()
	return nil
}
示例#5
0
文件: images.go 项目: maxim28/docker
func runImages(dockerCli *client.DockerCli, opts imagesOptions) error {
	ctx := context.Background()

	// Consolidate all filter flags, and sanity check them early.
	// They'll get process in the daemon/server.
	imageFilterArgs := filters.NewArgs()
	for _, f := range opts.filter {
		var err error
		imageFilterArgs, err = filters.ParseFlag(f, imageFilterArgs)
		if err != nil {
			return err
		}
	}

	matchName := opts.matchName

	options := types.ImageListOptions{
		MatchName: matchName,
		All:       opts.all,
		Filters:   imageFilterArgs,
	}

	images, err := dockerCli.Client().ImageList(ctx, options)
	if err != nil {
		return err
	}

	f := opts.format
	if len(f) == 0 {
		if len(dockerCli.ConfigFile().ImagesFormat) > 0 && !opts.quiet {
			f = dockerCli.ConfigFile().ImagesFormat
		} else {
			f = "table"
		}
	}

	imagesCtx := formatter.ImageContext{
		Context: formatter.Context{
			Output: dockerCli.Out(),
			Format: f,
			Quiet:  opts.quiet,
			Trunc:  !opts.noTrunc,
		},
		Digest: opts.showDigests,
		Images: images,
	}

	imagesCtx.Write()

	return nil
}
示例#6
0
文件: list.go 项目: F21/docker
func runList(dockerCli *client.DockerCli, opts listOptions) error {
	client := dockerCli.Client()

	netFilterArgs := filters.NewArgs()
	for _, f := range opts.filter {
		var err error
		netFilterArgs, err = filters.ParseFlag(f, netFilterArgs)
		if err != nil {
			return err
		}
	}

	options := types.NetworkListOptions{
		Filters: netFilterArgs,
	}

	networkResources, err := client.NetworkList(context.Background(), options)
	if err != nil {
		return err
	}

	w := tabwriter.NewWriter(dockerCli.Out(), 20, 1, 3, ' ', 0)
	if !opts.quiet {
		fmt.Fprintf(w, "NETWORK ID\tNAME\tDRIVER\tSCOPE")
		fmt.Fprintf(w, "\n")
	}

	sort.Sort(byNetworkName(networkResources))
	for _, networkResource := range networkResources {
		ID := networkResource.ID
		netName := networkResource.Name
		driver := networkResource.Driver
		scope := networkResource.Scope
		if !opts.noTrunc {
			ID = stringid.TruncateID(ID)
		}
		if opts.quiet {
			fmt.Fprintln(w, ID)
			continue
		}
		fmt.Fprintf(w, "%s\t%s\t%s\t%s\t",
			ID,
			netName,
			driver,
			scope)
		fmt.Fprint(w, "\n")
	}
	w.Flush()
	return nil
}
示例#7
0
func findContainersForProject(name string) ([]types.Container, error) {
	client, err := client.NewEnvClient()
	if err != nil {
		return []types.Container{}, err
	}
	filterArgs := filters.NewArgs()
	if filterArgs, err = filters.ParseFlag(docker.KermitLabelFilter, filterArgs); err != nil {
		return []types.Container{}, err
	}

	return client.ContainerList(context.Background(), types.ContainerListOptions{
		All:    true,
		Filter: filterArgs,
	})
}
示例#8
0
文件: list.go 项目: maxim28/docker
func runList(dockerCli *client.DockerCli, opts listOptions) error {
	client := dockerCli.Client()

	netFilterArgs := filters.NewArgs()
	for _, f := range opts.filter {
		var err error
		netFilterArgs, err = filters.ParseFlag(f, netFilterArgs)
		if err != nil {
			return err
		}
	}

	options := types.NetworkListOptions{
		Filters: netFilterArgs,
	}

	networkResources, err := client.NetworkList(context.Background(), options)
	if err != nil {
		return err
	}

	f := opts.format
	if len(f) == 0 {
		if len(dockerCli.ConfigFile().NetworksFormat) > 0 && !opts.quiet {
			f = dockerCli.ConfigFile().NetworksFormat
		} else {
			f = "table"
		}
	}

	sort.Sort(byNetworkName(networkResources))

	networksCtx := formatter.NetworkContext{
		Context: formatter.Context{
			Output: dockerCli.Out(),
			Format: f,
			Quiet:  opts.quiet,
			Trunc:  !opts.noTrunc,
		},
		Networks: networkResources,
	}

	networksCtx.Write()

	return nil
}
示例#9
0
文件: volume.go 项目: ailispaw/docker
// CmdVolumeLs outputs a list of Docker volumes.
//
// Usage: docker volume ls [OPTIONS]
func (cli *DockerCli) CmdVolumeLs(args ...string) error {
	cmd := Cli.Subcmd("volume ls", nil, "List volumes", true)

	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display volume names")
	flFilter := opts.NewListOpts(nil)
	cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values (i.e. 'dangling=true')")

	cmd.Require(flag.Exact, 0)
	cmd.ParseFlags(args, true)

	volFilterArgs := filters.NewArgs()
	for _, f := range flFilter.GetAll() {
		var err error
		volFilterArgs, err = filters.ParseFlag(f, volFilterArgs)
		if err != nil {
			return err
		}
	}

	volumes, err := cli.client.VolumeList(context.Background(), volFilterArgs)
	if err != nil {
		return err
	}

	w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
	if !*quiet {
		for _, warn := range volumes.Warnings {
			fmt.Fprintln(cli.err, warn)
		}
		fmt.Fprintf(w, "DRIVER \tVOLUME NAME")
		fmt.Fprintf(w, "\n")
	}

	sort.Sort(byVolumeName(volumes.Volumes))
	for _, vol := range volumes.Volumes {
		if *quiet {
			fmt.Fprintln(w, vol.Name)
			continue
		}
		fmt.Fprintf(w, "%s\t%s\n", vol.Driver, vol.Name)
	}
	w.Flush()
	return nil
}
示例#10
0
文件: list.go 项目: nak3/docker
func runList(dockerCli *client.DockerCli, opts listOptions) error {
	client := dockerCli.Client()

	volFilterArgs := filters.NewArgs()
	for _, f := range opts.filter {
		var err error
		volFilterArgs, err = filters.ParseFlag(f, volFilterArgs)
		if err != nil {
			return err
		}
	}

	volumes, err := client.VolumeList(context.Background(), volFilterArgs)
	if err != nil {
		return err
	}

	f := opts.format
	if len(f) == 0 {
		if len(dockerCli.ConfigFile().VolumesFormat) > 0 && !opts.quiet {
			f = dockerCli.ConfigFile().VolumesFormat
		} else {
			f = "table"
		}
	}

	sort.Sort(byVolumeName(volumes.Volumes))

	volumeCtx := formatter.VolumeContext{
		Context: formatter.Context{
			Output: dockerCli.Out(),
			Format: f,
			Quiet:  opts.quiet,
		},
		Volumes: volumes.Volumes,
	}

	volumeCtx.Write()

	return nil
}
示例#11
0
func buildContainerListOptions(opts *psOptions) (*types.ContainerListOptions, error) {

	options := &types.ContainerListOptions{
		All:    opts.all,
		Limit:  opts.last,
		Size:   opts.size,
		Filter: filters.NewArgs(),
	}

	if opts.nLatest && opts.last == -1 {
		options.Limit = 1
	}

	for _, f := range opts.filter {
		var err error
		options.Filter, err = filters.ParseFlag(f, options.Filter)
		if err != nil {
			return nil, err
		}
	}

	// Currently only used with Size, so we can determine if the user
	// put {{.Size}} in their format.
	pre := &preProcessor{opts: options}
	tmpl, err := templates.Parse(opts.format)

	if err != nil {
		return nil, err
	}

	// This shouldn't error out but swallowing the error makes it harder
	// to track down if preProcessor issues come up. Ref #24696
	if err := tmpl.Execute(ioutil.Discard, pre); err != nil {
		return nil, err
	}

	return options, nil
}
示例#12
0
文件: list.go 项目: rlugojr/docker
func runList(dockerCli *client.DockerCli, opts listOptions) error {
	client := dockerCli.Client()

	volFilterArgs := filters.NewArgs()
	for _, f := range opts.filter {
		var err error
		volFilterArgs, err = filters.ParseFlag(f, volFilterArgs)
		if err != nil {
			return err
		}
	}

	volumes, err := client.VolumeList(context.Background(), volFilterArgs)
	if err != nil {
		return err
	}

	w := tabwriter.NewWriter(dockerCli.Out(), 20, 1, 3, ' ', 0)
	if !opts.quiet {
		for _, warn := range volumes.Warnings {
			fmt.Fprintln(dockerCli.Err(), warn)
		}
		fmt.Fprintf(w, "DRIVER \tVOLUME NAME")
		fmt.Fprintf(w, "\n")
	}

	sort.Sort(byVolumeName(volumes.Volumes))
	for _, vol := range volumes.Volumes {
		if opts.quiet {
			fmt.Fprintln(w, vol.Name)
			continue
		}
		fmt.Fprintf(w, "%s\t%s\n", vol.Driver, vol.Name)
	}
	w.Flush()
	return nil
}
示例#13
0
// CmdEvents prints a live stream of real time events from the server.
//
// Usage: docker events [OPTIONS]
func (cli *DockerCli) CmdEvents(args ...string) error {
	cmd := Cli.Subcmd("events", nil, Cli.DockerCommands["events"].Description, true)
	since := cmd.String([]string{"-since"}, "", "Show all events created since timestamp")
	until := cmd.String([]string{"-until"}, "", "Stream events until this timestamp")
	flFilter := opts.NewListOpts(nil)
	cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")
	cmd.Require(flag.Exact, 0)

	cmd.ParseFlags(args, true)

	eventFilterArgs := filters.NewArgs()

	// Consolidate all filter flags, and sanity check them early.
	// They'll get process in the daemon/server.
	for _, f := range flFilter.GetAll() {
		var err error
		eventFilterArgs, err = filters.ParseFlag(f, eventFilterArgs)
		if err != nil {
			return err
		}
	}

	options := types.EventsOptions{
		Since:   *since,
		Until:   *until,
		Filters: eventFilterArgs,
	}

	responseBody, err := cli.client.Events(options)
	if err != nil {
		return err
	}
	defer responseBody.Close()

	return streamEvents(responseBody, cli.out)
}
示例#14
0
文件: images.go 项目: dfilion/docker
// CmdImages lists the images in a specified repository, or all top-level images if no repository is specified.
//
// Usage: docker images [OPTIONS] [REPOSITORY]
func (cli *DockerCli) CmdImages(args ...string) error {
	cmd := Cli.Subcmd("images", []string{"[REPOSITORY[:TAG]]"}, Cli.DockerCommands["images"].Description, true)
	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs")
	all := cmd.Bool([]string{"a", "-all"}, false, "Show all images (default hides intermediate images)")
	noTrunc := cmd.Bool([]string{"-no-trunc"}, false, "Don't truncate output")
	showDigests := cmd.Bool([]string{"-digests"}, false, "Show digests")
	format := cmd.String([]string{"-format"}, "", "Pretty-print images using a Go template")

	flFilter := opts.NewListOpts(nil)
	cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")
	cmd.Require(flag.Max, 1)

	cmd.ParseFlags(args, true)

	// Consolidate all filter flags, and sanity check them early.
	// They'll get process in the daemon/server.
	imageFilterArgs := filters.NewArgs()
	for _, f := range flFilter.GetAll() {
		var err error
		imageFilterArgs, err = filters.ParseFlag(f, imageFilterArgs)
		if err != nil {
			return err
		}
	}

	var matchName string
	if cmd.NArg() == 1 {
		matchName = cmd.Arg(0)
	}

	options := types.ImageListOptions{
		MatchName: matchName,
		All:       *all,
		Filters:   imageFilterArgs,
	}

	images, err := cli.client.ImageList(options)
	if err != nil {
		return err
	}

	f := *format
	if len(f) == 0 {
		if len(cli.ImagesFormat()) > 0 && !*quiet {
			f = cli.ImagesFormat()
		} else {
			f = "table"
		}
	}

	imagesCtx := formatter.ImageContext{
		Context: formatter.Context{
			Output: cli.out,
			Format: f,
			Quiet:  *quiet,
			Trunc:  !*noTrunc,
		},
		Digest: *showDigests,
		Images: images,
	}

	imagesCtx.Write()

	return nil
}
示例#15
0
// CmdSearch searches the Docker Hub for images.
//
// Usage: docker search [OPTIONS] TERM
func (cli *DockerCli) CmdSearch(args ...string) error {
	var (
		err error

		filterArgs = filters.NewArgs()

		flFilter = opts.NewListOpts(nil)
	)

	cmd := Cli.Subcmd("search", []string{"TERM"}, Cli.DockerCommands["search"].Description, true)
	noTrunc := cmd.Bool([]string{"-no-trunc"}, false, "Don't truncate output")
	cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")

	// Deprecated since Docker 1.12 in favor of "--filter"
	automated := cmd.Bool([]string{"#-automated"}, false, "Only show automated builds - DEPRECATED")
	stars := cmd.Uint([]string{"s", "#-stars"}, 0, "Only displays with at least x stars - DEPRECATED")

	cmd.Require(flag.Exact, 1)

	cmd.ParseFlags(args, true)

	for _, f := range flFilter.GetAll() {
		if filterArgs, err = filters.ParseFlag(f, filterArgs); err != nil {
			return err
		}
	}

	name := cmd.Arg(0)
	v := url.Values{}
	v.Set("term", name)

	indexInfo, err := registry.ParseSearchIndexInfo(name)
	if err != nil {
		return err
	}

	ctx := context.Background()

	authConfig := cli.resolveAuthConfig(ctx, indexInfo)
	requestPrivilege := cli.registryAuthenticationPrivilegedFunc(indexInfo, "search")

	encodedAuth, err := encodeAuthToBase64(authConfig)
	if err != nil {
		return err
	}

	options := types.ImageSearchOptions{
		RegistryAuth:  encodedAuth,
		PrivilegeFunc: requestPrivilege,
		Filters:       filterArgs,
	}

	unorderedResults, err := cli.client.ImageSearch(ctx, name, options)
	if err != nil {
		return err
	}

	results := searchResultsByStars(unorderedResults)
	sort.Sort(results)

	w := tabwriter.NewWriter(cli.out, 10, 1, 3, ' ', 0)
	fmt.Fprintf(w, "NAME\tDESCRIPTION\tSTARS\tOFFICIAL\tAUTOMATED\n")
	for _, res := range results {
		// --automated and -s, --stars are deprecated since Docker 1.12
		if (*automated && !res.IsAutomated) || (int(*stars) > res.StarCount) {
			continue
		}
		desc := strings.Replace(res.Description, "\n", " ", -1)
		desc = strings.Replace(desc, "\r", " ", -1)
		if !*noTrunc && len(desc) > 45 {
			desc = stringutils.Truncate(desc, 42) + "..."
		}
		fmt.Fprintf(w, "%s\t%s\t%d\t", res.Name, desc, res.StarCount)
		if res.IsOfficial {
			fmt.Fprint(w, "[OK]")

		}
		fmt.Fprint(w, "\t")
		if res.IsAutomated {
			fmt.Fprint(w, "[OK]")
		}
		fmt.Fprint(w, "\n")
	}
	w.Flush()
	return nil
}
示例#16
0
func runPs(dockerCli *client.DockerCli, opts *psOptions) error {
	ctx := context.Background()

	if opts.nLatest && opts.last == -1 {
		opts.last = 1
	}

	containerFilterArgs := filters.NewArgs()
	for _, f := range opts.filter {
		var err error
		containerFilterArgs, err = filters.ParseFlag(f, containerFilterArgs)
		if err != nil {
			return err
		}
	}

	options := types.ContainerListOptions{
		All:    opts.all,
		Limit:  opts.last,
		Size:   opts.size,
		Filter: containerFilterArgs,
	}

	pre := &preProcessor{opts: &options}
	tmpl, err := templates.Parse(opts.format)

	if err != nil {
		return err
	}

	_ = tmpl.Execute(ioutil.Discard, pre)

	containers, err := dockerCli.Client().ContainerList(ctx, options)
	if err != nil {
		return err
	}

	f := opts.format
	if len(f) == 0 {
		if len(dockerCli.PsFormat()) > 0 && !opts.quiet {
			f = dockerCli.PsFormat()
		} else {
			f = "table"
		}
	}

	psCtx := formatter.ContainerContext{
		Context: formatter.Context{
			Output: dockerCli.Out(),
			Format: f,
			Quiet:  opts.quiet,
			Trunc:  !opts.noTrunc,
		},
		Size:       opts.size,
		Containers: containers,
	}

	psCtx.Write()

	return nil
}
示例#17
0
func runSearch(dockerCli *client.DockerCli, opts searchOptions) error {
	indexInfo, err := registry.ParseSearchIndexInfo(opts.term)
	if err != nil {
		return err
	}

	ctx := context.Background()

	authConfig := dockerCli.ResolveAuthConfig(ctx, indexInfo)
	requestPrivilege := dockerCli.RegistryAuthenticationPrivilegedFunc(indexInfo, "search")

	encodedAuth, err := client.EncodeAuthToBase64(authConfig)
	if err != nil {
		return err
	}

	searchFilters := filters.NewArgs()
	for _, f := range opts.filter {
		var err error
		searchFilters, err = filters.ParseFlag(f, searchFilters)
		if err != nil {
			return err
		}
	}

	options := types.ImageSearchOptions{
		RegistryAuth:  encodedAuth,
		PrivilegeFunc: requestPrivilege,
		Filters:       searchFilters,
		Limit:         opts.limit,
	}

	clnt := dockerCli.Client()

	unorderedResults, err := clnt.ImageSearch(ctx, opts.term, options)
	if err != nil {
		return err
	}

	results := searchResultsByStars(unorderedResults)
	sort.Sort(results)

	w := tabwriter.NewWriter(dockerCli.Out(), 10, 1, 3, ' ', 0)
	fmt.Fprintf(w, "NAME\tDESCRIPTION\tSTARS\tOFFICIAL\tAUTOMATED\n")
	for _, res := range results {
		// --automated and -s, --stars are deprecated since Docker 1.12
		if (opts.automated && !res.IsAutomated) || (int(opts.stars) > res.StarCount) {
			continue
		}
		desc := strings.Replace(res.Description, "\n", " ", -1)
		desc = strings.Replace(desc, "\r", " ", -1)
		if !opts.noTrunc && len(desc) > 45 {
			desc = stringutils.Truncate(desc, 42) + "..."
		}
		fmt.Fprintf(w, "%s\t%s\t%d\t", res.Name, desc, res.StarCount)
		if res.IsOfficial {
			fmt.Fprint(w, "[OK]")

		}
		fmt.Fprint(w, "\t")
		if res.IsAutomated {
			fmt.Fprint(w, "[OK]")
		}
		fmt.Fprint(w, "\n")
	}
	w.Flush()
	return nil
}
示例#18
0
文件: opts.go 项目: CNDonny/scope
// Set sets the value of the opt by parsing the command line value
func (o *FilterOpt) Set(value string) error {
	var err error
	o.filter, err = filters.ParseFlag(value, o.filter)
	return err
}
示例#19
0
文件: ps.go 项目: kjplatz/vic
// CmdPs outputs a list of Docker containers.
//
// Usage: docker ps [OPTIONS]
func (cli *DockerCli) CmdPs(args ...string) error {
	var (
		err error

		psFilterArgs = filters.NewArgs()

		cmd      = Cli.Subcmd("ps", nil, Cli.DockerCommands["ps"].Description, true)
		quiet    = cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs")
		size     = cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes")
		all      = cmd.Bool([]string{"a", "-all"}, false, "Show all containers (default shows just running)")
		noTrunc  = cmd.Bool([]string{"-no-trunc"}, false, "Don't truncate output")
		nLatest  = cmd.Bool([]string{"l", "-latest"}, false, "Show the latest created container (includes all states)")
		since    = cmd.String([]string{"#-since"}, "", "Show containers created since Id or Name (includes all states)")
		before   = cmd.String([]string{"#-before"}, "", "Only show containers created before Id or Name")
		last     = cmd.Int([]string{"n"}, -1, "Show n last created containers (includes all states)")
		format   = cmd.String([]string{"-format"}, "", "Pretty-print containers using a Go template")
		flFilter = opts.NewListOpts(nil)
	)
	cmd.Require(flag.Exact, 0)

	cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")

	cmd.ParseFlags(args, true)
	if *last == -1 && *nLatest {
		*last = 1
	}

	// Consolidate all filter flags, and sanity check them.
	// They'll get processed in the daemon/server.
	for _, f := range flFilter.GetAll() {
		if psFilterArgs, err = filters.ParseFlag(f, psFilterArgs); err != nil {
			return err
		}
	}

	options := types.ContainerListOptions{
		All:    *all,
		Limit:  *last,
		Since:  *since,
		Before: *before,
		Size:   *size,
		Filter: psFilterArgs,
	}

	containers, err := cli.client.ContainerList(context.Background(), options)
	if err != nil {
		return err
	}

	f := *format
	if len(f) == 0 {
		if len(cli.PsFormat()) > 0 && !*quiet {
			f = cli.PsFormat()
		} else {
			f = "table"
		}
	}

	psCtx := formatter.ContainerContext{
		Context: formatter.Context{
			Output: cli.out,
			Format: f,
			Quiet:  *quiet,
			Trunc:  !*noTrunc,
		},
		Size:       *size,
		Containers: containers,
	}

	psCtx.Write()

	return nil
}