Merge pull request #6079 from thaJeztah/less_errdefs

remove uses of github.com/docker/docker/errdefs
This commit is contained in:
Sebastiaan van Stijn 2025-05-16 21:06:21 +02:00 committed by GitHub
commit 0674a0085a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 202 additions and 96 deletions

View File

@ -12,8 +12,7 @@ import (
"github.com/docker/cli/internal/prompt"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types/build"
"github.com/docker/docker/errdefs"
units "github.com/docker/go-units"
"github.com/docker/go-units"
"github.com/spf13/cobra"
)
@ -75,7 +74,7 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
return 0, "", err
}
if !r {
return 0, "", errdefs.Cancelled(errors.New("builder prune has been cancelled"))
return 0, "", cancelledErr{errors.New("builder prune has been cancelled")}
}
}
@ -101,6 +100,10 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
return report.SpaceReclaimed, output, nil
}
type cancelledErr struct{ error }
func (cancelledErr) Cancelled() {}
// CachePrune executes a prune command for build cache
func CachePrune(ctx context.Context, dockerCli command.Cli, all bool, filter opts.FilterOpt) (uint64, string, error) {
return runPrune(ctx, dockerCli, pruneOptions{force: true, all: all, filter: filter})

View File

@ -11,7 +11,6 @@ import (
"github.com/docker/cli/cli/streams"
"github.com/docker/docker/client"
"github.com/docker/docker/errdefs"
"github.com/moby/term"
"github.com/pkg/errors"
)
@ -178,7 +177,7 @@ func withCustomHeadersFromEnv() client.Opt {
csvReader := csv.NewReader(strings.NewReader(value))
fields, err := csvReader.Read()
if err != nil {
return errdefs.InvalidParameter(errors.Errorf(
return invalidParameter(errors.Errorf(
"failed to parse custom headers from %s environment variable: value must be formatted as comma-separated key=value pairs",
envOverrideHTTPHeaders,
))
@ -195,7 +194,7 @@ func withCustomHeadersFromEnv() client.Opt {
k = strings.TrimSpace(k)
if k == "" {
return errdefs.InvalidParameter(errors.Errorf(
return invalidParameter(errors.Errorf(
`failed to set custom headers from %s environment variable: value contains a key=value pair with an empty key: '%s'`,
envOverrideHTTPHeaders, kv,
))
@ -206,7 +205,7 @@ func withCustomHeadersFromEnv() client.Opt {
// from an environment variable with the same name). In the meantime,
// produce an error to prevent users from depending on this.
if !hasValue {
return errdefs.InvalidParameter(errors.Errorf(
return invalidParameter(errors.Errorf(
`failed to set custom headers from %s environment variable: missing "=" in key=value pair: '%s'`,
envOverrideHTTPHeaders, kv,
))

View File

@ -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
}

View File

@ -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
}

View File

@ -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())

View File

@ -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) {

View File

@ -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"

View File

@ -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
},

View File

@ -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

View File

@ -5,6 +5,7 @@ package context
import (
"bytes"
"errors"
"fmt"
cerrdefs "github.com/containerd/errdefs"
@ -14,7 +15,6 @@ import (
"github.com/docker/cli/cli/command/formatter/tabwriter"
"github.com/docker/cli/cli/context/docker"
"github.com/docker/cli/cli/context/store"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@ -91,7 +91,7 @@ func createNewContext(contextStore store.ReaderWriter, o *CreateOptions) error {
}
dockerEP, dockerTLS, err := getDockerEndpointMetadataAndTLS(contextStore, o.Docker)
if err != nil {
return errors.Wrap(err, "unable to create docker endpoint config")
return fmt.Errorf("unable to create docker endpoint config: %w", err)
}
contextMetadata := store.Metadata{
Endpoints: map[string]any{
@ -124,9 +124,9 @@ func checkContextNameForCreation(s store.Reader, name string) error {
}
if _, err := s.GetMetadata(name); !cerrdefs.IsNotFound(err) {
if err != nil {
return errors.Wrap(err, "error while getting existing contexts")
return fmt.Errorf("error while getting existing contexts: %w", err)
}
return errors.Errorf("context %q already exists", name)
return fmt.Errorf("context %q already exists", name)
}
return nil
}

View File

@ -7,7 +7,6 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/errdefs"
"github.com/spf13/cobra"
)
@ -75,9 +74,13 @@ func checkContextExists(dockerCli command.Cli, name string) error {
contextDir := dockerCli.ContextStore().GetStorageInfo(name).MetadataPath
_, err := os.Stat(contextDir)
if os.IsNotExist(err) {
return errdefs.NotFound(fmt.Errorf("context %q does not exist", name))
return notFoundErr{fmt.Errorf("context %q does not exist", name)}
}
// Ignore other errors; if relevant, they will produce an error when
// performing the actual delete.
return nil
}
type notFoundErr struct{ error }
func (notFoundErr) NotFound() {}

View File

@ -9,7 +9,6 @@ import (
"github.com/docker/cli/cli/command/formatter/tabwriter"
"github.com/docker/cli/cli/context/docker"
"github.com/docker/cli/cli/context/store"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@ -77,7 +76,7 @@ func RunUpdate(dockerCLI command.Cli, o *UpdateOptions) error {
if o.Docker != nil {
dockerEP, dockerTLS, err := getDockerEndpointMetadataAndTLS(s, o.Docker)
if err != nil {
return errors.Wrap(err, "unable to create docker endpoint config")
return fmt.Errorf("unable to create docker endpoint config: %w", err)
}
c.Endpoints[docker.DockerEndpoint] = dockerEP
tlsDataToReset[docker.DockerEndpoint] = dockerTLS

View File

@ -7,7 +7,6 @@ import (
"github.com/docker/cli/cli/context/docker"
"github.com/docker/cli/cli/context/store"
cliflags "github.com/docker/cli/cli/flags"
"github.com/docker/docker/errdefs"
"github.com/pkg/errors"
)
@ -117,7 +116,7 @@ func (s *ContextStoreWithDefault) List() ([]store.Metadata, error) {
// CreateOrUpdate is not allowed for the default context and fails
func (s *ContextStoreWithDefault) CreateOrUpdate(meta store.Metadata) error {
if meta.Name == DefaultContextName {
return errdefs.InvalidParameter(errors.New("default context cannot be created nor updated"))
return invalidParameter(errors.New("default context cannot be created nor updated"))
}
return s.Store.CreateOrUpdate(meta)
}
@ -125,7 +124,7 @@ func (s *ContextStoreWithDefault) CreateOrUpdate(meta store.Metadata) error {
// Remove is not allowed for the default context and fails
func (s *ContextStoreWithDefault) Remove(name string) error {
if name == DefaultContextName {
return errdefs.InvalidParameter(errors.New("default context cannot be removed"))
return invalidParameter(errors.New("default context cannot be removed"))
}
return s.Store.Remove(name)
}
@ -145,7 +144,7 @@ func (s *ContextStoreWithDefault) GetMetadata(name string) (store.Metadata, erro
// ResetTLSMaterial is not implemented for default context and fails
func (s *ContextStoreWithDefault) ResetTLSMaterial(name string, data *store.ContextTLSData) error {
if name == DefaultContextName {
return errdefs.InvalidParameter(errors.New("default context cannot be edited"))
return invalidParameter(errors.New("default context cannot be edited"))
}
return s.Store.ResetTLSMaterial(name, data)
}
@ -153,7 +152,7 @@ func (s *ContextStoreWithDefault) ResetTLSMaterial(name string, data *store.Cont
// ResetEndpointTLSMaterial is not implemented for default context and fails
func (s *ContextStoreWithDefault) ResetEndpointTLSMaterial(contextName string, endpointName string, data *store.EndpointTLSData) error {
if contextName == DefaultContextName {
return errdefs.InvalidParameter(errors.New("default context cannot be edited"))
return invalidParameter(errors.New("default context cannot be edited"))
}
return s.Store.ResetEndpointTLSMaterial(contextName, endpointName, data)
}
@ -186,7 +185,7 @@ func (s *ContextStoreWithDefault) GetTLSData(contextName, endpointName, fileName
return nil, err
}
if defaultContext.TLS.Endpoints[endpointName].Files[fileName] == nil {
return nil, errdefs.NotFound(errors.Errorf("TLS data for %s/%s/%s does not exist", DefaultContextName, endpointName, fileName))
return nil, notFound(errors.Errorf("TLS data for %s/%s/%s does not exist", DefaultContextName, endpointName, fileName))
}
return defaultContext.TLS.Endpoints[endpointName].Files[fileName], nil
}

View File

@ -11,8 +11,7 @@ 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/docker/go-units"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@ -76,7 +75,7 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
return 0, "", err
}
if !r {
return 0, "", errdefs.Cancelled(errors.New("image prune has been cancelled"))
return 0, "", cancelledErr{errors.New("image prune has been cancelled")}
}
}
@ -106,6 +105,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 Image Prune API
// This returns the amount of space reclaimed and a detailed output string
func RunPrune(ctx context.Context, dockerCli command.Cli, all bool, filter opts.FilterOpt) (uint64, string, error) {

View File

@ -2,6 +2,7 @@ package network
import (
"context"
"errors"
"fmt"
"io"
"net"
@ -13,7 +14,6 @@ import (
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@ -143,7 +143,7 @@ func runCreate(ctx context.Context, apiClient client.NetworkAPIClient, output io
//nolint:gocyclo
func createIPAMConfig(options ipamOptions) (*network.IPAM, error) {
if len(options.subnets) < len(options.ipRanges) || len(options.subnets) < len(options.gateways) {
return nil, errors.Errorf("every ip-range or gateway must have a corresponding subnet")
return nil, errors.New("every ip-range or gateway must have a corresponding subnet")
}
iData := map[string]*network.IPAMConfig{}
@ -159,7 +159,7 @@ func createIPAMConfig(options ipamOptions) (*network.IPAM, error) {
return nil, err
}
if ok1 || ok2 {
return nil, errors.Errorf("multiple overlapping subnet configuration is not supported")
return nil, errors.New("multiple overlapping subnet configuration is not supported")
}
}
iData[s] = &network.IPAMConfig{Subnet: s, AuxAddress: map[string]string{}}
@ -180,14 +180,14 @@ func createIPAMConfig(options ipamOptions) (*network.IPAM, error) {
continue
}
if iData[s].IPRange != "" {
return nil, errors.Errorf("cannot configure multiple ranges (%s, %s) on the same subnet (%s)", r, iData[s].IPRange, s)
return nil, fmt.Errorf("cannot configure multiple ranges (%s, %s) on the same subnet (%s)", r, iData[s].IPRange, s)
}
d := iData[s]
d.IPRange = r
match = true
}
if !match {
return nil, errors.Errorf("no matching subnet for range %s", r)
return nil, fmt.Errorf("no matching subnet for range %s", r)
}
}
@ -203,14 +203,14 @@ func createIPAMConfig(options ipamOptions) (*network.IPAM, error) {
continue
}
if iData[s].Gateway != "" {
return nil, errors.Errorf("cannot configure multiple gateways (%s, %s) for the same subnet (%s)", g, iData[s].Gateway, s)
return nil, fmt.Errorf("cannot configure multiple gateways (%s, %s) for the same subnet (%s)", g, iData[s].Gateway, s)
}
d := iData[s]
d.Gateway = g
match = true
}
if !match {
return nil, errors.Errorf("no matching subnet for gateway %s", g)
return nil, fmt.Errorf("no matching subnet for gateway %s", g)
}
}
@ -229,7 +229,7 @@ func createIPAMConfig(options ipamOptions) (*network.IPAM, error) {
match = true
}
if !match {
return nil, errors.Errorf("no matching subnet for aux-address %s", aa)
return nil, fmt.Errorf("no matching subnet for aux-address %s", aa)
}
}
@ -250,7 +250,7 @@ func subnetMatches(subnet, data string) (bool, error) {
_, s, err := net.ParseCIDR(subnet)
if err != nil {
return false, errors.Wrap(err, "invalid subnet")
return false, fmt.Errorf("invalid subnet: %w", err)
}
if strings.Contains(data, "/") {

View File

@ -2,14 +2,13 @@ package network
import (
"context"
"errors"
"fmt"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/internal/prompt"
"github.com/docker/cli/opts"
"github.com/docker/docker/errdefs"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@ -58,7 +57,7 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
return "", err
}
if !r {
return "", errdefs.Cancelled(errors.New("network prune has been cancelled"))
return "", cancelledErr{errors.New("network prune has been cancelled")}
}
}
@ -77,6 +76,10 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
return output, nil
}
type cancelledErr struct{ error }
func (cancelledErr) Cancelled() {}
// RunPrune calls the Network 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) {

View File

@ -8,11 +8,18 @@ import (
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/errdefs"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
type forBiddenErr struct{ error }
func (forBiddenErr) Forbidden() {}
type notFoundErr struct{ error }
func (notFoundErr) NotFound() {}
func TestNetworkRemoveForce(t *testing.T) {
tests := []struct {
doc string
@ -68,9 +75,9 @@ func TestNetworkRemoveForce(t *testing.T) {
networkRemoveFunc: func(ctx context.Context, networkID string) error {
switch networkID {
case "no-such-network":
return errdefs.NotFound(errors.New("no such network: no-such-network"))
return notFoundErr{errors.New("no such network: no-such-network")}
case "in-use-network":
return errdefs.Forbidden(errors.New("network is in use"))
return forBiddenErr{errors.New("network is in use")}
case "existing-network":
return nil
default:

View File

@ -10,7 +10,6 @@ import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/internal/jsonstream"
"github.com/docker/cli/internal/prompt"
"github.com/docker/docker/errdefs"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@ -70,7 +69,7 @@ func runUpgrade(ctx context.Context, dockerCLI command.Cli, opts pluginOptions)
return err
}
if !r {
return errdefs.Cancelled(errors.New("plugin upgrade has been cancelled"))
return cancelledErr{errors.New("plugin upgrade has been cancelled")}
}
}
@ -93,3 +92,7 @@ func runUpgrade(ctx context.Context, dockerCLI command.Cli, opts pluginOptions)
_, _ = fmt.Fprintf(dockerCLI.Out(), "Upgraded plugin %s to %s\n", opts.localName, opts.remote) // todo: return proper values from the API for this result
return nil
}
type cancelledErr struct{ error }
func (cancelledErr) Cancelled() {}

View File

@ -18,7 +18,6 @@ import (
"github.com/docker/cli/internal/prompt"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
"github.com/docker/go-units"
"github.com/fvbommel/sortorder"
"github.com/pkg/errors"
@ -83,7 +82,7 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
return err
}
if !r {
return errdefs.Cancelled(errors.New("system prune has been cancelled"))
return cancelledErr{errors.New("system prune has been cancelled")}
}
}
pruneFuncs := []func(ctx context.Context, dockerCli command.Cli, all bool, filter opts.FilterOpt) (uint64, string, error){
@ -115,6 +114,10 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
return nil
}
type cancelledErr struct{ error }
func (cancelledErr) Cancelled() {}
// confirmationMessage constructs a confirmation message that depends on the cli options.
func confirmationMessage(dockerCli command.Cli, options pruneOptions) string {
t := template.Must(template.New("confirmation message").Parse(confirmationTemplate))

View File

@ -9,7 +9,6 @@ import (
"github.com/docker/cli/cli/command/image"
"github.com/docker/cli/cli/trust"
"github.com/docker/cli/internal/prompt"
"github.com/docker/docker/errdefs"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/theupdateframework/notary/client"
@ -50,7 +49,7 @@ func revokeTrust(ctx context.Context, dockerCLI command.Cli, remote string, opti
return err
}
if !deleteRemote {
return errdefs.Cancelled(errors.New("trust revoke has been cancelled"))
return cancelledErr{errors.New("trust revoke has been cancelled")}
}
}
@ -70,6 +69,10 @@ func revokeTrust(ctx context.Context, dockerCLI command.Cli, remote string, opti
return nil
}
type cancelledErr struct{ error }
func (cancelledErr) Cancelled() {}
func revokeSignature(notaryRepo client.Repository, tag string) error {
if tag != "" {
// Revoke signature for the specified tag

View File

@ -151,3 +151,22 @@ func ValidateOutputPathFileMode(fileMode os.FileMode) error {
}
return nil
}
func invalidParameter(err error) error {
return invalidParameterErr{err}
}
type invalidParameterErr struct{ error }
func (invalidParameterErr) InvalidParameter() {}
func notFound(err error) error {
return notFoundErr{err}
}
type notFoundErr struct{ error }
func (notFoundErr) NotFound() {}
func (e notFoundErr) Unwrap() error {
return e.error
}

View File

@ -2,6 +2,7 @@ package volume
import (
"context"
"errors"
"fmt"
"sort"
"strings"
@ -11,7 +12,6 @@ import (
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types/volume"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
@ -52,7 +52,7 @@ func newCreateCommand(dockerCli command.Cli) *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 1 {
if options.name != "" {
return errors.Errorf("conflicting options: cannot specify a volume-name through both --name and as a positional arg")
return errors.New("conflicting options: cannot specify a volume-name through both --name and as a positional arg")
}
options.name = args[0]
}

View File

@ -2,6 +2,7 @@ package volume
import (
"context"
"errors"
"fmt"
"github.com/docker/cli/cli"
@ -10,9 +11,7 @@ import (
"github.com/docker/cli/internal/prompt"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types/versions"
"github.com/docker/docker/errdefs"
units "github.com/docker/go-units"
"github.com/pkg/errors"
"github.com/docker/go-units"
"github.com/spf13/cobra"
)
@ -68,7 +67,7 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
if versions.GreaterThanOrEqualTo(dockerCli.CurrentVersion(), "1.42") {
if options.all {
if pruneFilters.Contains("all") {
return 0, "", errdefs.InvalidParameter(errors.New("conflicting options: cannot specify both --all and --filter all=1"))
return 0, "", invalidParamErr{errors.New("conflicting options: cannot specify both --all and --filter all=1")}
}
pruneFilters.Add("all", "true")
warning = allVolumesWarning
@ -83,7 +82,7 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
return 0, "", err
}
if !r {
return 0, "", errdefs.Cancelled(errors.New("volume prune has been cancelled"))
return 0, "", cancelledErr{errors.New("volume prune has been cancelled")}
}
}
@ -103,6 +102,14 @@ func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions)
return spaceReclaimed, output, nil
}
type invalidParamErr struct{ error }
func (invalidParamErr) InvalidParameter() {}
type cancelledErr struct{ error }
func (cancelledErr) Cancelled() {}
// RunPrune calls the Volume 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) {

View File

@ -2,12 +2,12 @@ package volume
import (
"context"
"errors"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/docker/api/types/volume"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
@ -50,7 +50,7 @@ func runUpdate(ctx context.Context, dockerCli command.Cli, volumeID, availabilit
}
if vol.ClusterVolume == nil {
return errors.New("Can only update cluster volumes")
return errors.New("can only update cluster volumes")
}
if flags.Changed("availability") {

View File

@ -0,0 +1,28 @@
package store
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 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
}

View File

@ -5,16 +5,15 @@ package store
import (
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"reflect"
"sort"
"github.com/docker/docker/errdefs"
"github.com/fvbommel/sortorder"
"github.com/moby/sys/atomicwriter"
"github.com/pkg/errors"
)
const (
@ -64,7 +63,7 @@ func parseTypedOrMap(payload []byte, getter TypeGetter) (any, error) {
func (s *metadataStore) get(name string) (Metadata, error) {
m, err := s.getByID(contextdirOf(name))
if err != nil {
return m, errors.Wrapf(err, "context %q", name)
return m, fmt.Errorf("context %q: %w", name, err)
}
return m, nil
}
@ -74,7 +73,7 @@ func (s *metadataStore) getByID(id contextdir) (Metadata, error) {
bytes, err := os.ReadFile(fileName)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return Metadata{}, errdefs.NotFound(errors.Wrap(err, "context not found"))
return Metadata{}, notFound(fmt.Errorf("context not found: %w", err))
}
return Metadata{}, err
}
@ -99,7 +98,7 @@ func (s *metadataStore) getByID(id contextdir) (Metadata, error) {
func (s *metadataStore) remove(name string) error {
if err := os.RemoveAll(s.contextDir(contextdirOf(name))); err != nil {
return errors.Wrapf(err, "failed to remove metadata")
return fmt.Errorf("failed to remove metadata: %w", err)
}
return nil
}
@ -119,7 +118,7 @@ func (s *metadataStore) list() ([]Metadata, error) {
if errors.Is(err, os.ErrNotExist) {
continue
}
return nil, errors.Wrap(err, "failed to read metadata")
return nil, fmt.Errorf("failed to read metadata: %w", err)
}
res = append(res, c)
}

View File

@ -10,6 +10,8 @@ import (
"bytes"
_ "crypto/sha256" // ensure ids can be computed
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"path"
@ -17,9 +19,7 @@ import (
"strings"
"github.com/docker/cli/internal/lazyregexp"
"github.com/docker/docker/errdefs"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
)
const restrictedNamePattern = "^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$"
@ -146,10 +146,10 @@ func (s *ContextStore) CreateOrUpdate(meta Metadata) error {
// Remove deletes the context with the given name, if found.
func (s *ContextStore) Remove(name string) error {
if err := s.meta.remove(name); err != nil {
return errors.Wrapf(err, "failed to remove context %s", name)
return fmt.Errorf("failed to remove context %s: %w", name, err)
}
if err := s.tls.remove(name); err != nil {
return errors.Wrapf(err, "failed to remove context %s", name)
return fmt.Errorf("failed to remove context %s: %w", name, err)
}
return nil
}
@ -226,7 +226,7 @@ func ValidateContextName(name string) error {
return errors.New(`"default" is a reserved context name`)
}
if !restrictedNameRegEx.MatchString(name) {
return errors.Errorf("context name %q is invalid, names are validated against regexp %q", name, restrictedNamePattern)
return fmt.Errorf("context name %q is invalid, names are validated against regexp %q", name, restrictedNamePattern)
}
return nil
}
@ -374,7 +374,7 @@ func importTar(name string, s Writer, reader io.Reader) error {
continue
}
if err := isValidFilePath(hdr.Name); err != nil {
return errors.Wrap(err, hdr.Name)
return fmt.Errorf("%s: %w", hdr.Name, err)
}
if hdr.Name == metaFile {
data, err := io.ReadAll(tr)
@ -400,7 +400,7 @@ func importTar(name string, s Writer, reader io.Reader) error {
}
}
if !importedMetaFile {
return errdefs.InvalidParameter(errors.New("invalid context: no metadata found"))
return invalidParameter(errors.New("invalid context: no metadata found"))
}
return s.ResetTLSMaterial(name, &tlsData)
}
@ -426,7 +426,7 @@ func importZip(name string, s Writer, reader io.Reader) error {
continue
}
if err := isValidFilePath(zf.Name); err != nil {
return errors.Wrap(err, zf.Name)
return fmt.Errorf("%s: %w", zf.Name, err)
}
if zf.Name == metaFile {
f, err := zf.Open()
@ -464,7 +464,7 @@ func importZip(name string, s Writer, reader io.Reader) error {
}
}
if !importedMetaFile {
return errdefs.InvalidParameter(errors.New("invalid context: no metadata found"))
return invalidParameter(errors.New("invalid context: no metadata found"))
}
return s.ResetTLSMaterial(name, &tlsData)
}

View File

@ -1,12 +1,11 @@
package store
import (
"fmt"
"os"
"path/filepath"
"github.com/docker/docker/errdefs"
"github.com/moby/sys/atomicwriter"
"github.com/pkg/errors"
)
const tlsDir = "tls"
@ -39,9 +38,9 @@ func (s *tlsStore) getData(name, endpointName, filename string) ([]byte, error)
data, err := os.ReadFile(filepath.Join(s.endpointDir(name, endpointName), filename))
if err != nil {
if os.IsNotExist(err) {
return nil, errdefs.NotFound(errors.Errorf("TLS data for %s/%s/%s does not exist", name, endpointName, filename))
return nil, notFound(fmt.Errorf("TLS data for %s/%s/%s does not exist", name, endpointName, filename))
}
return nil, errors.Wrapf(err, "failed to read TLS data for endpoint %s", endpointName)
return nil, fmt.Errorf("failed to read TLS data for endpoint %s: %w", endpointName, err)
}
return data, nil
}
@ -49,14 +48,14 @@ func (s *tlsStore) getData(name, endpointName, filename string) ([]byte, error)
// remove deletes all TLS data for the given context.
func (s *tlsStore) remove(name string) error {
if err := os.RemoveAll(s.contextDir(name)); err != nil {
return errors.Wrapf(err, "failed to remove TLS data")
return fmt.Errorf("failed to remove TLS data: %w", err)
}
return nil
}
func (s *tlsStore) removeEndpoint(name, endpointName string) error {
if err := os.RemoveAll(s.endpointDir(name, endpointName)); err != nil {
return errors.Wrapf(err, "failed to remove TLS data for endpoint %s", endpointName)
return fmt.Errorf("failed to remove TLS data for endpoint %s: %w", endpointName, err)
}
return nil
}
@ -68,7 +67,7 @@ func (s *tlsStore) listContextData(name string) (map[string]EndpointFiles, error
if os.IsNotExist(err) {
return map[string]EndpointFiles{}, nil
}
return nil, errors.Wrapf(err, "failed to list TLS files for context %s", name)
return nil, fmt.Errorf("failed to list TLS files for context %s: %w", name, err)
}
r := make(map[string]EndpointFiles)
for _, epFS := range epFSs {
@ -78,7 +77,7 @@ func (s *tlsStore) listContextData(name string) (map[string]EndpointFiles, error
continue
}
if err != nil {
return nil, errors.Wrapf(err, "failed to list TLS files for endpoint %s", epFS.Name())
return nil, fmt.Errorf("failed to list TLS files for endpoint %s: %w", epFS.Name(), err)
}
var files EndpointFiles
for _, fs := range fss {