Explorar o código

Merge pull request #6162 from vbatts/vbatts-ps_filter

docker ps: introducing filters
Victor Vieux %!s(int64=11) %!d(string=hai) anos
pai
achega
c9c271858a

+ 21 - 0
api/client/commands.go

@@ -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
 	}
@@ -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

+ 1 - 0
api/server/server.go

@@ -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)

+ 30 - 0
daemon/list.go

@@ -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.
@@ -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)
@@ -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)

+ 3 - 1
docs/sources/reference/api/docker_remote_api_v1.12.md

@@ -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:
 
@@ -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.
 
 
 

+ 20 - 0
docs/sources/reference/commandline/cli.md

@@ -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
@@ -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]