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>
| ... | ... |
@@ -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) {
|