diff --git a/cli/command/system/prune.go b/cli/command/system/prune.go index 51773cce3a38..886b9522e5a7 100644 --- a/cli/command/system/prune.go +++ b/cli/command/system/prune.go @@ -114,7 +114,7 @@ func confirmationMessage(dockerCli command.Cli, options pruneOptions) string { "all networks not used by at least one container", } if options.pruneVolumes { - warnings = append(warnings, "all volumes not used by at least one container") + warnings = append(warnings, "all anonymous volumes not used by at least one container") } if options.all { warnings = append(warnings, "all images without at least one container associated to them") diff --git a/cli/command/volume/prune.go b/cli/command/volume/prune.go index 16fd5508988e..22aaa812107e 100644 --- a/cli/command/volume/prune.go +++ b/cli/command/volume/prune.go @@ -23,7 +23,7 @@ func NewPruneCommand(dockerCli command.Cli) *cobra.Command { cmd := &cobra.Command{ Use: "prune [OPTIONS]", - Short: "Remove all unused local volumes", + Short: "Remove unused local volumes", Args: cli.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { spaceReclaimed, output, err := runPrune(dockerCli, options) @@ -47,13 +47,21 @@ func NewPruneCommand(dockerCli command.Cli) *cobra.Command { return cmd } -const warning = `WARNING! This will remove all local volumes not used by at least one container. +const warning = `WARNING! This will remove all %s local volumes not used by at least one container. Are you sure you want to continue?` func runPrune(dockerCli command.Cli, options pruneOptions) (spaceReclaimed uint64, output string, err error) { pruneFilters := command.PruneFilters(dockerCli, options.filter.Value()) - if !options.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), warning) { + var removed_volumes string + if pruneFilters.Contains("all") && + (pruneFilters.ExactMatch("all", "true") || pruneFilters.ExactMatch("all", "1")) { + removed_volumes = "named and anonymous" + } else { + removed_volumes = "anonymous" + } + + if !options.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), fmt.Sprintf(warning, removed_volumes)) { return 0, "", nil } diff --git a/cli/command/volume/prune_test.go b/cli/command/volume/prune_test.go index 7cfbad66b312..08b6cc88acf0 100644 --- a/cli/command/volume/prune_test.go +++ b/cli/command/volume/prune_test.go @@ -77,6 +77,23 @@ func TestVolumePruneForce(t *testing.T) { } } +func TestVolumePrunePromptAllNo(t *testing.T) { + // FIXME(vdemeester) make it work.. + skip.If(t, runtime.GOOS == "windows", "TODO: fix test on windows") + + for _, input := range []string{"1", "true"} { + cli := test.NewFakeCli(&fakeClient{ + volumePruneFunc: simplePruneFunc, + }) + + cli.SetIn(streams.NewIn(io.NopCloser(strings.NewReader("n")))) + cmd := NewPruneCommand(cli) + cmd.Flags().Set("filter", fmt.Sprintf("all=%s", input)) + assert.NilError(t, cmd.Execute()) + golden.Assert(t, cli.OutBuffer().String(), "volume-prune-all-no.golden") + } +} + func TestVolumePrunePromptYes(t *testing.T) { // FIXME(vdemeester) make it work.. skip.If(t, runtime.GOOS == "windows", "TODO: fix test on windows") diff --git a/cli/command/volume/testdata/volume-prune-all-no.golden b/cli/command/volume/testdata/volume-prune-all-no.golden new file mode 100644 index 000000000000..24cacd385b57 --- /dev/null +++ b/cli/command/volume/testdata/volume-prune-all-no.golden @@ -0,0 +1,2 @@ +WARNING! This will remove all named and anonymous local volumes not used by at least one container. +Are you sure you want to continue? [y/N] Total reclaimed space: 0B diff --git a/cli/command/volume/testdata/volume-prune-no.golden b/cli/command/volume/testdata/volume-prune-no.golden index 710344c36b52..b6018ef653dc 100644 --- a/cli/command/volume/testdata/volume-prune-no.golden +++ b/cli/command/volume/testdata/volume-prune-no.golden @@ -1,2 +1,2 @@ -WARNING! This will remove all local volumes not used by at least one container. +WARNING! This will remove all anonymous local volumes not used by at least one container. Are you sure you want to continue? [y/N] Total reclaimed space: 0B diff --git a/cli/command/volume/testdata/volume-prune-yes.golden b/cli/command/volume/testdata/volume-prune-yes.golden index 54488e2f25d9..0a0f627a66d8 100644 --- a/cli/command/volume/testdata/volume-prune-yes.golden +++ b/cli/command/volume/testdata/volume-prune-yes.golden @@ -1,4 +1,4 @@ -WARNING! This will remove all local volumes not used by at least one container. +WARNING! This will remove all anonymous local volumes not used by at least one container. Are you sure you want to continue? [y/N] Deleted Volumes: foo bar diff --git a/docs/reference/commandline/volume_prune.md b/docs/reference/commandline/volume_prune.md index ea5ffd1e3fca..89f378a5299f 100644 --- a/docs/reference/commandline/volume_prune.md +++ b/docs/reference/commandline/volume_prune.md @@ -15,14 +15,27 @@ Remove all unused local volumes ## Description -Remove all unused local volumes. Unused local volumes are those which are not referenced by any containers +Remove all unused anonymous local volumes. Unused local volumes are those which +are not referenced by any containers. Anonymous volumes have random names and +are created by Docker during container or service creation. + +Named volumes can be also removed using the filter `all=1`. ## Examples ```console $ docker volume prune -WARNING! This will remove all local volumes not used by at least one container. +WARNING! This will remove all anonymous local volumes not used by at least one container. +Are you sure you want to continue? [y/N] y +Deleted Volumes: +07c7bdf3e34ab76d921894c2b834f073721fccfbbcba792aa7648e3a7a664c2e + +Total reclaimed space: 36 B + +$ docker volume prune --filter all=1 + +WARNING! This will remove all anonymous local volumes not used by at least one container. Are you sure you want to continue? [y/N] y Deleted Volumes: 07c7bdf3e34ab76d921894c2b834f073721fccfbbcba792aa7648e3a7a664c2e @@ -39,6 +52,7 @@ than one filter, then pass multiple flags (e.g., `--filter "foo=bar" --filter "b The currently supported filters are: * label (`label=`, `label==`, `label!=`, or `label!==`) - only remove volumes with (or without, in case `label!=...` is used) the specified labels. +* all (`all=0`, `all=1`) - whether named volumes should also be removed. The `label` filter accepts two formats. One is the `label=...` (`label=` or `label==`), which removes volumes with the specified labels. The other