Skip to content

Commit bf8cb43

Browse files
committed
system prune: delegate version check
Move the version-check for pruners to the pruner, which can return a [ErrNotImplemented] error to indicate they won't be run with the API version that's used. This helps separating concerns, and doesn't enforce knowledge about what's supported by each content-type onto the system prune command. [ErrNotImplemented]: https://pkg.go.dev/github.com/docker/docker@v28.3.3+incompatible/errdefs#ErrNotImplemented Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent a888c40 commit bf8cb43

3 files changed

Lines changed: 25 additions & 21 deletions

File tree

cli/command/builder/prune.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/docker/cli/opts"
1515
"github.com/docker/go-units"
1616
"github.com/moby/moby/api/types/build"
17+
"github.com/moby/moby/api/types/versions"
1718
"github.com/spf13/cobra"
1819
)
1920

@@ -112,6 +113,10 @@ type cancelledErr struct{ error }
112113

113114
func (cancelledErr) Cancelled() {}
114115

116+
type errNotImplemented struct{ error }
117+
118+
func (errNotImplemented) NotImplemented() {}
119+
115120
// CachePrune executes a prune command for build cache
116121
//
117122
// Deprecated: this function was only used internally and will be removed in the next release.
@@ -122,6 +127,10 @@ func CachePrune(ctx context.Context, dockerCli command.Cli, all bool, filter opt
122127
// pruneFn prunes the build cache for use in "docker system prune" and
123128
// returns the amount of space reclaimed and a detailed output string.
124129
func pruneFn(ctx context.Context, dockerCLI command.Cli, options pruner.PruneOptions) (uint64, string, error) {
130+
if ver := dockerCLI.Client().ClientVersion(); ver != "" && versions.LessThan(ver, "1.31") {
131+
// Not supported on older daemons.
132+
return 0, "", errNotImplemented{errors.New("builder prune requires API version 1.31 or greater")}
133+
}
125134
if !options.Confirmed {
126135
// Dry-run: perform validation and produce confirmation before pruning.
127136
var confirmMsg string

cli/command/system/prune.go

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,14 @@ import (
1717
"github.com/docker/cli/opts"
1818
"github.com/docker/go-units"
1919
"github.com/fvbommel/sortorder"
20-
"github.com/moby/moby/api/types/versions"
2120
"github.com/spf13/cobra"
2221
)
2322

2423
type pruneOptions struct {
25-
force bool
26-
all bool
27-
pruneVolumes bool
28-
pruneBuildCache bool
29-
filter opts.FilterOpt
24+
force bool
25+
all bool
26+
pruneVolumes bool
27+
filter opts.FilterOpt
3028
}
3129

3230
// newPruneCommand creates a new cobra.Command for `docker prune`
@@ -38,7 +36,6 @@ func newPruneCommand(dockerCli command.Cli) *cobra.Command {
3836
Short: "Remove unused data",
3937
Args: cli.NoArgs,
4038
RunE: func(cmd *cobra.Command, args []string) error {
41-
options.pruneBuildCache = versions.GreaterThanOrEqualTo(dockerCli.Client().ClientVersion(), "1.31")
4239
return runPrune(cmd.Context(), dockerCli, options)
4340
},
4441
Annotations: map[string]string{"version": "1.25"},
@@ -95,11 +92,7 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
9592
if !options.pruneVolumes {
9693
continue
9794
}
98-
case pruner.TypeBuildCache:
99-
if !options.pruneBuildCache {
100-
continue
101-
}
102-
case pruner.TypeContainer, pruner.TypeNetwork, pruner.TypeImage:
95+
case pruner.TypeContainer, pruner.TypeNetwork, pruner.TypeImage, pruner.TypeBuildCache:
10396
// no special handling; keeping the "exhaustive" linter happy.
10497
default:
10598
// other pruners; no special handling; keeping the "exhaustive" linter happy.
@@ -110,7 +103,7 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
110103
All: options.all,
111104
Filter: options.filter,
112105
})
113-
if err != nil {
106+
if err != nil && !errdefs.IsNotImplemented(err) {
114107
return err
115108
}
116109
spaceReclaimed += spc
@@ -141,10 +134,10 @@ func dryRun(ctx context.Context, dockerCli command.Cli, options pruneOptions) (s
141134
if !options.pruneVolumes {
142135
continue
143136
}
144-
case pruner.TypeBuildCache:
145-
if !options.pruneBuildCache {
146-
continue
147-
}
137+
case pruner.TypeContainer, pruner.TypeNetwork, pruner.TypeImage, pruner.TypeBuildCache:
138+
// no special handling; keeping the "exhaustive" linter happy.
139+
default:
140+
// other pruners; no special handling; keeping the "exhaustive" linter happy.
148141
}
149142
// Always run with "[pruner.PruneOptions.Confirmed] = false"
150143
// to perform validation of the given options and produce
@@ -155,7 +148,7 @@ func dryRun(ctx context.Context, dockerCli command.Cli, options pruneOptions) (s
155148
})
156149
// A "canceled" error is expected in dry-run mode; any other error
157150
// must be returned as a "fatal" error.
158-
if err != nil && !errdefs.IsCanceled(err) {
151+
if err != nil && !errdefs.IsCanceled(err) && !errdefs.IsNotImplemented(err) {
159152
errs = append(errs, err)
160153
}
161154
if confirmMsg != "" {

cli/command/system/pruner/pruner.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ var pruneOrder = []ContentType{
5050
// will be pruned (for example, "all stopped containers") instead of
5151
// executing the prune. This summary is presented to the user as a
5252
// confirmation message. It may return a [ErrCancelled] to indicate
53-
// the operation was canceled. Any other error is considered a
54-
// validation error of the given options (such as a filter that
55-
// is not supported.
53+
// the operation was canceled or a [ErrNotImplemented] if the prune
54+
// function is not implemented for the daemon's API version. Any
55+
// other error is considered a validation error for the given options
56+
// (such as a filter that is not supported).
5657
// - If [PruneOptions.Confirmed] is "true", the PruneFunc must execute
5758
// the prune with the given options.
5859
//
@@ -64,6 +65,7 @@ var pruneOrder = []ContentType{
6465
// presented to the user.
6566
//
6667
// [ErrCancelled]: https://pkg.go.dev/github.com/docker/docker@v28.3.3+incompatible/errdefs#ErrCancelled
68+
// [ErrNotImplemented]: https://pkg.go.dev/github.com/docker/docker@v28.3.3+incompatible/errdefs#ErrNotImplemented
6769
type PruneFunc func(ctx context.Context, dockerCLI command.Cli, pruneOpts PruneOptions) (spaceReclaimed uint64, details string, _ error)
6870

6971
type PruneOptions struct {

0 commit comments

Comments
 (0)