-
Notifications
You must be signed in to change notification settings - Fork 3.1k
volume prune: add dry-run support #28673
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -95,6 +95,12 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error { | |
| // - `anonymous` When true/false, restrict to anonymous or named volumes only. | ||
| // - `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. | ||
| // - in: query | ||
| // name: dryrun | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| // type: boolean | ||
| // required: false | ||
| // default: false | ||
| // description: Show which volumes would be pruned without removing them. | ||
| // responses: | ||
| // '200': | ||
| // "$ref": "#/responses/volumePruneLibpod" | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ package integration | |
| import ( | ||
| . "github.com/onsi/ginkgo/v2" | ||
| . "github.com/onsi/gomega" | ||
| . "go.podman.io/podman/v6/test/utils" | ||
| ) | ||
|
|
||
| var _ = Describe("Podman volume prune", func() { | ||
|
|
@@ -139,4 +140,80 @@ var _ = Describe("Podman volume prune", func() { | |
| Expect(session.OutputToStringArray()).To(HaveLen(1)) | ||
| Expect(session.OutputToStringArray()[0]).To(Equal(vol1)) | ||
| }) | ||
|
|
||
| It("podman volume prune --all --dry-run", func() { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would like to see also other tests for example:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Honny1 Before adding the test code, I would like to share the results I observed in my remote environment. ## case 1: --dry-run without --all
$ podman volume prune --dry-run
Volumes that would be pruned:
## case 2: --dry-run combined with --force
$ podman volume prune --force --all --dry-run
Volumes that would be pruned:
vol1
validatepr-gocache
validatepr-gomodcache
validatepr-lintcache
validatepr-precommitcache
$ podman volume ls
DRIVER VOLUME NAME
local vol1
local validatepr-gocache
local validatepr-gomodcache
local validatepr-lintcache
local validatepr-precommitcache
## case 3: Negative test for volumes in use
$ podman run -d --name testctr -v vol1:/data alpine sleep 1000
$ podman volume prune --all --dry-run
Volumes that would be pruned:
validatepr-gocache
validatepr-gomodcache
validatepr-lintcache
validatepr-precommitcache
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not forget to create also anonymous volumes. |
||
| vol1 := "vol1" | ||
| vol2 := "vol2" | ||
|
|
||
| podmanTest.PodmanExitCleanly("volume", "create", vol1) | ||
| podmanTest.PodmanExitCleanly("volume", "create", vol2) | ||
|
|
||
| session := podmanTest.PodmanExitCleanly("volume", "prune", "--all", "--dry-run") | ||
| Expect(session.OutputToString()).To(ContainSubstring("Volumes that would be pruned:")) | ||
| Expect(session.OutputToString()).To(ContainSubstring(vol1)) | ||
| Expect(session.OutputToString()).To(ContainSubstring(vol2)) | ||
|
|
||
| session = podmanTest.PodmanExitCleanly("volume", "ls", "-q") | ||
| Expect(session.OutputToStringArray()).To(HaveLen(2)) | ||
| Expect(session.OutputToString()).To(ContainSubstring(vol1)) | ||
| Expect(session.OutputToString()).To(ContainSubstring(vol2)) | ||
| }) | ||
|
|
||
| It("podman volume prune --filter --dry-run", func() { | ||
| vol1 := "vol1" | ||
| vol2 := "vol2" | ||
|
|
||
| podmanTest.PodmanExitCleanly("volume", "create", "--label", "dryrun=true", vol1) | ||
| podmanTest.PodmanExitCleanly("volume", "create", "--label", "dryrun=false", vol2) | ||
|
|
||
| session := podmanTest.PodmanExitCleanly("volume", "prune", "--dry-run", "--filter", "label=dryrun=true") | ||
| Expect(session.OutputToString()).To(ContainSubstring("Volumes that would be pruned:")) | ||
| Expect(session.OutputToString()).To(ContainSubstring(vol1)) | ||
| Expect(session.OutputToString()).ToNot(ContainSubstring(vol2)) | ||
|
|
||
| session = podmanTest.PodmanExitCleanly("volume", "ls", "-q") | ||
| Expect(session.OutputToStringArray()).To(HaveLen(2)) | ||
| Expect(session.OutputToString()).To(ContainSubstring(vol1)) | ||
| Expect(session.OutputToString()).To(ContainSubstring(vol2)) | ||
| }) | ||
|
|
||
| It("podman volume prune --dry-run only shows anonymous volumes", func() { | ||
| vol1 := "vol1" | ||
| anon_vol := podmanTest.PodmanExitCleanly("volume", "create").OutputToString() | ||
| podmanTest.PodmanExitCleanly("volume", "create", vol1) | ||
|
|
||
| session := podmanTest.PodmanExitCleanly("volume", "prune", "--dry-run") | ||
| Expect(session.OutputToString()).To(ContainSubstring("Volumes that would be pruned:")) | ||
| Expect(session.OutputToString()).To(ContainSubstring(anon_vol)) | ||
|
|
||
| session = podmanTest.PodmanExitCleanly("volume", "ls", "-q") | ||
| Expect(session.OutputToStringArray()).To(HaveLen(2)) | ||
| Expect(session.OutputToString()).To(ContainSubstring(vol1)) | ||
| Expect(session.OutputToString()).To(ContainSubstring(anon_vol)) | ||
| }) | ||
|
|
||
| It("podman volume prune --all --dry-run excludes volumes in use", func() { | ||
| vol1 := "vol1" | ||
| vol2 := "vol2" | ||
|
|
||
| podmanTest.PodmanExitCleanly("volume", "create", vol1) | ||
| podmanTest.PodmanExitCleanly("volume", "create", vol2) | ||
| podmanTest.PodmanExitCleanly("create", "-v", "vol2:/data", ALPINE, "ls") | ||
|
|
||
| session := podmanTest.PodmanExitCleanly("volume", "prune", "--all", "--dry-run") | ||
| Expect(session.OutputToString()).To(ContainSubstring("Volumes that would be pruned:")) | ||
| Expect(session.OutputToString()).To(ContainSubstring(vol1)) | ||
| Expect(session.OutputToString()).ToNot(ContainSubstring(vol2)) | ||
|
|
||
| session = podmanTest.PodmanExitCleanly("volume", "ls", "-q") | ||
| Expect(session.OutputToStringArray()).To(HaveLen(2)) | ||
| Expect(session.OutputToString()).To(ContainSubstring(vol1)) | ||
| Expect(session.OutputToString()).To(ContainSubstring(vol2)) | ||
| }) | ||
|
|
||
| It("podman volume prune --force --dry-run fails", func() { | ||
| session := podmanTest.Podman([]string{"volume", "prune", "--force", "--dry-run"}) | ||
| session.WaitWithDefaultTimeout() | ||
| Expect(session).Should(ExitWithError(125, "--force and --dry-run cannot be used together")) | ||
| }) | ||
| }) | ||
Uh oh!
There was an error while loading. Please reload this page.