Skip to content

Commit f5f69e7

Browse files
committed
Fix filtering in volume prune and ls
Fixes: #26786 Signed-off-by: Šimon Brauner <sbrauner@redhat.com>
1 parent 00012e3 commit f5f69e7

7 files changed

Lines changed: 45 additions & 14 deletions

File tree

docs/source/markdown/options/filter.volume-ls.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@
55
#### **--filter**, **-f**=*filter*
66

77
Filter what volumes are shown in the output.
8-
Multiple filters can be given with multiple uses of the --filter flag.
9-
Filters with the same key work inclusive, with the only exception being `label`
10-
which is exclusive. Filters with different keys always work exclusive.
8+
9+
The *filters* argument format is of `key=value`. If there is more than one *filter*, then pass multiple OPTIONS: **--filter** *foo=bar* **--filter** *bif=baz*.
10+
11+
Filters with different `keys` are combined with `AND`.
12+
Filters with the same `key` are combined with `OR`,
13+
with the only exceptions being `label` and `label!`,
14+
which are combined with `AND`.
1115

1216
Volumes can be filtered by the following attributes:
1317

@@ -23,3 +27,7 @@ Volumes can be filtered by the following attributes:
2327
| scope | Filters volume by scope |
2428
| after/since | Filter by volumes created after the given VOLUME (name or tag) |
2529
| until | Filter by volumes created before given timestamp |
30+
31+
The `label` *filter* accepts two formats. One is the `label`=*key* or `label`=*key*=*value*, which removes volumes with the specified labels. The other format is the `label!`=*key* or `label!`=*key*=*value*, which removes volumes without the specified labels.
32+
33+
The `until` *filter* can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. 10m, 1h30m) computed relative to the machine's time.

docs/source/markdown/podman-volume-prune.1.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ Provide filter values.
2727

2828
The *filters* argument format is of `key=value`. If there is more than one *filter*, then pass multiple OPTIONS: **--filter** *foo=bar* **--filter** *bif=baz*.
2929

30+
Filters with different `keys` are combined with `AND`.
31+
Filters with the same `key` are combined with `OR`,
32+
with the only exceptions being `label` and `label!`,
33+
which are combined with `AND`.
34+
3035
Supported filters:
3136

3237
| Filter | Description |

