From bfc6aeca4acc87899b8eed931e84a7d33b49dae5 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 16 May 2025 19:20:44 +0200 Subject: [PATCH] cli/command/container: define local errors instead of errdefs Signed-off-by: Sebastiaan van Stijn --- cli/command/container/create.go | 3 +-- cli/command/container/errors.go | 31 +++++++++++++++++++++++++++ cli/command/container/opts.go | 17 +++++++-------- cli/command/container/prune.go | 7 ++++-- cli/command/container/restart_test.go | 3 +-- cli/command/container/rm_test.go | 3 +-- cli/command/container/stop_test.go | 3 +-- 7 files changed, 48 insertions(+), 19 deletions(-) create mode 100644 cli/command/container/errors.go diff --git a/cli/command/container/create.go b/cli/command/container/create.go index 0e091b6718..beb11995de 100644 --- a/cli/command/container/create.go +++ b/cli/command/container/create.go @@ -29,7 +29,6 @@ import ( "github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/versions" "github.com/docker/docker/client" - "github.com/docker/docker/errdefs" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -317,7 +316,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c if options.platform != "" && versions.GreaterThanOrEqualTo(dockerCli.Client().ClientVersion(), "1.41") { p, err := platforms.Parse(options.platform) if err != nil { - return "", errors.Wrap(errdefs.InvalidParameter(err), "error parsing specified platform") + return "", errors.Wrap(invalidParameter(err), "error parsing specified platform") } platform = &p } diff --git a/cli/command/container/errors.go b/cli/command/container/errors.go new file mode 100644 index 0000000000..957aa25fa6 --- /dev/null +++ b/cli/command/container/errors.go @@ -0,0 +1,31 @@ +package container + +import cerrdefs "github.com/containerd/errdefs" + +func invalidParameter(err error) error { + if err == nil || cerrdefs.IsInvalidArgument(err) { + return err + } + return invalidParameterErr{err} +} + +type invalidParameterErr struct{ error } + +func (invalidParameterErr) InvalidParameter() {} +func (e invalidParameterErr) Unwrap() error { + return e.error +} + +func notFound(err error) error { + if err == nil || cerrdefs.IsNotFound(err) { + return err + } + return notFoundErr{err} +} + +type notFoundErr struct{ error } + +func (notFoundErr) NotFound() {} +func (e notFoundErr) Unwrap() error { + return e.error +} diff --git a/cli/command/container/opts.go b/cli/command/container/opts.go index 8883271f67..cf9c780623 100644 --- a/cli/command/container/opts.go +++ b/cli/command/container/opts.go @@ -19,7 +19,6 @@ import ( mounttypes "github.com/docker/docker/api/types/mount" networktypes "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/strslice" - "github.com/docker/docker/errdefs" "github.com/docker/go-connections/nat" "github.com/pkg/errors" "github.com/spf13/pflag" @@ -781,7 +780,7 @@ func parseNetworkOpts(copts *containerOptions) (map[string]*networktypes.Endpoin return nil, err } if _, ok := endpoints[n.Target]; ok { - return nil, errdefs.InvalidParameter(errors.Errorf("network %q is specified multiple times", n.Target)) + return nil, invalidParameter(errors.Errorf("network %q is specified multiple times", n.Target)) } // For backward compatibility: if no custom options are provided for the network, @@ -795,7 +794,7 @@ func parseNetworkOpts(copts *containerOptions) (map[string]*networktypes.Endpoin endpoints[n.Target] = ep } if hasUserDefined && hasNonUserDefined { - return nil, errdefs.InvalidParameter(errors.New("conflicting options: cannot attach both user-defined and non-user-defined network-modes")) + return nil, invalidParameter(errors.New("conflicting options: cannot attach both user-defined and non-user-defined network-modes")) } return endpoints, nil } @@ -803,22 +802,22 @@ func parseNetworkOpts(copts *containerOptions) (map[string]*networktypes.Endpoin func applyContainerOptions(n *opts.NetworkAttachmentOpts, copts *containerOptions) error { //nolint:gocyclo // TODO should we error if _any_ advanced option is used? (i.e. forbid to combine advanced notation with the "old" flags (`--network-alias`, `--link`, `--ip`, `--ip6`)? if len(n.Aliases) > 0 && copts.aliases.Len() > 0 { - return errdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --network-alias and per-network alias")) + return invalidParameter(errors.New("conflicting options: cannot specify both --network-alias and per-network alias")) } if len(n.Links) > 0 && copts.links.Len() > 0 { - return errdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --link and per-network links")) + return invalidParameter(errors.New("conflicting options: cannot specify both --link and per-network links")) } if n.IPv4Address != "" && copts.ipv4Address != "" { - return errdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --ip and per-network IPv4 address")) + return invalidParameter(errors.New("conflicting options: cannot specify both --ip and per-network IPv4 address")) } if n.IPv6Address != "" && copts.ipv6Address != "" { - return errdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --ip6 and per-network IPv6 address")) + return invalidParameter(errors.New("conflicting options: cannot specify both --ip6 and per-network IPv6 address")) } if n.MacAddress != "" && copts.macAddress != "" { - return errdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --mac-address and per-network MAC address")) + return invalidParameter(errors.New("conflicting options: cannot specify both --mac-address and per-network MAC address")) } if len(n.LinkLocalIPs) > 0 && copts.linkLocalIPs.Len() > 0 { - return errdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --link-local-ip and per-network link-local IP addresses")) + return invalidParameter(errors.New("conflicting options: cannot specify both --link-local-ip and per-network link-local IP addresses")) } if copts.aliases.Len() > 0 { n.Aliases = make([]string, copts.aliases.Len()) diff --git a/cli/command/container/prune.go b/cli/command/container/prune.go index 74f741a7a7..7a1d575d6e 100644 --- a/cli/command/container/prune.go +++ b/cli/command/container/prune.go @@ -9,7 +9,6 @@ import ( "github.com/docker/cli/cli/command/completion" "github.com/docker/cli/internal/prompt" "github.com/docker/cli/opts" - "github.com/docker/docker/errdefs" units "github.com/docker/go-units" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -62,7 +61,7 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions) return 0, "", err } if !r { - return 0, "", errdefs.Cancelled(errors.New("container prune has been cancelled")) + return 0, "", cancelledErr{errors.New("container prune has been cancelled")} } } @@ -82,6 +81,10 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions) return spaceReclaimed, output, nil } +type cancelledErr struct{ error } + +func (cancelledErr) Cancelled() {} + // RunPrune calls the Container Prune API // This returns the amount of space reclaimed and a detailed output string func RunPrune(ctx context.Context, dockerCli command.Cli, _ bool, filter opts.FilterOpt) (uint64, string, error) { diff --git a/cli/command/container/restart_test.go b/cli/command/container/restart_test.go index a5cdb1cf1b..f7986a8751 100644 --- a/cli/command/container/restart_test.go +++ b/cli/command/container/restart_test.go @@ -10,7 +10,6 @@ import ( "github.com/docker/cli/internal/test" "github.com/docker/docker/api/types/container" - "github.com/docker/docker/errdefs" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) @@ -66,7 +65,7 @@ func TestRestart(t *testing.T) { containerRestartFunc: func(ctx context.Context, containerID string, options container.StopOptions) error { assert.Check(t, is.DeepEqual(options, tc.expectedOpts)) if containerID == "nosuchcontainer" { - return errdefs.NotFound(errors.New("Error: no such container: " + containerID)) + return notFound(errors.New("Error: no such container: " + containerID)) } // TODO(thaJeztah): consider using parallelOperation for restart, similar to "stop" and "remove" diff --git a/cli/command/container/rm_test.go b/cli/command/container/rm_test.go index 505fc7c48b..e9850a9b93 100644 --- a/cli/command/container/rm_test.go +++ b/cli/command/container/rm_test.go @@ -10,7 +10,6 @@ import ( "github.com/docker/cli/internal/test" "github.com/docker/docker/api/types/container" - "github.com/docker/docker/errdefs" "gotest.tools/v3/assert" ) @@ -36,7 +35,7 @@ func TestRemoveForce(t *testing.T) { mutex.Unlock() if container == "nosuchcontainer" { - return errdefs.NotFound(errors.New("Error: no such container: " + container)) + return notFound(errors.New("Error: no such container: " + container)) } return nil }, diff --git a/cli/command/container/stop_test.go b/cli/command/container/stop_test.go index 83a9b706f1..fc2b88c7ac 100644 --- a/cli/command/container/stop_test.go +++ b/cli/command/container/stop_test.go @@ -10,7 +10,6 @@ import ( "github.com/docker/cli/internal/test" "github.com/docker/docker/api/types/container" - "github.com/docker/docker/errdefs" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) @@ -66,7 +65,7 @@ func TestStop(t *testing.T) { containerStopFunc: func(ctx context.Context, containerID string, options container.StopOptions) error { assert.Check(t, is.DeepEqual(options, tc.expectedOpts)) if containerID == "nosuchcontainer" { - return errdefs.NotFound(errors.New("Error: no such container: " + containerID)) + return notFound(errors.New("Error: no such container: " + containerID)) } // containerStopFunc is called in parallel for each container