Skip to content

Commit

Permalink
Add support for volume prune until filter to http api
Browse files Browse the repository at this point in the history
As stated in #10579 docker silently implements until filter for volume prune.
This commit adds initial support to the HTTP API, both libpod and compat.
It enables further work on that issue, such as adding cli support in the future.

Signed-off-by: Jakub Guzik <[email protected]>
  • Loading branch information
jmguzik committed Jun 22, 2021
1 parent 1b27234 commit a0b24de
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 9 deletions.
6 changes: 4 additions & 2 deletions pkg/api/server/register_volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
// description: |
// JSON encoded value of filters (a map[string][]string) to match volumes against before pruning.
// Available filters:
// - label (label=<key>, label=<key>=<value>, label!=<key>, or label!=<key>=<value>) Prune volumes with (or without, in case label!=... is used) the specified labels.
// - `until=<timestamp>` Prune volumes created before this timestamp. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon machine’s time.
// - `label` (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or `label!=<key>=<value>`) Prune volumes with (or without, in case `label!=...` is used) the specified labels.
// responses:
// '200':
// "$ref": "#/responses/VolumePruneResponse"
Expand Down Expand Up @@ -268,7 +269,8 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error {
// description: |
// JSON encoded value of filters (a map[string][]string) to match volumes against before pruning.
// Available filters:
// - label (label=<key>, label=<key>=<value>, label!=<key>, or label!=<key>=<value>) Prune volumes with (or without, in case label!=... is used) the specified labels.
// - `until=<timestamp>` Prune volumes created before this timestamp. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon machine’s time.
// - `label` (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or `label!=<key>=<value>`) Prune volumes with (or without, in case `label!=...` is used) the specified labels.
// responses:
// '200':
// "$ref": "#/responses/DockerVolumePruneResponse"
Expand Down
15 changes: 13 additions & 2 deletions pkg/domain/filters/volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,22 @@ func GeneratePruneVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, erro
var vf []libpod.VolumeFilter
for filter, v := range filters {
for _, val := range v {
filterVal := val
switch filter {
case "label":
filter := val
vf = append(vf, func(v *libpod.Volume) bool {
return util.MatchLabelFilters([]string{filter}, v.Labels())
return util.MatchLabelFilters([]string{filterVal}, v.Labels())
})
case "until":
until, err := util.ComputeUntilTimestamp([]string{filterVal})
if err != nil {
return nil, err
}
vf = append(vf, func(v *libpod.Volume) bool {
if !until.IsZero() && v.CreatedTime().Before(until) {
return true
}
return false
})
default:
return nil, errors.Errorf("%q is an invalid volume filter", filter)
Expand Down
47 changes: 42 additions & 5 deletions test/apiv2/30-volumes.at
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,6 @@ t POST libpod/volumes/prune?filters='{"label":["tes' 500 \
t POST libpod/volumes/prune?filters='{"label":["testlabel"]}' 200
t GET libpod/volumes/json?filters='{"label":["testlabel"]}' 200 length=0

## Prune volumes
t POST libpod/volumes/prune 200
#After prune volumes, there should be no volume existing
t GET libpod/volumes/json 200 length=0

# libpod api: do not use list filters for prune
t POST libpod/volumes/prune?filters='{"name":["anyname"]}' 500 \
.cause="\"name\" is an invalid volume filter"
Expand All @@ -146,4 +141,46 @@ t POST volumes/prune?filters='{"driver":["anydriver"]}' 500 \
t POST volumes/prune?filters='{"scope":["anyscope"]}' 500 \
.cause="\"scope\" is an invalid volume filter"

## Prune volumes using until filter
t POST libpod/volumes/create \
Name=foo5 \
Label='{"testuntil":""}' \
Options='{"type":"tmpfs","o":"nodev,noexec"}}' \
201 \
.Name=foo5 \
.Labels.testuntil="" \
.Options.type=tmpfs \
.Options.o=nodev,noexec

# with date way back in the past, volume should not be deleted
t POST libpod/volumes/prune?filters='{"until":["500000"]}' 200
t GET libpod/volumes/json?filters='{"label":["testuntil"]}' 200 length=1

# with date far in the future, volume should be deleted
t POST libpod/volumes/prune?filters='{"until":["5000000000"]}' 200
t GET libpod/volumes/json?filters='{"label":["testuntil"]}' 200 length=0

t POST libpod/volumes/create \
Name=foo6 \
Label='{"testuntilcompat":""}' \
Options='{"type":"tmpfs","o":"nodev,noexec"}}' \
201 \
.Name=foo6 \
.Labels.testuntilcompat="" \
.Options.type=tmpfs \
.Options.o=nodev,noexec

# with date way back in the past, volume should not be deleted (compat api)
t POST volumes/prune?filters='{"until":["500000"]}' 200
t GET libpod/volumes/json?filters='{"label":["testuntilcompat"]}' 200 length=1

# with date far in the future, volume should be deleted (compat api)
t POST volumes/prune?filters='{"until":["5000000000"]}' 200
t GET libpod/volumes/json?filters='{"label":["testuntilcompat"]}' 200 length=0

## Prune volumes
t POST libpod/volumes/prune 200
#After prune volumes, there should be no volume existing
t GET libpod/volumes/json 200 length=0

# vim: filetype=sh

0 comments on commit a0b24de

Please sign in to comment.