libpod/runtime_volume.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func (r *Runtime) HasVolume(name string) (bool, error) {
7171
// Volumes retrieves all volumes
7272
// Filters can be provided which will determine which volumes are included in the
7373
// output. If multiple filters are used, a volume will be returned if
74-
// any of the filters are matched
74+
// all of the filters are matched
7575
func (r *Runtime) Volumes(filters ...VolumeFilter) ([]*Volume, error) {
7676
if !r.valid {
7777
return nil, define.ErrRuntimeStopped
@@ -88,9 +88,9 @@ func (r *Runtime) Volumes(filters ...VolumeFilter) ([]*Volume, error) {
8888

8989
volsFiltered := make([]*Volume, 0, len(vols))
9090
for _, vol := range vols {
91-
include := false
91+
include := true
9292
for _, filter := range filters {
93-
include = include || filter(vol)
93+
include = include && filter(vol)
9494
}
9595

9696
if include {

pkg/domain/filters/containers.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo
3232
}, nil
3333
case "label!":
3434
return func(c *libpod.Container) bool {
35-
return !filters.MatchLabelFilters(filterValues, c.Labels())
35+
return filters.MatchNegatedLabelFilters(filterValues, c.Labels())
3636
}, nil
3737
case "name":
3838
// we only have to match one name
@@ -309,7 +309,7 @@ func GeneratePruneContainerFilterFuncs(filter string, filterValues []string, _ *
309309
}, nil
310310
case "label!":
311311
return func(c *libpod.Container) bool {
312-
return !filters.MatchLabelFilters(filterValues, c.Labels())
312+
return filters.MatchNegatedLabelFilters(filterValues, c.Labels())
313313
}, nil
314314
case "until":
315315
return prepareUntilFilterFunc(filterValues)
@@ -478,7 +478,11 @@ func GenerateExternalContainerFilterFuncs(filter string, filterValues []string,
478478
}, nil
479479
case "label":
480480
return func(listContainer *types.ListContainer) bool {
481-
return !filters.MatchLabelFilters(filterValues, listContainer.Labels)
481+
return filters.MatchLabelFilters(filterValues, listContainer.Labels)
482+
}, nil
483+
case "label!":
484+
return func(listContainer *types.ListContainer) bool {
485+
return filters.MatchNegatedLabelFilters(filterValues, listContainer.Labels)
482486
}, nil
483487
case "pod":
484488
var pods []*libpod.Pod

pkg/domain/filters/pods.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
122122
case "label!":
123123
return func(p *libpod.Pod) bool {
124124
labels := p.Labels()
125-
return !filters.MatchLabelFilters(filterValues, labels)
125+
return filters.MatchNegatedLabelFilters(filterValues, labels)
126126
}, nil
127127
case "until":
128128
return func(p *libpod.Pod) bool {

pkg/domain/filters/volumes.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func GenerateVolumeFilters(filter string, filterValues []string, runtime *libpod
3535
}, nil
3636
case "label!":
3737
return func(v *libpod.Volume) bool {
38-
return !filters.MatchLabelFilters(filterValues, v.Labels())
38+
return filters.MatchNegatedLabelFilters(filterValues, v.Labels())
3939
}, nil
4040
case "opt":
4141
return func(v *libpod.Volume) bool {
@@ -101,7 +101,7 @@ func GeneratePruneVolumeFilters(filter string, filterValues []string, runtime *l
101101
}, nil
102102
case "label!":
103103
return func(v *libpod.Volume) bool {
104-
return !filters.MatchLabelFilters(filterValues, v.Labels())
104+
return filters.MatchNegatedLabelFilters(filterValues, v.Labels())
105105
}, nil
106106
case "until":
107107
return createUntilFilterVolumeFunction(filterValues)

test/e2e/volume_ls_test.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ var _ = Describe("Podman volume ls", func() {
189189

190190
vol1Name := session.OutputToString()
191191

192-
session = podmanTest.Podman([]string{"volume", "create", "--label", "b=c", "--label", "a=b", "vol2"})
192+
session = podmanTest.Podman([]string{"volume", "create", "--label", "a=b", "--label", "b=c", "--label", "d=e", "vol2"})
193193
session.WaitWithDefaultTimeout()
194194
Expect(session).Should(ExitCleanly())
195195

@@ -208,11 +208,25 @@ var _ = Describe("Podman volume ls", func() {
208208
Expect(session.OutputToStringArray()[0]).To(Equal(vol1Name))
209209
Expect(session.OutputToStringArray()[1]).To(Equal(vol2Name))
210210

211-
session = podmanTest.Podman([]string{"volume", "ls", "-q", "--filter", "label=c=d", "--filter", "label=b=c"})
211+
session = podmanTest.Podman([]string{"volume", "ls", "-q", "--filter", "label=b=c", "--filter", "label=c=d"})
212212
session.WaitWithDefaultTimeout()
213213
Expect(session).Should(ExitCleanly())
214214
Expect(session.OutputToStringArray()).To(HaveLen(1))
215215
Expect(session.OutputToStringArray()[0]).To(Equal(vol3Name))
216+
217+
// Filters with label! key
218+
session = podmanTest.Podman([]string{"volume", "ls", "-q", "--filter", "label!=c=d", "--filter", "label!=d=e"})
219+
session.WaitWithDefaultTimeout()
220+
Expect(session).Should(ExitCleanly())
221+
Expect(session.OutputToStringArray()).To(HaveLen(1))
222+
Expect(session.OutputToStringArray()[0]).To(Equal(vol1Name))
223+
224+
// Filters with different keys
225+
session = podmanTest.Podman([]string{"volume", "ls", "-q", "--filter", "label=b=c", "--filter", "name=vol1"})
226+
session.WaitWithDefaultTimeout()
227+
Expect(session).Should(ExitCleanly())
228+
Expect(session.OutputToStringArray()).To(HaveLen(1))
229+
Expect(session.OutputToStringArray()[0]).To(Equal(vol1Name))
216230
})
217231

218232
It("podman ls volume with --filter since/after", func() {

0 commit comments

Comments
 (0)