Skip to content

Commit

Permalink
Merge pull request moby#6162 from vbatts/vbatts-ps_filter
Browse files Browse the repository at this point in the history
docker ps: introducing filters
  • Loading branch information
vieux committed Aug 13, 2014
2 parents c071cd7 + 8414671 commit c9c2718
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 1 deletion.
21 changes: 21 additions & 0 deletions api/client/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,9 @@ func (cli *DockerCli) CmdPs(args ...string) error {
before := cmd.String([]string{"#beforeId", "#-before-id", "-before"}, "", "Show only container created before Id or Name, include non-running ones.")
last := cmd.Int([]string{"n"}, -1, "Show n last created containers, include non-running ones.")

var flFilter opts.ListOpts
cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values. Valid filters:\nexited=<int> - containers with exit code of <int>")

if err := cmd.Parse(args); err != nil {
return nil
}
Expand All @@ -1510,6 +1513,24 @@ func (cli *DockerCli) CmdPs(args ...string) error {
v.Set("size", "1")
}

// Consolidate all filter flags, and sanity check them.
// They'll get processed in the daemon/server.
psFilterArgs := filters.Args{}
for _, f := range flFilter.GetAll() {
var err error
psFilterArgs, err = filters.ParseFlag(f, psFilterArgs)
if err != nil {
return err
}
}
if len(psFilterArgs) > 0 {
filterJson, err := filters.ToParam(psFilterArgs)
if err != nil {
return err
}
v.Set("filters", filterJson)
}

body, _, err := readBody(cli.call("GET", "/containers/json?"+v.Encode(), nil, false))
if err != nil {
return err
Expand Down
1 change: 1 addition & 0 deletions api/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ func getContainersJSON(eng *engine.Engine, version version.Version, w http.Respo
job.Setenv("since", r.Form.Get("since"))
job.Setenv("before", r.Form.Get("before"))
job.Setenv("limit", r.Form.Get("limit"))
job.Setenv("filters", r.Form.Get("filters"))

if version.GreaterThanOrEqualTo("1.5") {
streamJSON(job, w, false)
Expand Down
30 changes: 30 additions & 0 deletions daemon/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package daemon
import (
"errors"
"fmt"
"strconv"
"strings"

"github.com/docker/docker/pkg/graphdb"

"github.com/docker/docker/engine"
"github.com/docker/docker/pkg/parsers/filters"
)

// List returns an array of all containers registered in the daemon.
Expand All @@ -24,9 +26,25 @@ func (daemon *Daemon) Containers(job *engine.Job) engine.Status {
before = job.Getenv("before")
n = job.GetenvInt("limit")
size = job.GetenvBool("size")
psFilters filters.Args
filt_exited []int
)
outs := engine.NewTable("Created", 0)

psFilters, err := filters.FromParam(job.Getenv("filters"))
if err != nil {
return job.Error(err)
}
if i, ok := psFilters["exited"]; ok {
for _, value := range i {
code, err := strconv.Atoi(value)
if err != nil {
return job.Error(err)
}
filt_exited = append(filt_exited, code)
}
}

names := map[string][]string{}
daemon.ContainerGraph().Walk("/", func(p string, e *graphdb.Entity) error {
names[e.ID()] = append(names[e.ID()], p)
Expand Down Expand Up @@ -69,6 +87,18 @@ func (daemon *Daemon) Containers(job *engine.Job) engine.Status {
return errLast
}
}
if len(filt_exited) > 0 && !container.State.IsRunning() {
should_skip := true
for _, code := range filt_exited {
if code == container.State.GetExitCode() {
should_skip = false
break
}
}
if should_skip {
return nil
}
}
displayed++
out := &engine.Env{}
out.Set("Id", container.ID)
Expand Down
4 changes: 3 additions & 1 deletion docs/sources/reference/api/docker_remote_api_v1.12.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ List containers
non-running ones.
- **size** – 1/True/true or 0/False/false, Show the containers
sizes
- **filters** – a JSON encoded value of the filters (a map[string][]string)
to process on the images list.

Status Codes:

Expand Down Expand Up @@ -759,7 +761,7 @@ Copy files or folders of container `id`
 

- **all** – 1/True/true or 0/False/false, default false
- **filters** – a json encoded value of the filters (a map[string][]string) to process on the images list.
- **filters** – a JSON encoded value of the filters (a map[string][]string) to process on the images list.



Expand Down
20 changes: 20 additions & 0 deletions docs/sources/reference/commandline/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,7 @@ further details.

-a, --all=false Show all containers. Only running containers are shown by default.
--before="" Show only container created before Id or Name, include non-running ones.
-f, --filter=[] Provide filter values (i.e. 'exited=0')
-l, --latest=false Show only the latest created container, include non-running ones.
-n=-1 Show n last created containers, include non-running ones.
--no-trunc=false Don't truncate output
Expand All @@ -811,6 +812,25 @@ Running `docker ps` showing 2 linked containers.
`docker ps` will show only running containers by default. To see all containers:
`docker ps -a`

### Filtering

The filtering flag (-f or --filter) format is a "key=value" pair. If there is more
than one filter, then pass multiple flags (e.g. `--filter "foo=bar" --filter "bif=baz"`)

Current filters:
* exited (int - the code of exited containers. Only useful with '--all')


#### Successfully exited containers

$ sudo docker ps -a --filter 'exited=0'
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea09c3c82f6e registry:latest /srv/run.sh 2 weeks ago Exited (0) 2 weeks ago 127.0.0.1:5000->5000/tcp desperate_leakey
106ea823fe4e fedora:latest /bin/sh -c 'bash -l' 2 weeks ago Exited (0) 2 weeks ago determined_albattani
48ee228c9464 fedora:20 bash 2 weeks ago Exited (0) 2 weeks ago tender_torvalds

This shows all the containers that have exited with status of '0'

## pull

Usage: docker pull NAME[:TAG]
Expand Down

0 comments on commit c9c2718

Please sign in to comment.