diff --git a/cli/command/container/create.go b/cli/command/container/create.go index 54e73c9264..0e091b6718 100644 --- a/cli/command/container/create.go +++ b/cli/command/container/create.go @@ -11,6 +11,7 @@ import ( "path" "strings" + cerrdefs "github.com/containerd/errdefs" "github.com/containerd/platforms" "github.com/distribution/reference" "github.com/docker/cli/cli" @@ -342,7 +343,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c response, err := dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, platform, options.name) if err != nil { // Pull image if it does not exist locally and we have the PullImageMissing option. Default behavior. - if errdefs.IsNotFound(err) && namedRef != nil && options.pull == PullImageMissing { + if cerrdefs.IsNotFound(err) && namedRef != nil && options.pull == PullImageMissing { if !options.quiet { // we don't want to write to stdout anything apart from container.ID _, _ = fmt.Fprintf(dockerCli.Err(), "Unable to find image '%s' locally\n", reference.FamiliarString(namedRef)) diff --git a/cli/command/container/rm.go b/cli/command/container/rm.go index 4295f9e382..c36f523a5c 100644 --- a/cli/command/container/rm.go +++ b/cli/command/container/rm.go @@ -6,11 +6,11 @@ import ( "fmt" "strings" + cerrdefs "github.com/containerd/errdefs" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/completion" "github.com/docker/docker/api/types/container" - "github.com/docker/docker/errdefs" "github.com/spf13/cobra" ) @@ -67,7 +67,7 @@ func runRm(ctx context.Context, dockerCLI command.Cli, opts *rmOptions) error { var errs []error for _, name := range opts.containers { if err := <-errChan; err != nil { - if opts.force && errdefs.IsNotFound(err) { + if opts.force && cerrdefs.IsNotFound(err) { _, _ = fmt.Fprintln(dockerCLI.Err(), err) continue } diff --git a/cli/command/context/create.go b/cli/command/context/create.go index e0bc8df83d..9a84546c64 100644 --- a/cli/command/context/create.go +++ b/cli/command/context/create.go @@ -7,13 +7,13 @@ import ( "bytes" "fmt" + cerrdefs "github.com/containerd/errdefs" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/completion" "github.com/docker/cli/cli/command/formatter/tabwriter" "github.com/docker/cli/cli/context/docker" "github.com/docker/cli/cli/context/store" - "github.com/docker/docker/errdefs" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -122,7 +122,7 @@ func checkContextNameForCreation(s store.Reader, name string) error { if err := store.ValidateContextName(name); err != nil { return err } - if _, err := s.GetMetadata(name); !errdefs.IsNotFound(err) { + if _, err := s.GetMetadata(name); !cerrdefs.IsNotFound(err) { if err != nil { return errors.Wrap(err, "error while getting existing contexts") } diff --git a/cli/command/context/remove_test.go b/cli/command/context/remove_test.go index 5f48e740c5..bbcddec6d1 100644 --- a/cli/command/context/remove_test.go +++ b/cli/command/context/remove_test.go @@ -4,9 +4,9 @@ import ( "path/filepath" "testing" + cerrdefs "github.com/containerd/errdefs" "github.com/docker/cli/cli/config" "github.com/docker/cli/cli/config/configfile" - "github.com/docker/docker/errdefs" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) @@ -18,7 +18,7 @@ func TestRemove(t *testing.T) { _, err := cli.ContextStore().GetMetadata("current") assert.NilError(t, err) _, err = cli.ContextStore().GetMetadata("other") - assert.Check(t, is.ErrorType(err, errdefs.IsNotFound)) + assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound)) } func TestRemoveNotAContext(t *testing.T) { diff --git a/cli/command/context/use_test.go b/cli/command/context/use_test.go index 0d95ee2cb3..8c7265dac8 100644 --- a/cli/command/context/use_test.go +++ b/cli/command/context/use_test.go @@ -9,11 +9,11 @@ import ( "runtime" "testing" + cerrdefs "github.com/containerd/errdefs" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/config" "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/flags" - "github.com/docker/docker/errdefs" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) @@ -47,7 +47,7 @@ func TestUse(t *testing.T) { func TestUseNoExist(t *testing.T) { cli := makeFakeCli(t) err := newUseCommand(cli).RunE(nil, []string{"test"}) - assert.Check(t, is.ErrorType(err, errdefs.IsNotFound)) + assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound)) } // TestUseDefaultWithoutConfigFile verifies that the CLI does not create diff --git a/cli/command/defaultcontextstore_test.go b/cli/command/defaultcontextstore_test.go index 2acc1a9015..d0c8d09b75 100644 --- a/cli/command/defaultcontextstore_test.go +++ b/cli/command/defaultcontextstore_test.go @@ -7,11 +7,11 @@ import ( "crypto/rand" "testing" + cerrdefs "github.com/containerd/errdefs" "github.com/docker/cli/cli/config/configfile" "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/docker/go-connections/tlsconfig" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -158,7 +158,7 @@ func TestErrCreateDefault(t *testing.T) { Metadata: testContext{Bar: "baz"}, Name: "default", }) - assert.Check(t, is.ErrorType(err, errdefs.IsInvalidParameter)) + assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument)) assert.Error(t, err, "default context cannot be created nor updated") } @@ -166,7 +166,7 @@ func TestErrRemoveDefault(t *testing.T) { meta := testDefaultMetadata() s := testStore(t, meta, store.ContextTLSData{}) err := s.Remove("default") - assert.Check(t, is.ErrorType(err, errdefs.IsInvalidParameter)) + assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument)) assert.Error(t, err, "default context cannot be removed") } @@ -174,5 +174,5 @@ func TestErrTLSDataError(t *testing.T) { meta := testDefaultMetadata() s := testStore(t, meta, store.ContextTLSData{}) _, err := s.GetTLSData("default", "noop", "noop") - assert.Check(t, is.ErrorType(err, errdefs.IsNotFound)) + assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound)) } diff --git a/cli/command/image/remove.go b/cli/command/image/remove.go index 577772cbcb..f0fa7d3488 100644 --- a/cli/command/image/remove.go +++ b/cli/command/image/remove.go @@ -5,11 +5,11 @@ import ( "errors" "fmt" + cerrdefs "github.com/containerd/errdefs" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/completion" "github.com/docker/docker/api/types/image" - "github.com/docker/docker/errdefs" "github.com/spf13/cobra" ) @@ -64,7 +64,7 @@ func runRemove(ctx context.Context, dockerCLI command.Cli, opts removeOptions, i for _, img := range images { dels, err := apiClient.ImageRemove(ctx, img, options) if err != nil { - if !errdefs.IsNotFound(err) { + if !cerrdefs.IsNotFound(err) { fatalErr = true } errs = append(errs, err) diff --git a/cli/command/network/remove.go b/cli/command/network/remove.go index 86f9ff5e2c..69578a48c0 100644 --- a/cli/command/network/remove.go +++ b/cli/command/network/remove.go @@ -5,12 +5,12 @@ import ( "fmt" "strconv" + cerrdefs "github.com/containerd/errdefs" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/completion" "github.com/docker/cli/internal/prompt" "github.com/docker/docker/api/types/network" - "github.com/docker/docker/errdefs" "github.com/spf13/cobra" ) @@ -59,7 +59,7 @@ func runRemove(ctx context.Context, dockerCLI command.Cli, networks []string, op } } if err := apiClient.NetworkRemove(ctx, name); err != nil { - if opts.force && errdefs.IsNotFound(err) { + if opts.force && cerrdefs.IsNotFound(err) { continue } _, _ = fmt.Fprintln(dockerCLI.Err(), err) diff --git a/cli/command/registry/login.go b/cli/command/registry/login.go index 771cc3270a..ce5e584859 100644 --- a/cli/command/registry/login.go +++ b/cli/command/registry/login.go @@ -8,6 +8,7 @@ import ( "strconv" "strings" + cerrdefs "github.com/containerd/errdefs" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/completion" @@ -17,7 +18,6 @@ import ( "github.com/docker/cli/internal/tui" registrytypes "github.com/docker/docker/api/types/registry" "github.com/docker/docker/client" - "github.com/docker/docker/errdefs" "github.com/docker/docker/registry" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -156,7 +156,7 @@ func loginWithStoredCredentials(ctx context.Context, dockerCLI command.Cli, auth response, err := dockerCLI.Client().RegistryLogin(ctx, authConfig) if err != nil { - if errdefs.IsUnauthorized(err) { + if cerrdefs.IsUnauthorized(err) { _, _ = fmt.Fprintln(dockerCLI.Err(), "Stored credentials invalid or expired") } else { _, _ = fmt.Fprintln(dockerCLI.Err(), "Login did not succeed, error:", err) diff --git a/cli/command/service/inspect.go b/cli/command/service/inspect.go index d096402b50..dd27e91d2c 100644 --- a/cli/command/service/inspect.go +++ b/cli/command/service/inspect.go @@ -7,6 +7,7 @@ import ( "context" "strings" + cerrdefs "github.com/containerd/errdefs" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/completion" @@ -14,7 +15,6 @@ import ( flagsHelper "github.com/docker/cli/cli/flags" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/network" - "github.com/docker/docker/errdefs" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -67,7 +67,7 @@ func runInspect(ctx context.Context, dockerCli command.Cli, opts inspectOptions) getRef := func(ref string) (any, []byte, error) { // Service inspect shows defaults values in empty fields. service, _, err := client.ServiceInspectWithRaw(ctx, ref, types.ServiceInspectOptions{InsertDefaults: true}) - if err == nil || !errdefs.IsNotFound(err) { + if err == nil || !cerrdefs.IsNotFound(err) { return service, nil, err } return nil, nil, errors.Errorf("Error: no such service: %s", ref) @@ -75,7 +75,7 @@ func runInspect(ctx context.Context, dockerCli command.Cli, opts inspectOptions) getNetwork := func(ref string) (any, []byte, error) { nw, _, err := client.NetworkInspectWithRaw(ctx, ref, network.InspectOptions{Scope: "swarm"}) - if err == nil || !errdefs.IsNotFound(err) { + if err == nil || !cerrdefs.IsNotFound(err) { return nw, nil, err } return nil, nil, errors.Errorf("Error: no such network: %s", ref) diff --git a/cli/command/service/logs.go b/cli/command/service/logs.go index 8cad7a575a..9098f2317c 100644 --- a/cli/command/service/logs.go +++ b/cli/command/service/logs.go @@ -9,6 +9,7 @@ import ( "strconv" "strings" + cerrdefs "github.com/containerd/errdefs" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/completion" @@ -18,7 +19,6 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" - "github.com/docker/docker/errdefs" "github.com/docker/docker/pkg/stdcopy" "github.com/docker/docker/pkg/stringid" "github.com/pkg/errors" @@ -94,12 +94,12 @@ func runLogs(ctx context.Context, dockerCli command.Cli, opts *logsOptions) erro service, _, err := apiClient.ServiceInspectWithRaw(ctx, opts.target, types.ServiceInspectOptions{}) if err != nil { // if it's any error other than service not found, it's Real - if !errdefs.IsNotFound(err) { + if !cerrdefs.IsNotFound(err) { return err } task, _, err := apiClient.TaskInspectWithRaw(ctx, opts.target) if err != nil { - if errdefs.IsNotFound(err) { + if cerrdefs.IsNotFound(err) { // if the task isn't found, rewrite the error to be clear // that we looked for services AND tasks and found none err = fmt.Errorf("no such task or service: %v", opts.target) diff --git a/cli/command/stack/swarm/deploy_composefile.go b/cli/command/stack/swarm/deploy_composefile.go index 8ff7b7337e..771df89d58 100644 --- a/cli/command/stack/swarm/deploy_composefile.go +++ b/cli/command/stack/swarm/deploy_composefile.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" + cerrdefs "github.com/containerd/errdefs" "github.com/docker/cli/cli/command" servicecli "github.com/docker/cli/cli/command/service" "github.com/docker/cli/cli/command/stack/options" @@ -15,7 +16,6 @@ import ( "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" - "github.com/docker/docker/errdefs" ) func deployCompose(ctx context.Context, dockerCli command.Cli, opts *options.Deploy, config *composetypes.Config) error { @@ -98,7 +98,7 @@ func validateExternalNetworks(ctx context.Context, apiClient client.NetworkAPICl } nw, err := apiClient.NetworkInspect(ctx, networkName, network.InspectOptions{}) switch { - case errdefs.IsNotFound(err): + case cerrdefs.IsNotFound(err): return fmt.Errorf("network %q is declared as external, but could not be found. You need to create a swarm-scoped network before the stack is deployed", networkName) case err != nil: return err @@ -120,7 +120,7 @@ func createSecrets(ctx context.Context, dockerCLI command.Cli, secrets []swarm.S if err := apiClient.SecretUpdate(ctx, secret.ID, secret.Meta.Version, secretSpec); err != nil { return fmt.Errorf("failed to update secret %s: %w", secretSpec.Name, err) } - case errdefs.IsNotFound(err): + case cerrdefs.IsNotFound(err): // secret does not exist, then we create a new one. _, _ = fmt.Fprintln(dockerCLI.Out(), "Creating secret", secretSpec.Name) if _, err := apiClient.SecretCreate(ctx, secretSpec); err != nil { @@ -144,7 +144,7 @@ func createConfigs(ctx context.Context, dockerCLI command.Cli, configs []swarm.C if err := apiClient.ConfigUpdate(ctx, config.ID, config.Meta.Version, configSpec); err != nil { return fmt.Errorf("failed to update config %s: %w", configSpec.Name, err) } - case errdefs.IsNotFound(err): + case cerrdefs.IsNotFound(err): // config does not exist, then we create a new one. _, _ = fmt.Fprintln(dockerCLI.Out(), "Creating config", configSpec.Name) if _, err := apiClient.ConfigCreate(ctx, configSpec); err != nil { diff --git a/cli/command/system/inspect.go b/cli/command/system/inspect.go index 9cbca4c421..f5340fb01e 100644 --- a/cli/command/system/inspect.go +++ b/cli/command/system/inspect.go @@ -9,6 +9,7 @@ import ( "fmt" "strings" + cerrdefs "github.com/containerd/errdefs" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/completion" @@ -18,7 +19,6 @@ import ( "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/network" "github.com/docker/docker/client" - "github.com/docker/docker/errdefs" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -279,7 +279,7 @@ func inspectAll(ctx context.Context, dockerCLI command.Cli, getSize bool, typeCo } func isErrSkippable(err error) bool { - return errdefs.IsNotFound(err) || + return cerrdefs.IsNotFound(err) || strings.Contains(err.Error(), "not supported") || strings.Contains(err.Error(), "invalid reference format") } diff --git a/cli/context/store/metadata_test.go b/cli/context/store/metadata_test.go index b92ee30276..beaf133d37 100644 --- a/cli/context/store/metadata_test.go +++ b/cli/context/store/metadata_test.go @@ -8,7 +8,7 @@ import ( "path/filepath" "testing" - "github.com/docker/docker/errdefs" + cerrdefs "github.com/containerd/errdefs" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) @@ -26,7 +26,7 @@ func testMetadata(name string) Metadata { func TestMetadataGetNotExisting(t *testing.T) { testee := metadataStore{root: t.TempDir(), config: testCfg} _, err := testee.get("noexist") - assert.ErrorType(t, err, errdefs.IsNotFound) + assert.ErrorType(t, err, cerrdefs.IsNotFound) } func TestMetadataCreateGetRemove(t *testing.T) { @@ -60,7 +60,7 @@ func TestMetadataCreateGetRemove(t *testing.T) { assert.NilError(t, testee.remove("test-context")) assert.NilError(t, testee.remove("test-context")) // support duplicate remove _, err = testee.get("test-context") - assert.ErrorType(t, err, errdefs.IsNotFound) + assert.ErrorType(t, err, cerrdefs.IsNotFound) } func TestMetadataRespectJsonAnnotation(t *testing.T) { diff --git a/cli/context/store/store_test.go b/cli/context/store/store_test.go index c4eaab8606..2d3074783a 100644 --- a/cli/context/store/store_test.go +++ b/cli/context/store/store_test.go @@ -17,7 +17,7 @@ import ( "path/filepath" "testing" - "github.com/docker/docker/errdefs" + cerrdefs "github.com/containerd/errdefs" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) @@ -107,7 +107,7 @@ func TestRemove(t *testing.T) { })) assert.NilError(t, s.Remove("source")) _, err = s.GetMetadata("source") - assert.Check(t, is.ErrorType(err, errdefs.IsNotFound)) + assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound)) f, err := s.ListTLSFiles("source") assert.NilError(t, err) assert.Equal(t, 0, len(f)) @@ -122,7 +122,7 @@ func TestListEmptyStore(t *testing.T) { func TestErrHasCorrectContext(t *testing.T) { _, err := New(t.TempDir(), testCfg).GetMetadata("no-exists") assert.ErrorContains(t, err, "no-exists") - assert.Check(t, is.ErrorType(err, errdefs.IsNotFound)) + assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound)) } func TestDetectImportContentType(t *testing.T) { diff --git a/cli/context/store/tlsstore_test.go b/cli/context/store/tlsstore_test.go index 511ba1d2f3..a6aae68ae0 100644 --- a/cli/context/store/tlsstore_test.go +++ b/cli/context/store/tlsstore_test.go @@ -3,7 +3,7 @@ package store import ( "testing" - "github.com/docker/docker/errdefs" + cerrdefs "github.com/containerd/errdefs" "gotest.tools/v3/assert" ) @@ -13,7 +13,7 @@ func TestTlsCreateUpdateGetRemove(t *testing.T) { const contextName = "test-ctx" _, err := testee.getData(contextName, "test-ep", "test-data") - assert.ErrorType(t, err, errdefs.IsNotFound) + assert.ErrorType(t, err, cerrdefs.IsNotFound) err = testee.createOrUpdate(contextName, "test-ep", "test-data", []byte("data")) assert.NilError(t, err) @@ -29,7 +29,7 @@ func TestTlsCreateUpdateGetRemove(t *testing.T) { err = testee.removeEndpoint(contextName, "test-ep") assert.NilError(t, err) _, err = testee.getData(contextName, "test-ep", "test-data") - assert.ErrorType(t, err, errdefs.IsNotFound) + assert.ErrorType(t, err, cerrdefs.IsNotFound) } func TestTlsListAndBatchRemove(t *testing.T) { diff --git a/cmd/docker/docker.go b/cmd/docker/docker.go index f1f54b98f7..a7dc49c909 100644 --- a/cmd/docker/docker.go +++ b/cmd/docker/docker.go @@ -10,6 +10,7 @@ import ( "strings" "syscall" + cerrdefs "github.com/containerd/errdefs" "github.com/docker/cli/cli" pluginmanager "github.com/docker/cli/cli-plugins/manager" "github.com/docker/cli/cli-plugins/socket" @@ -20,7 +21,6 @@ import ( "github.com/docker/cli/cli/version" platformsignals "github.com/docker/cli/cmd/docker/internal/signals" "github.com/docker/docker/api/types/versions" - "github.com/docker/docker/errdefs" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -41,7 +41,7 @@ func main() { os.Exit(getExitCode(err)) } - if err != nil && !errdefs.IsCancelled(err) { + if err != nil && !cerrdefs.IsCanceled(err) { if err.Error() != "" { _, _ = fmt.Fprintln(os.Stderr, err) } diff --git a/vendor.mod b/vendor.mod index 15b39ed2c4..3d1425eef8 100644 --- a/vendor.mod +++ b/vendor.mod @@ -8,6 +8,7 @@ go 1.23.0 require ( dario.cat/mergo v1.0.1 + github.com/containerd/errdefs v1.0.0 github.com/containerd/platforms v1.0.0-rc.1 github.com/cpuguy83/go-md2man/v2 v2.0.7 github.com/creack/pty v1.1.24 diff --git a/vendor.sum b/vendor.sum index 90ccf06a39..dcedb66a5b 100644 --- a/vendor.sum +++ b/vendor.sum @@ -32,6 +32,8 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= github.com/cloudflare/cfssl v1.6.4 h1:NMOvfrEjFfC63K3SGXgAnFdsgkmiq4kATme5BfcqrO8= github.com/cloudflare/cfssl v1.6.4/go.mod h1:8b3CQMxfWPAeom3zBnGJ6sd+G1NkL5TXqmDXacb+1J0= +github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= +github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/platforms v1.0.0-rc.1 h1:83KIq4yy1erSRgOVHNk1HYdPvzdJ5CnsWaRoJX4C41E= diff --git a/vendor/github.com/containerd/errdefs/LICENSE b/vendor/github.com/containerd/errdefs/LICENSE new file mode 100644 index 0000000000..584149b6ee --- /dev/null +++ b/vendor/github.com/containerd/errdefs/LICENSE @@ -0,0 +1,191 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright The containerd Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/containerd/errdefs/README.md b/vendor/github.com/containerd/errdefs/README.md new file mode 100644 index 0000000000..bd418c63f9 --- /dev/null +++ b/vendor/github.com/containerd/errdefs/README.md @@ -0,0 +1,13 @@ +# errdefs + +A Go package for defining and checking common containerd errors. + +## Project details + +**errdefs** is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE). +As a containerd sub-project, you will find the: + * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md), + * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS), + * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md) + +information in our [`containerd/project`](https://github.com/containerd/project) repository. diff --git a/vendor/github.com/containerd/errdefs/errors.go b/vendor/github.com/containerd/errdefs/errors.go new file mode 100644 index 0000000000..f654d19649 --- /dev/null +++ b/vendor/github.com/containerd/errdefs/errors.go @@ -0,0 +1,443 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Package errdefs defines the common errors used throughout containerd +// packages. +// +// Use with fmt.Errorf to add context to an error. +// +// To detect an error class, use the IsXXX functions to tell whether an error +// is of a certain type. +package errdefs + +import ( + "context" + "errors" +) + +// Definitions of common error types used throughout containerd. All containerd +// errors returned by most packages will map into one of these errors classes. +// Packages should return errors of these types when they want to instruct a +// client to take a particular action. +// +// These errors map closely to grpc errors. +var ( + ErrUnknown = errUnknown{} + ErrInvalidArgument = errInvalidArgument{} + ErrNotFound = errNotFound{} + ErrAlreadyExists = errAlreadyExists{} + ErrPermissionDenied = errPermissionDenied{} + ErrResourceExhausted = errResourceExhausted{} + ErrFailedPrecondition = errFailedPrecondition{} + ErrConflict = errConflict{} + ErrNotModified = errNotModified{} + ErrAborted = errAborted{} + ErrOutOfRange = errOutOfRange{} + ErrNotImplemented = errNotImplemented{} + ErrInternal = errInternal{} + ErrUnavailable = errUnavailable{} + ErrDataLoss = errDataLoss{} + ErrUnauthenticated = errUnauthorized{} +) + +// cancelled maps to Moby's "ErrCancelled" +type cancelled interface { + Cancelled() +} + +// IsCanceled returns true if the error is due to `context.Canceled`. +func IsCanceled(err error) bool { + return errors.Is(err, context.Canceled) || isInterface[cancelled](err) +} + +type errUnknown struct{} + +func (errUnknown) Error() string { return "unknown" } + +func (errUnknown) Unknown() {} + +func (e errUnknown) WithMessage(msg string) error { + return customMessage{e, msg} +} + +// unknown maps to Moby's "ErrUnknown" +type unknown interface { + Unknown() +} + +// IsUnknown returns true if the error is due to an unknown error, +// unhandled condition or unexpected response. +func IsUnknown(err error) bool { + return errors.Is(err, errUnknown{}) || isInterface[unknown](err) +} + +type errInvalidArgument struct{} + +func (errInvalidArgument) Error() string { return "invalid argument" } + +func (errInvalidArgument) InvalidParameter() {} + +func (e errInvalidArgument) WithMessage(msg string) error { + return customMessage{e, msg} +} + +// invalidParameter maps to Moby's "ErrInvalidParameter" +type invalidParameter interface { + InvalidParameter() +} + +// IsInvalidArgument returns true if the error is due to an invalid argument +func IsInvalidArgument(err error) bool { + return errors.Is(err, ErrInvalidArgument) || isInterface[invalidParameter](err) +} + +// deadlineExceed maps to Moby's "ErrDeadline" +type deadlineExceeded interface { + DeadlineExceeded() +} + +// IsDeadlineExceeded returns true if the error is due to +// `context.DeadlineExceeded`. +func IsDeadlineExceeded(err error) bool { + return errors.Is(err, context.DeadlineExceeded) || isInterface[deadlineExceeded](err) +} + +type errNotFound struct{} + +func (errNotFound) Error() string { return "not found" } + +func (errNotFound) NotFound() {} + +func (e errNotFound) WithMessage(msg string) error { + return customMessage{e, msg} +} + +// notFound maps to Moby's "ErrNotFound" +type notFound interface { + NotFound() +} + +// IsNotFound returns true if the error is due to a missing object +func IsNotFound(err error) bool { + return errors.Is(err, ErrNotFound) || isInterface[notFound](err) +} + +type errAlreadyExists struct{} + +func (errAlreadyExists) Error() string { return "already exists" } + +func (errAlreadyExists) AlreadyExists() {} + +func (e errAlreadyExists) WithMessage(msg string) error { + return customMessage{e, msg} +} + +type alreadyExists interface { + AlreadyExists() +} + +// IsAlreadyExists returns true if the error is due to an already existing +// metadata item +func IsAlreadyExists(err error) bool { + return errors.Is(err, ErrAlreadyExists) || isInterface[alreadyExists](err) +} + +type errPermissionDenied struct{} + +func (errPermissionDenied) Error() string { return "permission denied" } + +func (errPermissionDenied) Forbidden() {} + +func (e errPermissionDenied) WithMessage(msg string) error { + return customMessage{e, msg} +} + +// forbidden maps to Moby's "ErrForbidden" +type forbidden interface { + Forbidden() +} + +// IsPermissionDenied returns true if the error is due to permission denied +// or forbidden (403) response +func IsPermissionDenied(err error) bool { + return errors.Is(err, ErrPermissionDenied) || isInterface[forbidden](err) +} + +type errResourceExhausted struct{} + +func (errResourceExhausted) Error() string { return "resource exhausted" } + +func (errResourceExhausted) ResourceExhausted() {} + +func (e errResourceExhausted) WithMessage(msg string) error { + return customMessage{e, msg} +} + +type resourceExhausted interface { + ResourceExhausted() +} + +// IsResourceExhausted returns true if the error is due to +// a lack of resources or too many attempts. +func IsResourceExhausted(err error) bool { + return errors.Is(err, errResourceExhausted{}) || isInterface[resourceExhausted](err) +} + +type errFailedPrecondition struct{} + +func (e errFailedPrecondition) Error() string { return "failed precondition" } + +func (errFailedPrecondition) FailedPrecondition() {} + +func (e errFailedPrecondition) WithMessage(msg string) error { + return customMessage{e, msg} +} + +type failedPrecondition interface { + FailedPrecondition() +} + +// IsFailedPrecondition returns true if an operation could not proceed due to +// the lack of a particular condition +func IsFailedPrecondition(err error) bool { + return errors.Is(err, errFailedPrecondition{}) || isInterface[failedPrecondition](err) +} + +type errConflict struct{} + +func (errConflict) Error() string { return "conflict" } + +func (errConflict) Conflict() {} + +func (e errConflict) WithMessage(msg string) error { + return customMessage{e, msg} +} + +// conflict maps to Moby's "ErrConflict" +type conflict interface { + Conflict() +} + +// IsConflict returns true if an operation could not proceed due to +// a conflict. +func IsConflict(err error) bool { + return errors.Is(err, errConflict{}) || isInterface[conflict](err) +} + +type errNotModified struct{} + +func (errNotModified) Error() string { return "not modified" } + +func (errNotModified) NotModified() {} + +func (e errNotModified) WithMessage(msg string) error { + return customMessage{e, msg} +} + +// notModified maps to Moby's "ErrNotModified" +type notModified interface { + NotModified() +} + +// IsNotModified returns true if an operation could not proceed due +// to an object not modified from a previous state. +func IsNotModified(err error) bool { + return errors.Is(err, errNotModified{}) || isInterface[notModified](err) +} + +type errAborted struct{} + +func (errAborted) Error() string { return "aborted" } + +func (errAborted) Aborted() {} + +func (e errAborted) WithMessage(msg string) error { + return customMessage{e, msg} +} + +type aborted interface { + Aborted() +} + +// IsAborted returns true if an operation was aborted. +func IsAborted(err error) bool { + return errors.Is(err, errAborted{}) || isInterface[aborted](err) +} + +type errOutOfRange struct{} + +func (errOutOfRange) Error() string { return "out of range" } + +func (errOutOfRange) OutOfRange() {} + +func (e errOutOfRange) WithMessage(msg string) error { + return customMessage{e, msg} +} + +type outOfRange interface { + OutOfRange() +} + +// IsOutOfRange returns true if an operation could not proceed due +// to data being out of the expected range. +func IsOutOfRange(err error) bool { + return errors.Is(err, errOutOfRange{}) || isInterface[outOfRange](err) +} + +type errNotImplemented struct{} + +func (errNotImplemented) Error() string { return "not implemented" } + +func (errNotImplemented) NotImplemented() {} + +func (e errNotImplemented) WithMessage(msg string) error { + return customMessage{e, msg} +} + +// notImplemented maps to Moby's "ErrNotImplemented" +type notImplemented interface { + NotImplemented() +} + +// IsNotImplemented returns true if the error is due to not being implemented +func IsNotImplemented(err error) bool { + return errors.Is(err, errNotImplemented{}) || isInterface[notImplemented](err) +} + +type errInternal struct{} + +func (errInternal) Error() string { return "internal" } + +func (errInternal) System() {} + +func (e errInternal) WithMessage(msg string) error { + return customMessage{e, msg} +} + +// system maps to Moby's "ErrSystem" +type system interface { + System() +} + +// IsInternal returns true if the error returns to an internal or system error +func IsInternal(err error) bool { + return errors.Is(err, errInternal{}) || isInterface[system](err) +} + +type errUnavailable struct{} + +func (errUnavailable) Error() string { return "unavailable" } + +func (errUnavailable) Unavailable() {} + +func (e errUnavailable) WithMessage(msg string) error { + return customMessage{e, msg} +} + +// unavailable maps to Moby's "ErrUnavailable" +type unavailable interface { + Unavailable() +} + +// IsUnavailable returns true if the error is due to a resource being unavailable +func IsUnavailable(err error) bool { + return errors.Is(err, errUnavailable{}) || isInterface[unavailable](err) +} + +type errDataLoss struct{} + +func (errDataLoss) Error() string { return "data loss" } + +func (errDataLoss) DataLoss() {} + +func (e errDataLoss) WithMessage(msg string) error { + return customMessage{e, msg} +} + +// dataLoss maps to Moby's "ErrDataLoss" +type dataLoss interface { + DataLoss() +} + +// IsDataLoss returns true if data during an operation was lost or corrupted +func IsDataLoss(err error) bool { + return errors.Is(err, errDataLoss{}) || isInterface[dataLoss](err) +} + +type errUnauthorized struct{} + +func (errUnauthorized) Error() string { return "unauthorized" } + +func (errUnauthorized) Unauthorized() {} + +func (e errUnauthorized) WithMessage(msg string) error { + return customMessage{e, msg} +} + +// unauthorized maps to Moby's "ErrUnauthorized" +type unauthorized interface { + Unauthorized() +} + +// IsUnauthorized returns true if the error indicates that the user was +// unauthenticated or unauthorized. +func IsUnauthorized(err error) bool { + return errors.Is(err, errUnauthorized{}) || isInterface[unauthorized](err) +} + +func isInterface[T any](err error) bool { + for { + switch x := err.(type) { + case T: + return true + case customMessage: + err = x.err + case interface{ Unwrap() error }: + err = x.Unwrap() + if err == nil { + return false + } + case interface{ Unwrap() []error }: + for _, err := range x.Unwrap() { + if isInterface[T](err) { + return true + } + } + return false + default: + return false + } + } +} + +// customMessage is used to provide a defined error with a custom message. +// The message is not wrapped but can be compared by the `Is(error) bool` interface. +type customMessage struct { + err error + msg string +} + +func (c customMessage) Is(err error) bool { + return c.err == err +} + +func (c customMessage) As(target any) bool { + return errors.As(c.err, target) +} + +func (c customMessage) Error() string { + return c.msg +} diff --git a/vendor/github.com/containerd/errdefs/resolve.go b/vendor/github.com/containerd/errdefs/resolve.go new file mode 100644 index 0000000000..c02d4a73f4 --- /dev/null +++ b/vendor/github.com/containerd/errdefs/resolve.go @@ -0,0 +1,147 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package errdefs + +import "context" + +// Resolve returns the first error found in the error chain which matches an +// error defined in this package or context error. A raw, unwrapped error is +// returned or ErrUnknown if no matching error is found. +// +// This is useful for determining a response code based on the outermost wrapped +// error rather than the original cause. For example, a not found error deep +// in the code may be wrapped as an invalid argument. When determining status +// code from Is* functions, the depth or ordering of the error is not +// considered. +// +// The search order is depth first, a wrapped error returned from any part of +// the chain from `Unwrap() error` will be returned before any joined errors +// as returned by `Unwrap() []error`. +func Resolve(err error) error { + if err == nil { + return nil + } + err = firstError(err) + if err == nil { + err = ErrUnknown + } + return err +} + +func firstError(err error) error { + for { + switch err { + case ErrUnknown, + ErrInvalidArgument, + ErrNotFound, + ErrAlreadyExists, + ErrPermissionDenied, + ErrResourceExhausted, + ErrFailedPrecondition, + ErrConflict, + ErrNotModified, + ErrAborted, + ErrOutOfRange, + ErrNotImplemented, + ErrInternal, + ErrUnavailable, + ErrDataLoss, + ErrUnauthenticated, + context.DeadlineExceeded, + context.Canceled: + return err + } + switch e := err.(type) { + case customMessage: + err = e.err + case unknown: + return ErrUnknown + case invalidParameter: + return ErrInvalidArgument + case notFound: + return ErrNotFound + case alreadyExists: + return ErrAlreadyExists + case forbidden: + return ErrPermissionDenied + case resourceExhausted: + return ErrResourceExhausted + case failedPrecondition: + return ErrFailedPrecondition + case conflict: + return ErrConflict + case notModified: + return ErrNotModified + case aborted: + return ErrAborted + case errOutOfRange: + return ErrOutOfRange + case notImplemented: + return ErrNotImplemented + case system: + return ErrInternal + case unavailable: + return ErrUnavailable + case dataLoss: + return ErrDataLoss + case unauthorized: + return ErrUnauthenticated + case deadlineExceeded: + return context.DeadlineExceeded + case cancelled: + return context.Canceled + case interface{ Unwrap() error }: + err = e.Unwrap() + if err == nil { + return nil + } + case interface{ Unwrap() []error }: + for _, ue := range e.Unwrap() { + if fe := firstError(ue); fe != nil { + return fe + } + } + return nil + case interface{ Is(error) bool }: + for _, target := range []error{ErrUnknown, + ErrInvalidArgument, + ErrNotFound, + ErrAlreadyExists, + ErrPermissionDenied, + ErrResourceExhausted, + ErrFailedPrecondition, + ErrConflict, + ErrNotModified, + ErrAborted, + ErrOutOfRange, + ErrNotImplemented, + ErrInternal, + ErrUnavailable, + ErrDataLoss, + ErrUnauthenticated, + context.DeadlineExceeded, + context.Canceled} { + if e.Is(target) { + return target + } + } + return nil + default: + return nil + } + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index df9c3a3fa6..18b52a027b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -21,6 +21,9 @@ github.com/cenkalti/backoff/v4 # github.com/cespare/xxhash/v2 v2.3.0 ## explicit; go 1.11 github.com/cespare/xxhash/v2 +# github.com/containerd/errdefs v1.0.0 +## explicit; go 1.20 +github.com/containerd/errdefs # github.com/containerd/log v0.1.0 ## explicit; go 1.20 github.com/containerd/log