From 7c46ba02e694ae540866b29ebf0dab76e556cc13 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 6 Jun 2016 02:04:33 +0200 Subject: [PATCH] add support for filtering by network ID This adds support for filtering by network ID, to be consistent with other filter options. Note that only *full* matches are returned; this is consistent with other filters (e.g. volume), that also return full matches only. Signed-off-by: Sebastiaan van Stijn --- daemon/list.go | 7 +++- docs/reference/api/docker_remote_api.md | 2 +- docs/reference/api/docker_remote_api_v1.24.md | 2 +- docs/reference/commandline/ps.md | 32 +++++++++++---- integration-cli/docker_cli_ps_test.go | 39 +++++++++++++++---- man/docker-ps.1.md | 2 +- 6 files changed, 65 insertions(+), 19 deletions(-) diff --git a/daemon/list.go b/daemon/list.go index 1a26316293..fd5b78dd60 100644 --- a/daemon/list.go +++ b/daemon/list.go @@ -378,9 +378,14 @@ func includeContainerInList(container *container.Container, ctx *listContext) it networkExist := fmt.Errorf("container part of network") if ctx.filters.Include("network") { err := ctx.filters.WalkValues("network", func(value string) error { - if network := container.NetworkSettings.Networks[value]; network != nil { + if _, ok := container.NetworkSettings.Networks[value]; ok { return networkExist } + for _, nw := range container.NetworkSettings.Networks { + if nw.NetworkID == value { + return networkExist + } + } return nil }) if err != networkExist { diff --git a/docs/reference/api/docker_remote_api.md b/docs/reference/api/docker_remote_api.md index 19a11cda39..8b87496f2a 100644 --- a/docs/reference/api/docker_remote_api.md +++ b/docs/reference/api/docker_remote_api.md @@ -117,7 +117,7 @@ This section lists each version from latest to oldest. Each listing includes a * `POST /containers/create` now takes `StorageOpt` field. * `GET /info` now returns `SecurityOptions` field, showing if `apparmor`, `seccomp`, or `selinux` is supported. * `GET /networks` now supports filtering by `label` and `driver`. -* `GET /containers/json` now supports filtering containers by `network` name. +* `GET /containers/json` now supports filtering containers by `network` name or id. * `POST /containers/create` now takes `MaximumIOps` and `MaximumIOBps` fields. Windows daemon only. * `POST /containers/create` now returns an HTTP 400 "bad parameter" message if no command is specified (instead of an HTTP 500 "server error") diff --git a/docs/reference/api/docker_remote_api_v1.24.md b/docs/reference/api/docker_remote_api_v1.24.md index 18cb84e9cf..d525a71944 100644 --- a/docs/reference/api/docker_remote_api_v1.24.md +++ b/docs/reference/api/docker_remote_api_v1.24.md @@ -223,7 +223,7 @@ Query Parameters: - `before`=(`` or ``) - `since`=(`` or ``) - `volume`=(`` or ``) - - `network`=(``) + - `network`=(`` or ``) Status Codes: diff --git a/docs/reference/commandline/ps.md b/docs/reference/commandline/ps.md index 71c4fe5dc7..c661c653dc 100644 --- a/docs/reference/commandline/ps.md +++ b/docs/reference/commandline/ps.md @@ -62,7 +62,7 @@ The currently supported filters are: * since (container's id or name) - filters containers created since given id or name * isolation (default|process|hyperv) (Windows daemon only) * volume (volume name or mount point) - filters containers that mount volumes. -* network (network name) - filters containers connected to the provided network name +* network (network id or name) - filters containers connected to the provided network #### Label @@ -209,15 +209,33 @@ The `volume` filter shows only containers that mount a specific volume or have a #### Network -The `network` filter shows only containers that has endpoints on the provided network name. +The `network` filter shows only containers that are connected to a network with +a given name or id. - $docker run -d --net=net1 --name=test1 ubuntu top - $docker run -d --net=net2 --name=test2 ubuntu top +The following filter matches all containers that are connected to a network +with a name containing `net1`. - $docker ps --filter network=net1 - CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES - 9d4893ed80fe ubuntu "top" 10 minutes ago Up 10 minutes test1 +```bash +$ docker run -d --net=net1 --name=test1 ubuntu top +$ docker run -d --net=net2 --name=test2 ubuntu top +$ docker ps --filter network=net1 +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +9d4893ed80fe ubuntu "top" 10 minutes ago Up 10 minutes test1 +``` + +The network filter matches on both the network's name and id. The following +example shows all containers that are attached to the `net1` network, using +the network id as a filter; + +```bash +$ docker network inspect --format "{{.ID}}" net1 +8c0b4110ae930dbe26b258de9bc34a03f98056ed6f27f991d32919bfe401d7c5 + +$ docker ps --filter network=8c0b4110ae930dbe26b258de9bc34a03f98056ed6f27f991d32919bfe401d7c5 +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +9d4893ed80fe ubuntu "top" 10 minutes ago Up 10 minutes test1 +``` ## Formatting diff --git a/integration-cli/docker_cli_ps_test.go b/integration-cli/docker_cli_ps_test.go index 6c07de352b..a4ee9a9f65 100644 --- a/integration-cli/docker_cli_ps_test.go +++ b/integration-cli/docker_cli_ps_test.go @@ -806,15 +806,30 @@ func (s *DockerSuite) TestPsFormatSize(c *check.C) { } func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) { - // create a container - out, _ := runSleepingContainer(c, "--net=bridge", "--name=onbridgenetwork") - out, _ = runSleepingContainer(c, "--net=none", "--name=onnonenetwork") + // TODO default network on Windows is not called "bridge", and creating a + // custom network fails on Windows fails with "Error response from daemon: plugin not found") + testRequires(c, DaemonIsLinux) + + // create some containers + runSleepingContainer(c, "--net=bridge", "--name=onbridgenetwork") + runSleepingContainer(c, "--net=none", "--name=onnonenetwork") + + // Filter docker ps on non existing network + out, _ := dockerCmd(c, "ps", "--filter", "network=doesnotexist") + containerOut := strings.TrimSpace(string(out)) + lines := strings.Split(containerOut, "\n") + + // skip header + lines = lines[1:] + + // ps output should have no containers + c.Assert(lines, checker.HasLen, 0) // Filter docker ps on network bridge out, _ = dockerCmd(c, "ps", "--filter", "network=bridge") - containerOut := strings.TrimSpace(string(out)) + containerOut = strings.TrimSpace(string(out)) - lines := strings.Split(containerOut, "\n") + lines = strings.Split(containerOut, "\n") // skip header lines = lines[1:] @@ -823,7 +838,7 @@ func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) { c.Assert(lines, checker.HasLen, 1) // Making sure onbridgenetwork is on the output - c.Assert(lines[0], checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on network\n")) + c.Assert(containerOut, checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on network\n")) // Filter docker ps on networks bridge and none out, _ = dockerCmd(c, "ps", "--filter", "network=bridge", "--filter", "network=none") @@ -838,6 +853,14 @@ func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) { c.Assert(lines, checker.HasLen, 2) // Making sure onbridgenetwork and onnonenetwork is on the output - c.Assert(lines[0], checker.Contains, "onnonenetwork", check.Commentf("Missing the container on none network\n")) - c.Assert(lines[1], checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on bridge network\n")) + c.Assert(containerOut, checker.Contains, "onnonenetwork", check.Commentf("Missing the container on none network\n")) + c.Assert(containerOut, checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on bridge network\n")) + + nwID, _ := dockerCmd(c, "network", "inspect", "--format", "{{.ID}}", "bridge") + + // Filter by network ID + out, _ = dockerCmd(c, "ps", "--filter", "network="+nwID) + containerOut = strings.TrimSpace(string(out)) + + c.Assert(containerOut, checker.Contains, "onbridgenetwork") } diff --git a/man/docker-ps.1.md b/man/docker-ps.1.md index 0c2404b573..14c770121f 100644 --- a/man/docker-ps.1.md +++ b/man/docker-ps.1.md @@ -36,7 +36,7 @@ the running containers. - since=(|) - ancestor=([:tag]||) - containers created from an image or a descendant. - volume=(|) - - network=() - containers connected to the provided network name + - network=(|) - containers connected to the provided network **--format**="*TEMPLATE*" Pretty-print containers using a Go template.