Browse code

Make volume dangling filter return only used volumes with `dangling=false`.

Signed-off-by: David Calavera <david.calavera@gmail.com>

David Calavera authored on 2016/01/26 04:39:41
Showing 4 changed files
... ...
@@ -439,8 +439,8 @@ func (daemon *Daemon) Volumes(filter string) ([]*types.Volume, []string, error)
439 439
 	if err != nil {
440 440
 		return nil, nil, err
441 441
 	}
442
-	if danglingOnly {
443
-		volumes = daemon.volumes.FilterByUsed(volumes)
442
+	if volFilters.Include("dangling") {
443
+		volumes = daemon.volumes.FilterByUsed(volumes, !danglingOnly)
444 444
 	}
445 445
 	for _, v := range volumes {
446 446
 		volumesOut = append(volumesOut, volumeToAPIType(v))
... ...
@@ -106,8 +106,8 @@ func (s *DockerSuite) TestVolumeCliLsFilterDangling(c *check.C) {
106 106
 
107 107
 	out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=false")
108 108
 
109
-	// Same as above, but explicitly disabling dangling
110
-	c.Assert(out, checker.Contains, "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
109
+	// Explicitly disabling dangling
110
+	c.Assert(out, check.Not(checker.Contains), "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
111 111
 	c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("expected volume 'testisinuse1' in output"))
112 112
 	c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output"))
113 113
 
... ...
@@ -126,7 +126,7 @@ func (s *DockerSuite) TestVolumeCliLsFilterDangling(c *check.C) {
126 126
 
127 127
 	out, _ = dockerCmd(c, "volume", "ls", "--filter", "dangling=0")
128 128
 	// dangling=0 is same as dangling=false case
129
-	c.Assert(out, checker.Contains, "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
129
+	c.Assert(out, check.Not(checker.Contains), "testnotinuse1\n", check.Commentf("expected volume 'testnotinuse1' in output"))
130 130
 	c.Assert(out, checker.Contains, "testisinuse1\n", check.Commentf("expected volume 'testisinuse1' in output"))
131 131
 	c.Assert(out, checker.Contains, "testisinuse2\n", check.Commentf("expected volume 'testisinuse2' in output"))
132 132
 }
... ...
@@ -336,12 +336,18 @@ func (s *VolumeStore) FilterByDriver(name string) ([]volume.Volume, error) {
336 336
 	return ls, nil
337 337
 }
338 338
 
339
-// FilterByUsed returns the available volumes filtered by if they are not in use
340
-func (s *VolumeStore) FilterByUsed(vols []volume.Volume) []volume.Volume {
339
+// FilterByUsed returns the available volumes filtered by if they are in use or not.
340
+// `used=true` returns only volumes that are being used, while `used=false` returns
341
+// only volumes that are not being used.
342
+func (s *VolumeStore) FilterByUsed(vols []volume.Volume, used bool) []volume.Volume {
341 343
 	return s.filter(vols, func(v volume.Volume) bool {
342 344
 		s.locks.Lock(v.Name())
343
-		defer s.locks.Unlock(v.Name())
344
-		return len(s.refs[v.Name()]) == 0
345
+		l := len(s.refs[v.Name()])
346
+		s.locks.Unlock(v.Name())
347
+		if (used && l > 0) || (!used && l == 0) {
348
+			return true
349
+		}
350
+		return false
345 351
 	})
346 352
 }
347 353
 
... ...
@@ -123,3 +123,37 @@ func TestFilterByDriver(t *testing.T) {
123 123
 		t.Fatalf("Expected 1 volume, got %v, %v", len(l), l)
124 124
 	}
125 125
 }
126
+
127
+func TestFilterByUsed(t *testing.T) {
128
+	volumedrivers.Register(vt.NewFakeDriver("fake"), "fake")
129
+	volumedrivers.Register(vt.NewFakeDriver("noop"), "noop")
130
+
131
+	s := New()
132
+	if _, err := s.CreateWithRef("fake1", "fake", "volReference", nil); err != nil {
133
+		t.Fatal(err)
134
+	}
135
+	if _, err := s.Create("fake2", "fake", nil); err != nil {
136
+		t.Fatal(err)
137
+	}
138
+
139
+	vols, _, err := s.List()
140
+	if err != nil {
141
+		t.Fatal(err)
142
+	}
143
+
144
+	dangling := s.FilterByUsed(vols, false)
145
+	if len(dangling) != 1 {
146
+		t.Fatalf("expected 1 danging volume, got %v", len(dangling))
147
+	}
148
+	if dangling[0].Name() != "fake2" {
149
+		t.Fatalf("expected danging volume fake2, got %s", dangling[0].Name())
150
+	}
151
+
152
+	used := s.FilterByUsed(vols, true)
153
+	if len(used) != 1 {
154
+		t.Fatalf("expected 1 used volume, got %v", len(used))
155
+	}
156
+	if used[0].Name() != "fake1" {
157
+		t.Fatalf("expected used volume fake1, got %s", used[0].Name())
158
+	}
159
+}