summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pkg/api/server/register_volumes.go6
-rw-r--r--pkg/domain/filters/volumes.go15
-rw-r--r--test/apiv2/30-volumes.at47
3 files changed, 59 insertions, 9 deletions
diff --git a/pkg/api/server/register_volumes.go b/pkg/api/server/register_volumes.go
index e5d6cf195..d58bf0662 100644
--- a/pkg/api/server/register_volumes.go
+++ b/pkg/api/server/register_volumes.go
@@ -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"
@@ -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"
diff --git a/pkg/domain/filters/volumes.go b/pkg/domain/filters/volumes.go
index 9a08adf82..df23c31c0 100644
--- a/pkg/domain/filters/volumes.go
+++ b/pkg/domain/filters/volumes.go
@@ -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)
diff --git a/test/apiv2/30-volumes.at b/test/apiv2/30-volumes.at
index ed606134a..5feceea7b 100644
--- a/test/apiv2/30-volumes.at
+++ b/test/apiv2/30-volumes.at
@@ -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"
@@ -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