Browse code

Fix volume filter validation

Fixes: #18890
This fix add same filter validation logic as images. We should
add such check to make sure filters work make sense to end-users

Right now, we keep old use 1 as filter, but in long term, it should
be have same interface checking as images, it could be improved in
other patches.

Signed-off-by: Kai Qiang Wu(Kennan) <wkqwu@cn.ibm.com>

Kai Qiang Wu(Kennan) authored on 2016/01/04 17:37:01
Showing 2 changed files
... ...
@@ -15,6 +15,10 @@ import (
15 15
 	"github.com/docker/go-connections/nat"
16 16
 )
17 17
 
18
+var acceptedVolumeFilterTags = map[string]bool{
19
+	"dangling": true,
20
+}
21
+
18 22
 // iterationAction represents possible outcomes happening during the container iteration.
19 23
 type iterationAction int
20 24
 
... ...
@@ -410,20 +414,32 @@ func (daemon *Daemon) transformContainer(container *container.Container, ctx *li
410 410
 // Volumes lists known volumes, using the filter to restrict the range
411 411
 // of volumes returned.
412 412
 func (daemon *Daemon) Volumes(filter string) ([]*types.Volume, []string, error) {
413
-	var volumesOut []*types.Volume
413
+	var (
414
+		volumesOut   []*types.Volume
415
+		danglingOnly = false
416
+	)
414 417
 	volFilters, err := filters.FromParam(filter)
415 418
 	if err != nil {
416 419
 		return nil, nil, err
417 420
 	}
418 421
 
419
-	filterUsed := volFilters.Include("dangling") &&
420
-		(volFilters.ExactMatch("dangling", "true") || volFilters.ExactMatch("dangling", "1"))
422
+	if err := volFilters.Validate(acceptedVolumeFilterTags); err != nil {
423
+		return nil, nil, err
424
+	}
425
+
426
+	if volFilters.Include("dangling") {
427
+		if volFilters.ExactMatch("dangling", "true") || volFilters.ExactMatch("dangling", "1") {
428
+			danglingOnly = true
429
+		} else if !volFilters.ExactMatch("dangling", "false") && !volFilters.ExactMatch("dangling", "0") {
430
+			return nil, nil, fmt.Errorf("Invalid filter 'dangling=%s'", volFilters.Get("dangling"))
431
+		}
432
+	}
421 433
 
422 434
 	volumes, warnings, err := daemon.volumes.List()
423 435
 	if err != nil {
424 436
 		return nil, nil, err
425 437
 	}
426
-	if filterUsed {
438
+	if danglingOnly {
427 439
 		volumes = daemon.volumes.FilterByUsed(volumes)
428 440
 	}
429 441
 	for _, v := range volumes {
... ...
@@ -117,6 +117,30 @@ func (s *DockerSuite) TestVolumeCliLsFilterDangling(c *check.C) {
117 117
 	c.Assert(out, checker.Contains, "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
118 118
 	c.Assert(out, check.Not(checker.Contains), "testisinuse1\n", check.Commentf("volume 'testisinuse1' in output, but not expected"))
119 119
 	c.Assert(out, check.Not(checker.Contains), "testisinuse2\n", check.Commentf("volume 'testisinuse2' in output, but not expected"))
120
+
121
+	out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=1")
122
+	// Filter "dangling" volumes; only "dangling" (unused) volumes should be in the output, dangling also accept 1
123
+	c.Assert(out, checker.Contains, "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
124
+	c.Assert(out, check.Not(checker.Contains), "testisinuse1\n", check.Commentf("volume 'testisinuse1' in output, but not expected"))
125
+	c.Assert(out, check.Not(checker.Contains), "testisinuse2\n", check.Commentf("volume 'testisinuse2' in output, but not expected"))
126
+
127
+	out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=0")
128
+	// dangling=0 is same as dangling=false case
129
+	c.Assert(out, checker.Contains, "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
130
+	c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("expected volume 'testisinuse1' in output"))
131
+	c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output"))
132
+}
133
+
134
+func (s *DockerSuite) TestVolumeCliLsErrorWithInvalidFilterName(c *check.C) {
135
+	out, _, err := dockerCmdWithError("volume", "ls", "-f", "FOO=123")
136
+	c.Assert(err, checker.NotNil)
137
+	c.Assert(out, checker.Contains, "Invalid filter")
138
+}
139
+
140
+func (s *DockerSuite) TestVolumeCliLsWithIncorrectFilterValue(c *check.C) {
141
+	out, _, err := dockerCmdWithError("volume", "ls", "-f", "dangling=invalid")
142
+	c.Assert(err, check.NotNil)
143
+	c.Assert(out, checker.Contains, "Invalid filter")
120 144
 }
121 145
 
122 146
 func (s *DockerSuite) TestVolumeCliRm(c *check.C) {