Skip to content

Commit 9a0d945

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 0a6bf95 commit 9a0d945

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"},
@@ -91,11 +88,7 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
9188
if !options.pruneVolumes {
9289
continue
9390
}
94-
case pruner.TypeBuildCache:
95-
if !options.pruneBuildCache {
96-
continue
97-
}
98-
case pruner.TypeContainer, pruner.TypeNetwork, pruner.TypeImage:
91+
case pruner.TypeContainer, pruner.TypeNetwork, pruner.TypeImage, pruner.TypeBuildCache:
9992
// no special handling; keeping the "exhaustive" linter happy.
10093
default:
10194
// other pruners; no special handling; keeping the "exhaustive" linter happy.
@@ -106,7 +99,7 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
10699
All: options.all,
107100
Filter: options.filter,
108101
})
109-
if err != nil {
102+
if err != nil && !errdefs.IsNotImplemented(err) {
110103
return err
111104
}
112105
spaceReclaimed += spc
@@ -137,10 +130,10 @@ func dryRun(ctx context.Context, dockerCli command.Cli, options pruneOptions) (s
137130
if !options.pruneVolumes {
138131
continue
139132
}
140-
case pruner.TypeBuildCache:
141-
if !options.pruneBuildCache {
142-
continue
143-
}
133+
case pruner.TypeContainer, pruner.TypeNetwork, pruner.TypeImage, pruner.TypeBuildCache:
134+
// no special handling; keeping the "exhaustive" linter happy.
135+
default:
136+
// other pruners; no special handling; keeping the "exhaustive" linter happy.
144137
}
145138
// Always run with "[pruner.PruneOptions.Confirmed] = false"
146139
// to perform validation of the given options and produce
@@ -151,7 +144,7 @@ func dryRun(ctx context.Context, dockerCli command.Cli, options pruneOptions) (s
151144
})
152145
// A "canceled" error is expected in dry-run mode; any other error
153146
// must be returned as a "fatal" error.
154-
if err != nil && !errdefs.IsCanceled(err) {
147+
if err != nil && !errdefs.IsCanceled(err) && !errdefs.IsNotImplemented(err) {
155148
errs = append(errs, err)
156149
}
157150
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)