diff --git a/api/client/info.go b/api/client/info.go index b309dbfeed..42f06826e3 100644 --- a/api/client/info.go +++ b/api/client/info.go @@ -25,6 +25,9 @@ func (cli *DockerCli) CmdInfo(args ...string) error { } fmt.Fprintf(cli.out, "Containers: %d\n", info.Containers) + fmt.Fprintf(cli.out, " Running: %d\n", info.ContainersRunning) + fmt.Fprintf(cli.out, " Paused: %d\n", info.ContainersPaused) + fmt.Fprintf(cli.out, " Stopped: %d\n", info.ContainersStopped) fmt.Fprintf(cli.out, "Images: %d\n", info.Images) ioutils.FprintfIfNotEmpty(cli.out, "Server Version: %s\n", info.ServerVersion) ioutils.FprintfIfNotEmpty(cli.out, "Storage Driver: %s\n", info.Driver) diff --git a/api/types/types.go b/api/types/types.go index c4267858d3..6a02fdd9a8 100644 --- a/api/types/types.go +++ b/api/types/types.go @@ -193,6 +193,9 @@ type Version struct { type Info struct { ID string Containers int + ContainersRunning int + ContainersPaused int + ContainersStopped int Images int Driver string DriverStatus [][2]string diff --git a/daemon/info.go b/daemon/info.go index 83fe68fcb9..faaf0245b5 100644 --- a/daemon/info.go +++ b/daemon/info.go @@ -54,9 +54,24 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) { initPath := utils.DockerInitPath("") sysInfo := sysinfo.New(true) + var cRunning, cPaused, cStopped int + for _, c := range daemon.List() { + switch c.StateString() { + case "paused": + cPaused++ + case "running": + cRunning++ + default: + cStopped++ + } + } + v := &types.Info{ ID: daemon.ID, Containers: len(daemon.List()), + ContainersRunning: cRunning, + ContainersPaused: cPaused, + ContainersStopped: cStopped, Images: len(daemon.imageStore.Map()), Driver: daemon.GraphDriverName(), DriverStatus: daemon.layerStore.DriverStatus(), diff --git a/docs/reference/commandline/info.md b/docs/reference/commandline/info.md index c776ced583..51ae2699a1 100644 --- a/docs/reference/commandline/info.md +++ b/docs/reference/commandline/info.md @@ -21,6 +21,9 @@ For example: $ docker -D info Containers: 14 + Running: 3 + Paused: 1 + Stopped: 10 Images: 52 Server Version: 1.9.0 Storage Driver: aufs diff --git a/docs/userguide/labels-custom-metadata.md b/docs/userguide/labels-custom-metadata.md index 1a57eafe8d..ae6a3c5e9d 100644 --- a/docs/userguide/labels-custom-metadata.md +++ b/docs/userguide/labels-custom-metadata.md @@ -192,6 +192,9 @@ These labels appear as part of the `docker info` output for the daemon: $ docker -D info Containers: 12 + Running: 5 + Paused: 2 + Stopped: 5 Images: 672 Server Version: 1.9.0 Storage Driver: aufs diff --git a/integration-cli/check_test.go b/integration-cli/check_test.go index 030b07f0e5..b922316b61 100644 --- a/integration-cli/check_test.go +++ b/integration-cli/check_test.go @@ -28,6 +28,7 @@ type DockerSuite struct { } func (s *DockerSuite) TearDownTest(c *check.C) { + unpauseAllContainers() deleteAllContainers() deleteAllImages() deleteAllVolumes() diff --git a/integration-cli/docker_api_info_test.go b/integration-cli/docker_api_info_test.go index 479bf5fa4f..9e6af66e5a 100644 --- a/integration-cli/docker_api_info_test.go +++ b/integration-cli/docker_api_info_test.go @@ -18,6 +18,9 @@ func (s *DockerSuite) TestInfoApi(c *check.C) { stringsToCheck := []string{ "ID", "Containers", + "ContainersRunning", + "ContainersPaused", + "ContainersStopped", "Images", "ExecutionDriver", "LoggingDriver", diff --git a/integration-cli/docker_cli_info_test.go b/integration-cli/docker_cli_info_test.go index 232e4131f9..a7d28b6696 100644 --- a/integration-cli/docker_cli_info_test.go +++ b/integration-cli/docker_cli_info_test.go @@ -3,6 +3,7 @@ package main import ( "fmt" "net" + "strings" "github.com/docker/docker/pkg/integration/checker" "github.com/docker/docker/utils" @@ -17,6 +18,9 @@ func (s *DockerSuite) TestInfoEnsureSucceeds(c *check.C) { stringsToCheck := []string{ "ID:", "Containers:", + " Running:", + " Paused:", + " Stopped:", "Images:", "Execution Driver:", "OSType:", @@ -101,3 +105,44 @@ func (s *DockerSuite) TestInfoDiscoveryAdvertiseInterfaceName(c *check.C) { c.Assert(out, checker.Contains, fmt.Sprintf("Cluster store: %s\n", discoveryBackend)) c.Assert(out, checker.Contains, fmt.Sprintf("Cluster advertise: %s:2375\n", ip.String())) } + +func (s *DockerSuite) TestInfoDisplaysRunningContainers(c *check.C) { + testRequires(c, DaemonIsLinux) + + dockerCmd(c, "run", "-d", "busybox", "top") + out, _ := dockerCmd(c, "info") + c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", 1)) + c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", 1)) + c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", 0)) + c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", 0)) +} + +func (s *DockerSuite) TestInfoDisplaysPausedContainers(c *check.C) { + testRequires(c, DaemonIsLinux) + + out, _ := dockerCmd(c, "run", "-d", "busybox", "top") + cleanedContainerID := strings.TrimSpace(out) + + dockerCmd(c, "pause", cleanedContainerID) + + out, _ = dockerCmd(c, "info") + c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", 1)) + c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", 0)) + c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", 1)) + c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", 0)) +} + +func (s *DockerSuite) TestInfoDisplaysStoppedContainers(c *check.C) { + testRequires(c, DaemonIsLinux) + + out, _ := dockerCmd(c, "run", "-d", "busybox", "top") + cleanedContainerID := strings.TrimSpace(out) + + dockerCmd(c, "stop", cleanedContainerID) + + out, _ = dockerCmd(c, "info") + c.Assert(out, checker.Contains, fmt.Sprintf("Containers: %d\n", 1)) + c.Assert(out, checker.Contains, fmt.Sprintf(" Running: %d\n", 0)) + c.Assert(out, checker.Contains, fmt.Sprintf(" Paused: %d\n", 0)) + c.Assert(out, checker.Contains, fmt.Sprintf(" Stopped: %d\n", 1)) +} diff --git a/man/docker-info.1.md b/man/docker-info.1.md index ae04e49edf..0dc46c14ed 100644 --- a/man/docker-info.1.md +++ b/man/docker-info.1.md @@ -32,6 +32,9 @@ Here is a sample output: # docker info Containers: 14 + Running: 3 + Paused: 1 + Stopped: 10 Images: 52 Server Version: 1.9.0 Storage Driver: aufs