Преглед изворни кода

Merge pull request #8263 from jfrazelle/filter-status-name

Filter containers by status.
Alexandr Morozov пре 10 година
родитељ
комит
e32b54fe35

+ 1 - 1
api/client/commands.go

@@ -1485,7 +1485,7 @@ func (cli *DockerCli) CmdPs(args ...string) error {
 	last := cmd.Int([]string{"n"}, -1, "Show n last created containers, include non-running ones.")
 
 	flFilter := opts.NewListOpts(nil)
-	cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values. Valid filters:\nexited=<int> - containers with exit code of <int>")
+	cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values. Valid filters:\nexited=<int> - containers with exit code of <int>\nstatus=(restarting|running|paused|exited)")
 
 	if err := cmd.Parse(args); err != nil {
 		return nil

+ 8 - 0
daemon/list.go

@@ -28,6 +28,7 @@ func (daemon *Daemon) Containers(job *engine.Job) engine.Status {
 		size        = job.GetenvBool("size")
 		psFilters   filters.Args
 		filt_exited []int
+		filt_status []string
 	)
 	outs := engine.NewTable("Created", 0)
 
@@ -45,6 +46,8 @@ func (daemon *Daemon) Containers(job *engine.Job) engine.Status {
 		}
 	}
 
+	filt_status, _ = psFilters["status"]
+
 	names := map[string][]string{}
 	daemon.ContainerGraph().Walk("/", func(p string, e *graphdb.Entity) error {
 		names[e.ID()] = append(names[e.ID()], p)
@@ -99,6 +102,11 @@ func (daemon *Daemon) Containers(job *engine.Job) engine.Status {
 				return nil
 			}
 		}
+		for _, status := range filt_status {
+			if container.State.StateString() != strings.ToLower(status) {
+				return nil
+			}
+		}
 		displayed++
 		out := &engine.Env{}
 		out.Set("Id", container.ID)

+ 14 - 0
daemon/state.go

@@ -46,6 +46,20 @@ func (s *State) String() string {
 	return fmt.Sprintf("Exited (%d) %s ago", s.ExitCode, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt)))
 }
 
+// StateString returns a single string to describe state
+func (s *State) StateString() string {
+	if s.Running {
+		if s.Paused {
+			return "paused"
+		}
+		if s.Restarting {
+			return "restarting"
+		}
+		return "running"
+	}
+	return "exited"
+}
+
 func wait(waitChan <-chan struct{}, timeout time.Duration) error {
 	if timeout < 0 {
 		<-waitChan

+ 9 - 7
docs/sources/reference/commandline/cli.md

@@ -241,14 +241,15 @@ as the root. Wildcards are allowed but the search is not recursive.
     temp?
 
 The first line above `*/temp*`, would ignore all files with names starting with
-`temp` from any subdirectory below the root directory, for example file named 
-`/somedir/temporary.txt` will be ignored. The second line `*/*/temp*`, will  
+`temp` from any subdirectory below the root directory. For example, a file named
+`/somedir/temporary.txt` would be ignored. The second line `*/*/temp*`, will
 ignore files starting with name `temp` from any subdirectory that is two levels
-below the root directory, for example a file `/somedir/subdir/temporary.txt` is 
-ignored in this case. The last line in the above example `temp?`, will ignore 
-the files that match the pattern from the root directory, for example files 
-`tempa`, `tempb` are ignored from the root directory. Currently  there is no
-support for regular expressions, formats like `[^temp*]` are ignored.
+below the root directory. For example, the file `/somedir/subdir/temporary.txt`
+would get ignored in this case. The last line in the above example `temp?`
+will ignore the files that match the pattern from the root directory.
+For example, the files `tempa`, `tempb` are ignored from the root directory.
+Currently there is no support for regular expressions. Formats
+like `[^temp*]` are ignored.
 
 
 See also:
@@ -943,6 +944,7 @@ further details.
       --before=""           Show only container created before Id or Name, include non-running ones.
       -f, --filter=[]       Provide filter values. Valid filters:
                               exited=<int> - containers with exit code of <int>
+                              status=(restarting|running|paused|exited)
       -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

+ 46 - 0
integration-cli/docker_cli_ps_test.go

@@ -235,4 +235,50 @@ func TestPsListContainersSize(t *testing.T) {
 	if foundSize != expectedSize {
 		t.Fatalf("Expected size %q, got %q", expectedSize, foundSize)
 	}
+
+	deleteAllContainers()
+	logDone("ps - test ps size")
+}
+
+func TestPsListContainersFilterStatus(t *testing.T) {
+	// FIXME: this should test paused, but it makes things hang and its wonky
+	// this is because paused containers can't be controlled by signals
+
+	// start exited container
+	runCmd := exec.Command(dockerBinary, "run", "-d", "busybox")
+	out, _, err := runCommandWithOutput(runCmd)
+	errorOut(err, t, out)
+	firstID := stripTrailingCharacters(out)
+
+	// make sure the exited cintainer is not running
+	runCmd = exec.Command(dockerBinary, "wait", firstID)
+	out, _, err = runCommandWithOutput(runCmd)
+	errorOut(err, t, out)
+
+	// start running container
+	runCmd = exec.Command(dockerBinary, "run", "-d", "busybox", "sh", "-c", "sleep 360")
+	out, _, err = runCommandWithOutput(runCmd)
+	errorOut(err, t, out)
+	secondID := stripTrailingCharacters(out)
+
+	// filter containers by exited
+	runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--filter=status=exited")
+	out, _, err = runCommandWithOutput(runCmd)
+	errorOut(err, t, out)
+	containerOut := strings.TrimSpace(out)
+	if containerOut != firstID[:12] {
+		t.Fatalf("Expected id %s, got %s for exited filter, output: %q", firstID[:12], containerOut, out)
+	}
+
+	runCmd = exec.Command(dockerBinary, "ps", "-a", "-q", "--filter=status=running")
+	out, _, err = runCommandWithOutput(runCmd)
+	errorOut(err, t, out)
+	containerOut = strings.TrimSpace(out)
+	if containerOut != secondID[:12] {
+		t.Fatalf("Expected id %s, got %s for running filter, output: %q", secondID[:12], containerOut, out)
+	}
+
+	deleteAllContainers()
+
+	logDone("ps - test ps filter status")
 }