Browse code

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 <github@gone.nl>

Sebastiaan van Stijn authored on 2016/06/06 09:04:33
Showing 6 changed files
... ...
@@ -378,9 +378,14 @@ func includeContainerInList(container *container.Container, ctx *listContext) it
378 378
 	networkExist := fmt.Errorf("container part of network")
379 379
 	if ctx.filters.Include("network") {
380 380
 		err := ctx.filters.WalkValues("network", func(value string) error {
381
-			if network := container.NetworkSettings.Networks[value]; network != nil {
381
+			if _, ok := container.NetworkSettings.Networks[value]; ok {
382 382
 				return networkExist
383 383
 			}
384
+			for _, nw := range container.NetworkSettings.Networks {
385
+				if nw.NetworkID == value {
386
+					return networkExist
387
+				}
388
+			}
384 389
 			return nil
385 390
 		})
386 391
 		if err != networkExist {
... ...
@@ -117,7 +117,7 @@ This section lists each version from latest to oldest.  Each listing includes a
117 117
 * `POST /containers/create` now takes `StorageOpt` field.
118 118
 * `GET /info` now returns `SecurityOptions` field, showing if `apparmor`, `seccomp`, or `selinux` is supported.
119 119
 * `GET /networks` now supports filtering by `label` and `driver`.
120
-* `GET /containers/json` now supports filtering containers by `network` name.
120
+* `GET /containers/json` now supports filtering containers by `network` name or id.
121 121
 * `POST /containers/create` now takes `MaximumIOps` and `MaximumIOBps` fields. Windows daemon only.
122 122
 * `POST /containers/create` now returns an HTTP 400 "bad parameter" message
123 123
   if no command is specified (instead of an HTTP 500 "server error")
... ...
@@ -223,7 +223,7 @@ Query Parameters:
223 223
   -   `before`=(`<container id>` or `<container name>`)
224 224
   -   `since`=(`<container id>` or `<container name>`)
225 225
   -   `volume`=(`<volume name>` or `<mount point destination>`)
226
-  -   `network`=(`<network name>`)
226
+  -   `network`=(`<network id>` or `<network name>`)
227 227
 
228 228
 Status Codes:
229 229
 
... ...
@@ -62,7 +62,7 @@ The currently supported filters are:
62 62
 * since (container's id or name) - filters containers created since given id or name
63 63
 * isolation (default|process|hyperv)   (Windows daemon only)
64 64
 * volume (volume name or mount point) - filters containers that mount volumes.
65
-* network (network name) - filters containers connected to the provided network name
65
+* network (network id or name) - filters containers connected to the provided network
66 66
 
67 67
 #### Label
68 68
 
... ...
@@ -209,15 +209,33 @@ The `volume` filter shows only containers that mount a specific volume or have a
209 209
 
210 210
 #### Network
211 211
 
212
-The `network` filter shows only containers that has endpoints on the provided network name.
212
+The `network` filter shows only containers that are connected to a network with
213
+a given name or id.
213 214
 
214
-    $docker run -d --net=net1 --name=test1 ubuntu top
215
-    $docker run -d --net=net2 --name=test2 ubuntu top
215
+The following filter matches all containers that are connected to a network
216
+with a name containing `net1`.
216 217
 
217
-    $docker ps --filter network=net1
218
-    CONTAINER ID        IMAGE       COMMAND       CREATED             STATUS              PORTS               NAMES
219
-    9d4893ed80fe        ubuntu      "top"         10 minutes ago      Up 10 minutes                           test1
218
+```bash
219
+$ docker run -d --net=net1 --name=test1 ubuntu top
220
+$ docker run -d --net=net2 --name=test2 ubuntu top
221
+
222
+$ docker ps --filter network=net1
223
+CONTAINER ID        IMAGE       COMMAND       CREATED             STATUS              PORTS               NAMES
224
+9d4893ed80fe        ubuntu      "top"         10 minutes ago      Up 10 minutes                           test1
225
+```
226
+
227
+The network filter matches on both the network's name and id. The following
228
+example shows all containers that are attached to the `net1` network, using
229
+the network id as a filter;
230
+
231
+```bash
232
+$ docker network inspect --format "{{.ID}}" net1
233
+8c0b4110ae930dbe26b258de9bc34a03f98056ed6f27f991d32919bfe401d7c5
220 234
 
235
+$ docker ps --filter network=8c0b4110ae930dbe26b258de9bc34a03f98056ed6f27f991d32919bfe401d7c5
236
+CONTAINER ID        IMAGE       COMMAND       CREATED             STATUS              PORTS               NAMES
237
+9d4893ed80fe        ubuntu      "top"         10 minutes ago      Up 10 minutes                           test1
238
+```
221 239
 
222 240
 ## Formatting
223 241
 
... ...
@@ -806,15 +806,30 @@ func (s *DockerSuite) TestPsFormatSize(c *check.C) {
806 806
 }
807 807
 
808 808
 func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) {
809
-	// create a container
810
-	out, _ := runSleepingContainer(c, "--net=bridge", "--name=onbridgenetwork")
811
-	out, _ = runSleepingContainer(c, "--net=none", "--name=onnonenetwork")
809
+	// TODO default network on Windows is not called "bridge", and creating a
810
+	// custom network fails on Windows fails with "Error response from daemon: plugin not found")
811
+	testRequires(c, DaemonIsLinux)
812
+
813
+	// create some containers
814
+	runSleepingContainer(c, "--net=bridge", "--name=onbridgenetwork")
815
+	runSleepingContainer(c, "--net=none", "--name=onnonenetwork")
816
+
817
+	// Filter docker ps on non existing network
818
+	out, _ := dockerCmd(c, "ps", "--filter", "network=doesnotexist")
819
+	containerOut := strings.TrimSpace(string(out))
820
+	lines := strings.Split(containerOut, "\n")
821
+
822
+	// skip header
823
+	lines = lines[1:]
824
+
825
+	// ps output should have no containers
826
+	c.Assert(lines, checker.HasLen, 0)
812 827
 
813 828
 	// Filter docker ps on network bridge
814 829
 	out, _ = dockerCmd(c, "ps", "--filter", "network=bridge")
815
-	containerOut := strings.TrimSpace(string(out))
830
+	containerOut = strings.TrimSpace(string(out))
816 831
 
817
-	lines := strings.Split(containerOut, "\n")
832
+	lines = strings.Split(containerOut, "\n")
818 833
 
819 834
 	// skip header
820 835
 	lines = lines[1:]
... ...
@@ -823,7 +838,7 @@ func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) {
823 823
 	c.Assert(lines, checker.HasLen, 1)
824 824
 
825 825
 	// Making sure onbridgenetwork is on the output
826
-	c.Assert(lines[0], checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on network\n"))
826
+	c.Assert(containerOut, checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on network\n"))
827 827
 
828 828
 	// Filter docker ps on networks bridge and none
829 829
 	out, _ = dockerCmd(c, "ps", "--filter", "network=bridge", "--filter", "network=none")
... ...
@@ -838,6 +853,14 @@ func (s *DockerSuite) TestPsListContainersFilterNetwork(c *check.C) {
838 838
 	c.Assert(lines, checker.HasLen, 2)
839 839
 
840 840
 	// Making sure onbridgenetwork and onnonenetwork is on the output
841
-	c.Assert(lines[0], checker.Contains, "onnonenetwork", check.Commentf("Missing the container on none network\n"))
842
-	c.Assert(lines[1], checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on bridge network\n"))
841
+	c.Assert(containerOut, checker.Contains, "onnonenetwork", check.Commentf("Missing the container on none network\n"))
842
+	c.Assert(containerOut, checker.Contains, "onbridgenetwork", check.Commentf("Missing the container on bridge network\n"))
843
+
844
+	nwID, _ := dockerCmd(c, "network", "inspect", "--format", "{{.ID}}", "bridge")
845
+
846
+	// Filter by network ID
847
+	out, _ = dockerCmd(c, "ps", "--filter", "network="+nwID)
848
+	containerOut = strings.TrimSpace(string(out))
849
+
850
+	c.Assert(containerOut, checker.Contains, "onbridgenetwork")
843 851
 }
... ...
@@ -36,7 +36,7 @@ the running containers.
36 36
    - since=(<container-name>|<container-id>)
37 37
    - ancestor=(<image-name>[:tag]|<image-id>|<image@digest>) - containers created from an image or a descendant.
38 38
    - volume=(<volume-name>|<mount-point-destination>)
39
-   - network=(<network-name>) - containers connected to the provided network name
39
+   - network=(<network-name>|<network-id>) - containers connected to the provided network
40 40
 
41 41
 **--format**="*TEMPLATE*"
42 42
    Pretty-print containers using a Go template.