diff --git a/go.mod b/go.mod index 1028f0940..3388d94d8 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,6 @@ require ( github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 github.com/opencontainers/runtime-tools v0.9.0 github.com/opencontainers/selinux v1.10.1 - github.com/pkg/errors v0.9.1 github.com/pmezard/go-difflib v1.0.0 github.com/seccomp/libseccomp-golang v0.10.0 github.com/sirupsen/logrus v1.8.1 @@ -82,6 +81,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/proglottis/gpgme v0.1.2 // indirect github.com/prometheus/client_golang v1.11.1 // indirect github.com/prometheus/client_model v0.2.0 // indirect diff --git a/libimage/copier.go b/libimage/copier.go index 1cba29143..7570f2633 100644 --- a/libimage/copier.go +++ b/libimage/copier.go @@ -2,6 +2,8 @@ package libimage import ( "context" + "errors" + "fmt" "io" "os" "strings" @@ -17,7 +19,6 @@ import ( storageTransport "github.com/containers/image/v5/storage" "github.com/containers/image/v5/types" encconfig "github.com/containers/ocicrypt/config" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -343,12 +344,12 @@ func (c *copier) copy(ctx context.Context, source, destination types.ImageRefere // Sanity checks for Buildah. if sourceInsecure != nil && *sourceInsecure { if c.systemContext.DockerInsecureSkipTLSVerify == types.OptionalBoolFalse { - return nil, errors.Errorf("can't require tls verification on an insecured registry") + return nil, fmt.Errorf("can't require tls verification on an insecured registry") } } if destinationInsecure != nil && *destinationInsecure { if c.systemContext.DockerInsecureSkipTLSVerify == types.OptionalBoolFalse { - return nil, errors.Errorf("can't require tls verification on an insecured registry") + return nil, fmt.Errorf("can't require tls verification on an insecured registry") } } @@ -402,7 +403,7 @@ func checkRegistrySourcesAllows(dest types.ImageReference) (insecure *bool, err AllowedRegistries []string `json:"allowedRegistries,omitempty"` } if err := json.Unmarshal([]byte(registrySources), &sources); err != nil { - return nil, errors.Wrapf(err, "error parsing $BUILD_REGISTRY_SOURCES (%q) as JSON", registrySources) + return nil, fmt.Errorf("error parsing $BUILD_REGISTRY_SOURCES (%q) as JSON: %w", registrySources, err) } blocked := false if len(sources.BlockedRegistries) > 0 { @@ -413,7 +414,7 @@ func checkRegistrySourcesAllows(dest types.ImageReference) (insecure *bool, err } } if blocked { - return nil, errors.Errorf("registry %q denied by policy: it is in the blocked registries list (%s)", reference.Domain(dref), registrySources) + return nil, fmt.Errorf("registry %q denied by policy: it is in the blocked registries list (%s)", reference.Domain(dref), registrySources) } allowed := true if len(sources.AllowedRegistries) > 0 { @@ -425,7 +426,7 @@ func checkRegistrySourcesAllows(dest types.ImageReference) (insecure *bool, err } } if !allowed { - return nil, errors.Errorf("registry %q denied by policy: not in allowed registries list (%s)", reference.Domain(dref), registrySources) + return nil, fmt.Errorf("registry %q denied by policy: not in allowed registries list (%s)", reference.Domain(dref), registrySources) } for _, inseureDomain := range sources.InsecureRegistries { diff --git a/libimage/filters.go b/libimage/filters.go index f9f73f527..3968c5fdc 100644 --- a/libimage/filters.go +++ b/libimage/filters.go @@ -11,7 +11,6 @@ import ( filtersPkg "github.com/containers/common/pkg/filters" "github.com/containers/common/pkg/timetype" "github.com/containers/image/v5/docker/reference" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -102,7 +101,7 @@ func (r *Runtime) compileImageFilters(ctx context.Context, options *ListImagesOp } else { split = strings.SplitN(f, "=", 2) if len(split) != 2 { - return nil, errors.Errorf("invalid image filter %q: must be in the format %q", f, "filter=value or filter!=value") + return nil, fmt.Errorf("invalid image filter %q: must be in the format %q", f, "filter=value or filter!=value") } } @@ -186,7 +185,7 @@ func (r *Runtime) compileImageFilters(ctx context.Context, options *ListImagesOp filter = filterBefore(until) default: - return nil, errors.Errorf("unsupported image filter %q", key) + return nil, fmt.Errorf("unsupported image filter %q", key) } if negate { filter = negateFilter(filter) @@ -206,7 +205,7 @@ func negateFilter(f filterFunc) filterFunc { func (r *Runtime) containers(duplicate map[string]string, key, value string, externalFunc IsExternalContainerFunc) error { if exists, ok := duplicate[key]; ok && exists != value { - return errors.Errorf("specifying %q filter more than once with different values is not supported", key) + return fmt.Errorf("specifying %q filter more than once with different values is not supported", key) } duplicate[key] = value switch value { @@ -237,19 +236,19 @@ func (r *Runtime) until(value string) (time.Time, error) { func (r *Runtime) time(key, value string) (*Image, error) { img, _, err := r.LookupImage(value, nil) if err != nil { - return nil, errors.Wrapf(err, "could not find local image for filter filter %q=%q", key, value) + return nil, fmt.Errorf("could not find local image for filter filter %q=%q: %w", key, value, err) } return img, nil } func (r *Runtime) bool(duplicate map[string]string, key, value string) (bool, error) { if exists, ok := duplicate[key]; ok && exists != value { - return false, errors.Errorf("specifying %q filter more than once with different values is not supported", key) + return false, fmt.Errorf("specifying %q filter more than once with different values is not supported", key) } duplicate[key] = value set, err := strconv.ParseBool(value) if err != nil { - return false, errors.Wrapf(err, "non-boolean value %q for %s filter", key, value) + return false, fmt.Errorf("non-boolean value %q for %s filter: %w", key, value, err) } return set, nil } diff --git a/libimage/image.go b/libimage/image.go index d7c4fcd51..b1866fa9b 100644 --- a/libimage/image.go +++ b/libimage/image.go @@ -2,6 +2,7 @@ package libimage import ( "context" + "errors" "fmt" "path/filepath" "sort" @@ -16,7 +17,6 @@ import ( "github.com/hashicorp/go-multierror" "github.com/opencontainers/go-digest" ociv1 "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -54,7 +54,7 @@ func (i *Image) reload() error { logrus.Tracef("Reloading image %s", i.ID()) img, err := i.runtime.store.Image(i.ID()) if err != nil { - return errors.Wrap(err, "reloading image") + return fmt.Errorf("reloading image: %w", err) } i.storageImage = img i.cached.imageSource = nil @@ -81,7 +81,7 @@ func (i *Image) isCorrupted(name string) error { if name == "" { name = i.ID()[:12] } - return errors.Errorf("Image %s exists in local storage but may be corrupted (remove the image to resolve the issue): %v", name, err) + return fmt.Errorf("Image %s exists in local storage but may be corrupted (remove the image to resolve the issue): %v", name, err) } return nil } @@ -195,7 +195,7 @@ func (i *Image) Labels(ctx context.Context) (map[string]string, error) { if err != nil { isManifestList, listErr := i.IsManifestList(ctx) if listErr != nil { - err = errors.Wrapf(err, "fallback error checking whether image is a manifest list: %v", err) + err = fmt.Errorf("fallback error checking whether image is a manifest list: %v: %w", err, err) } else if isManifestList { logrus.Debugf("Ignoring error: cannot return labels for manifest list or image index %s", i.ID()) return nil, nil @@ -305,7 +305,7 @@ func (i *Image) removeContainers(options *RemoveImagesOptions) error { for _, cID := range containers { if err := i.runtime.store.DeleteContainer(cID); err != nil { // If the container does not exist anymore, we're good. - if errors.Cause(err) != storage.ErrContainerUnknown { + if !errors.Is(err, storage.ErrContainerUnknown) { multiE = multierror.Append(multiE, err) } } @@ -361,7 +361,7 @@ func (i *Image) removeRecursive(ctx context.Context, rmMap map[string]*RemoveIma logrus.Debugf("Removing image %s", i.ID()) if i.IsReadOnly() { - return processedIDs, errors.Errorf("cannot remove read-only image %q", i.ID()) + return processedIDs, fmt.Errorf("cannot remove read-only image %q", i.ID()) } if i.runtime.eventChannel != nil { @@ -384,15 +384,12 @@ func (i *Image) removeRecursive(ctx context.Context, rmMap map[string]*RemoveIma // have a closer look at the errors. On top, image removal should be // tolerant toward corrupted images. handleError := func(err error) error { - switch errors.Cause(err) { - case storage.ErrImageUnknown, storage.ErrNotAnImage, storage.ErrLayerUnknown: - // The image or layers of the image may already - // have been removed in which case we consider - // the image to be removed. + if errors.Is(err, storage.ErrImageUnknown) || errors.Is(err, storage.ErrNotAnImage) || errors.Is(err, storage.ErrLayerUnknown) { + // The image or layers of the image may already have been removed + // in which case we consider the image to be removed. return nil - default: - return err } + return err } // Calculate the size if requested. `podman-image-prune` likes to @@ -421,11 +418,11 @@ func (i *Image) removeRecursive(ctx context.Context, rmMap map[string]*RemoveIma byDigest := strings.HasPrefix(referencedBy, "sha256:") if !options.Force { if byID && numNames > 1 { - return processedIDs, errors.Errorf("unable to delete image %q by ID with more than one tag (%s): please force removal", i.ID(), i.Names()) + return processedIDs, fmt.Errorf("unable to delete image %q by ID with more than one tag (%s): please force removal", i.ID(), i.Names()) } else if byDigest && numNames > 1 { // FIXME - Docker will remove the digest but containers storage // does not support that yet, so our hands are tied. - return processedIDs, errors.Errorf("unable to delete image %q by digest with more than one tag (%s): please force removal", i.ID(), i.Names()) + return processedIDs, fmt.Errorf("unable to delete image %q by digest with more than one tag (%s): please force removal", i.ID(), i.Names()) } } @@ -509,16 +506,16 @@ var errTagDigest = errors.New("tag by digest not supported") // storage. The name is normalized according to the rules of NormalizeName. func (i *Image) Tag(name string) error { if strings.HasPrefix(name, "sha256:") { // ambiguous input - return errors.Wrap(errTagDigest, name) + return fmt.Errorf("%s: %w", name, errTagDigest) } ref, err := NormalizeName(name) if err != nil { - return errors.Wrapf(err, "normalizing name %q", name) + return fmt.Errorf("normalizing name %q: %w", name, err) } if _, isDigested := ref.(reference.Digested); isDigested { - return errors.Wrap(errTagDigest, name) + return fmt.Errorf("%s: %w", name, errTagDigest) } logrus.Debugf("Tagging image %s with %q", i.ID(), ref.String()) @@ -546,12 +543,12 @@ var errUntagDigest = errors.New("untag by digest not supported") // of NormalizeName. func (i *Image) Untag(name string) error { if strings.HasPrefix(name, "sha256:") { // ambiguous input - return errors.Wrap(errUntagDigest, name) + return fmt.Errorf("%s: %w", name, errUntagDigest) } ref, err := NormalizeName(name) if err != nil { - return errors.Wrapf(err, "normalizing name %q", name) + return fmt.Errorf("normalizing name %q: %w", name, err) } // FIXME: this is breaking Podman CI but must be re-enabled once @@ -560,9 +557,9 @@ func (i *Image) Untag(name string) error { // // !!! Also make sure to re-enable the tests !!! // - // if _, isDigested := ref.(reference.Digested); isDigested { - // return errors.Wrap(errUntagDigest, name) - // } + // if _, isDigested := ref.(reference.Digested); isDigested { + // return fmt.Errorf("%s: %w", name, errUntagDigest) + // } name = ref.String() @@ -582,7 +579,7 @@ func (i *Image) Untag(name string) error { } if !removedName { - return errors.Wrap(errTagUnknown, name) + return fmt.Errorf("%s: %w", name, errTagUnknown) } if err := i.runtime.store.SetNames(i.ID(), newNames); err != nil { @@ -731,7 +728,7 @@ func (i *Image) Mount(ctx context.Context, mountOptions []string, mountLabel str func (i *Image) Mountpoint() (string, error) { mountedTimes, err := i.runtime.store.Mounted(i.TopLayer()) if err != nil || mountedTimes == 0 { - if errors.Cause(err) == storage.ErrLayerUnknown { + if errors.Is(err, storage.ErrLayerUnknown) { // Can happen, Podman did it, but there's no // explanation why. err = nil @@ -943,7 +940,7 @@ func getImageID(ctx context.Context, src types.ImageReference, sys *types.System }() imageDigest := newImg.ConfigInfo().Digest if err = imageDigest.Validate(); err != nil { - return "", errors.Wrapf(err, "getting config info") + return "", fmt.Errorf("getting config info: %w", err) } return "@" + imageDigest.Encoded(), nil } diff --git a/libimage/image_config.go b/libimage/image_config.go index 683a2dc98..b311aa22e 100644 --- a/libimage/image_config.go +++ b/libimage/image_config.go @@ -8,7 +8,6 @@ import ( "github.com/containers/common/pkg/signal" ociv1 "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) // ImageConfig is a wrapper around the OCIv1 Image Configuration struct exported @@ -44,7 +43,7 @@ func ImageConfigFromChanges(changes []string) (*ImageConfig, error) { // nolint: if len(split) != 2 { split = strings.SplitN(change, "=", 2) if len(split) != 2 { - return nil, errors.Errorf("invalid change %q - must be formatted as KEY VALUE", change) + return nil, fmt.Errorf("invalid change %q - must be formatted as KEY VALUE", change) } } @@ -54,7 +53,7 @@ func ImageConfigFromChanges(changes []string) (*ImageConfig, error) { // nolint: case "USER": // Assume literal contents are the user. if value == "" { - return nil, errors.Errorf("invalid change %q - must provide a value to USER", change) + return nil, fmt.Errorf("invalid change %q - must provide a value to USER", change) } config.User = value case "EXPOSE": @@ -63,14 +62,14 @@ func ImageConfigFromChanges(changes []string) (*ImageConfig, error) { // nolint: // Protocol must be "tcp" or "udp" splitPort := strings.Split(value, "/") if len(splitPort) > 2 { - return nil, errors.Errorf("invalid change %q - EXPOSE port must be formatted as PORT[/PROTO]", change) + return nil, fmt.Errorf("invalid change %q - EXPOSE port must be formatted as PORT[/PROTO]", change) } portNum, err := strconv.Atoi(splitPort[0]) if err != nil { - return nil, errors.Wrapf(err, "invalid change %q - EXPOSE port must be an integer", change) + return nil, fmt.Errorf("invalid change %q - EXPOSE port must be an integer: %w", change, err) } if portNum > 65535 || portNum <= 0 { - return nil, errors.Errorf("invalid change %q - EXPOSE port must be a valid port number", change) + return nil, fmt.Errorf("invalid change %q - EXPOSE port must be a valid port number", change) } proto := "tcp" if len(splitPort) > 1 { @@ -79,7 +78,7 @@ func ImageConfigFromChanges(changes []string) (*ImageConfig, error) { // nolint: case "tcp", "udp": proto = testProto default: - return nil, errors.Errorf("invalid change %q - EXPOSE protocol must be TCP or UDP", change) + return nil, fmt.Errorf("invalid change %q - EXPOSE protocol must be TCP or UDP", change) } } if config.ExposedPorts == nil { @@ -101,7 +100,7 @@ func ImageConfigFromChanges(changes []string) (*ImageConfig, error) { // nolint: key = splitEnv[0] // We do need a key if key == "" { - return nil, errors.Errorf("invalid change %q - ENV must have at least one argument", change) + return nil, fmt.Errorf("invalid change %q - ENV must have at least one argument", change) } // Perfectly valid to not have a value if len(splitEnv) == 2 { @@ -163,11 +162,11 @@ func ImageConfigFromChanges(changes []string) (*ImageConfig, error) { // nolint: testUnmarshal = strings.Split(value, " ") } if len(testUnmarshal) == 0 { - return nil, errors.Errorf("invalid change %q - must provide at least one argument to VOLUME", change) + return nil, fmt.Errorf("invalid change %q - must provide at least one argument to VOLUME", change) } for _, vol := range testUnmarshal { if vol == "" { - return nil, errors.Errorf("invalid change %q - VOLUME paths must not be empty", change) + return nil, fmt.Errorf("invalid change %q - VOLUME paths must not be empty", change) } if config.Volumes == nil { config.Volumes = make(map[string]struct{}) @@ -181,7 +180,7 @@ func ImageConfigFromChanges(changes []string) (*ImageConfig, error) { // nolint: // WORKDIR c results in /A/b/c // Just need to check it's not empty... if value == "" { - return nil, errors.Errorf("invalid change %q - must provide a non-empty WORKDIR", change) + return nil, fmt.Errorf("invalid change %q - must provide a non-empty WORKDIR", change) } config.WorkingDir = filepath.Join(config.WorkingDir, value) case "LABEL": @@ -198,7 +197,7 @@ func ImageConfigFromChanges(changes []string) (*ImageConfig, error) { // nolint: splitLabel := strings.SplitN(value, "=", 2) // Unlike ENV, LABEL must have a value if len(splitLabel) != 2 { - return nil, errors.Errorf("invalid change %q - LABEL must be formatted key=value", change) + return nil, fmt.Errorf("invalid change %q - LABEL must be formatted key=value", change) } key = splitLabel[0] val = splitLabel[1] @@ -211,7 +210,7 @@ func ImageConfigFromChanges(changes []string) (*ImageConfig, error) { // nolint: } // Check key after we strip quotations if key == "" { - return nil, errors.Errorf("invalid change %q - LABEL must have a non-empty key", change) + return nil, fmt.Errorf("invalid change %q - LABEL must have a non-empty key", change) } if config.Labels == nil { config.Labels = make(map[string]string) @@ -221,17 +220,17 @@ func ImageConfigFromChanges(changes []string) (*ImageConfig, error) { // nolint: // Check the provided signal for validity. killSignal, err := signal.ParseSignal(value) if err != nil { - return nil, errors.Wrapf(err, "invalid change %q - KILLSIGNAL must be given a valid signal", change) + return nil, fmt.Errorf("invalid change %q - KILLSIGNAL must be given a valid signal: %w", change, err) } config.StopSignal = fmt.Sprintf("%d", killSignal) case "ONBUILD": // Onbuild always appends. if value == "" { - return nil, errors.Errorf("invalid change %q - ONBUILD must be given an argument", change) + return nil, fmt.Errorf("invalid change %q - ONBUILD must be given an argument", change) } config.OnBuild = append(config.OnBuild, value) default: - return nil, errors.Errorf("invalid change %q - invalid instruction %s", change, outerKey) + return nil, fmt.Errorf("invalid change %q - invalid instruction %s", change, outerKey) } } diff --git a/libimage/image_test.go b/libimage/image_test.go index c01b33542..c22cec6bc 100644 --- a/libimage/image_test.go +++ b/libimage/image_test.go @@ -2,12 +2,12 @@ package libimage import ( "context" + "errors" "os" "testing" "github.com/containers/common/pkg/config" "github.com/containers/image/v5/transports/alltransports" - "github.com/pkg/errors" "github.com/stretchr/testify/require" ) @@ -73,7 +73,7 @@ func TestImageFunctions(t *testing.T) { for _, digest := range digests { _, err := runtime.LookupManifestList(busybox + "@" + digest.String()) require.Error(t, err, "Manifest lookup should fail on an ordinary image") - require.Equal(t, ErrNotAManifestList, errors.Cause(err)) + require.True(t, errors.Is(err, ErrNotAManifestList)) } // Below mostly smoke tests. @@ -250,7 +250,7 @@ func TestTag(t *testing.T) { // Check for specific error. err = image.Tag("foo@" + digest) - require.True(t, errors.Cause(err) == errTagDigest, "check for specific digest error") + require.True(t, errors.Is(err, errTagDigest), "check for specific digest error") } func TestUntag(t *testing.T) { @@ -303,5 +303,5 @@ func TestUntag(t *testing.T) { // Check for specific error. err = image.Untag(digest) - require.True(t, errors.Cause(err) == errUntagDigest, "check for specific digest error") + require.True(t, errors.Is(err, errUntagDigest), "check for specific digest error") } diff --git a/libimage/import.go b/libimage/import.go index 3db392784..f557db626 100644 --- a/libimage/import.go +++ b/libimage/import.go @@ -2,6 +2,7 @@ package libimage import ( "context" + "errors" "fmt" "net/url" "os" @@ -10,7 +11,6 @@ import ( storageTransport "github.com/containers/image/v5/storage" tarballTransport "github.com/containers/image/v5/tarball" v1 "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -117,7 +117,7 @@ func (r *Runtime) Import(ctx context.Context, path string, options *ImportOption if options.Tag != "" { image, _, err := r.LookupImage(name, nil) if err != nil { - return "", errors.Wrap(err, "looking up imported image") + return "", fmt.Errorf("looking up imported image: %w", err) } if err := image.Tag(options.Tag); err != nil { return "", err diff --git a/libimage/manifest_list.go b/libimage/manifest_list.go index 4e8959004..ccc5d28c6 100644 --- a/libimage/manifest_list.go +++ b/libimage/manifest_list.go @@ -2,6 +2,7 @@ package libimage import ( "context" + "errors" "fmt" "time" @@ -13,7 +14,6 @@ import ( "github.com/containers/image/v5/types" "github.com/containers/storage" "github.com/opencontainers/go-digest" - "github.com/pkg/errors" ) // NOTE: the abstractions and APIs here are a first step to further merge @@ -145,7 +145,7 @@ func (m *ManifestList) LookupInstance(ctx context.Context, architecture, os, var } } - return nil, errors.Wrapf(storage.ErrImageUnknown, "could not find image instance %s of manifest list %s in local containers storage", instanceDigest, m.ID()) + return nil, fmt.Errorf("could not find image instance %s of manifest list %s in local containers storage: %w", instanceDigest, m.ID(), storage.ErrImageUnknown) } // Saves the specified manifest list and reloads it from storage with the new ID. diff --git a/libimage/manifest_list_test.go b/libimage/manifest_list_test.go index b70a7828b..169dfa5be 100644 --- a/libimage/manifest_list_test.go +++ b/libimage/manifest_list_test.go @@ -2,11 +2,11 @@ package libimage import ( "context" + "errors" "testing" "github.com/containers/common/pkg/config" "github.com/containers/storage" - "github.com/pkg/errors" "github.com/stretchr/testify/require" ) @@ -30,13 +30,13 @@ func TestCreateManifestList(t *testing.T) { _, err = runtime.LookupManifestList("nosuchthing") require.Error(t, err) - require.Equal(t, errors.Cause(err), storage.ErrImageUnknown) + require.True(t, errors.Is(err, storage.ErrImageUnknown)) _, err = runtime.Pull(ctx, "busybox", config.PullPolicyMissing, nil) require.NoError(t, err) _, err = runtime.LookupManifestList("busybox") require.Error(t, err) - require.Equal(t, errors.Cause(err), ErrNotAManifestList) + require.True(t, errors.Is(err, ErrNotAManifestList)) } // Following test ensure that `Tag` tags the manifest list instead of resolved image. diff --git a/libimage/manifests/manifests.go b/libimage/manifests/manifests.go index 2624dee78..8404da9c5 100644 --- a/libimage/manifests/manifests.go +++ b/libimage/manifests/manifests.go @@ -3,7 +3,9 @@ package manifests import ( "context" "encoding/json" + "errors" stderrors "errors" + "fmt" "io" "github.com/containers/common/pkg/manifests" @@ -21,7 +23,6 @@ import ( "github.com/containers/storage/pkg/lockfile" digest "github.com/opencontainers/go-digest" v1 "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -83,11 +84,11 @@ func Create() List { func LoadFromImage(store storage.Store, image string) (string, List, error) { img, err := store.Image(image) if err != nil { - return "", nil, errors.Wrapf(err, "error locating image %q for loading manifest list", image) + return "", nil, fmt.Errorf("error locating image %q for loading manifest list: %w", image, err) } manifestBytes, err := store.ImageBigData(img.ID, storage.ImageDigestManifestBigDataNamePrefix) if err != nil { - return "", nil, errors.Wrapf(err, "error locating image %q for loading manifest list", image) + return "", nil, fmt.Errorf("error locating image %q for loading manifest list: %w", image, err) } manifestList, err := manifests.FromBlob(manifestBytes) if err != nil { @@ -99,10 +100,10 @@ func LoadFromImage(store storage.Store, image string) (string, List, error) { } instancesBytes, err := store.ImageBigData(img.ID, instancesData) if err != nil { - return "", nil, errors.Wrapf(err, "error locating image %q for loading instance list", image) + return "", nil, fmt.Errorf("error locating image %q for loading instance list: %w", image, err) } if err := json.Unmarshal(instancesBytes, &list.instances); err != nil { - return "", nil, errors.Wrapf(err, "error decoding instance list for image %q", image) + return "", nil, fmt.Errorf("error decoding instance list for image %q: %w", image, err) } list.instances[""] = img.ID return img.ID, list, err @@ -122,7 +123,7 @@ func (l *list) SaveToImage(store storage.Store, imageID string, names []string, return "", err } img, err := store.CreateImage(imageID, names, "", "", &storage.ImageOptions{}) - if err == nil || errors.Cause(err) == storage.ErrDuplicateID { + if err == nil || errors.Is(err, storage.ErrDuplicateID) { created := (err == nil) if created { imageID = img.ID @@ -135,7 +136,7 @@ func (l *list) SaveToImage(store storage.Store, imageID string, names []string, logrus.Errorf("Deleting image %q after failing to save manifest for it", img.ID) } } - return "", errors.Wrapf(err, "saving manifest list to image %q", imageID) + return "", fmt.Errorf("saving manifest list to image %q: %w", imageID, err) } err = store.SetImageBigData(imageID, instancesData, instancesBytes, nil) if err != nil { @@ -144,22 +145,22 @@ func (l *list) SaveToImage(store storage.Store, imageID string, names []string, logrus.Errorf("Deleting image %q after failing to save instance locations for it", img.ID) } } - return "", errors.Wrapf(err, "saving instance list to image %q", imageID) + return "", fmt.Errorf("saving instance list to image %q: %w", imageID, err) } return imageID, nil } - return "", errors.Wrapf(err, "error creating image to hold manifest list") + return "", fmt.Errorf("error creating image to hold manifest list: %w", err) } // Reference returns an image reference for the composite image being built // in the list, or an error if the list has never been saved to a local image. func (l *list) Reference(store storage.Store, multiple cp.ImageListSelection, instances []digest.Digest) (types.ImageReference, error) { if l.instances[""] == "" { - return nil, errors.Wrap(ErrListImageUnknown, "error building reference to list") + return nil, fmt.Errorf("error building reference to list: %w", ErrListImageUnknown) } s, err := is.Transport.ParseStoreReference(store, l.instances[""]) if err != nil { - return nil, errors.Wrapf(err, "error creating ImageReference from image %q", l.instances[""]) + return nil, fmt.Errorf("error creating ImageReference from image %q: %w", l.instances[""], err) } references := make([]types.ImageReference, 0, len(l.instances)) whichInstances := make([]digest.Digest, 0, len(l.instances)) @@ -183,7 +184,7 @@ func (l *list) Reference(store storage.Store, multiple cp.ImageListSelection, in imageName := l.instances[instance] ref, err := alltransports.ParseImageName(imageName) if err != nil { - return nil, errors.Wrapf(err, "error creating ImageReference from image %q", imageName) + return nil, fmt.Errorf("error creating ImageReference from image %q: %w", imageName, err) } references = append(references, ref) } @@ -195,7 +196,7 @@ func (l *list) Push(ctx context.Context, dest types.ImageReference, options Push // Load the system signing policy. pushPolicy, err := signature.DefaultPolicy(options.SystemContext) if err != nil { - return nil, "", errors.Wrapf(err, "error obtaining default signature policy") + return nil, "", fmt.Errorf("error obtaining default signature policy: %w", err) } // Override the settings for local storage to make sure that we can always read the source "image". @@ -203,7 +204,7 @@ func (l *list) Push(ctx context.Context, dest types.ImageReference, options Push policyContext, err := signature.NewPolicyContext(pushPolicy) if err != nil { - return nil, "", errors.Wrapf(err, "error creating new signature policy context") + return nil, "", fmt.Errorf("error creating new signature policy context: %w", err) } defer func() { if err2 := policyContext.Destroy(); err2 != nil { @@ -266,7 +267,7 @@ func (l *list) Push(ctx context.Context, dest types.ImageReference, options Push func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.ImageReference, all bool) (digest.Digest, error) { src, err := ref.NewImageSource(ctx, sys) if err != nil { - return "", errors.Wrapf(err, "error setting up to read manifest and configuration from %q", transports.ImageName(ref)) + return "", fmt.Errorf("error setting up to read manifest and configuration from %q: %w", transports.ImageName(ref), err) } defer src.Close() @@ -281,13 +282,13 @@ func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.Imag primaryManifestBytes, primaryManifestType, err := src.GetManifest(ctx, nil) if err != nil { - return "", errors.Wrapf(err, "error reading manifest from %q", transports.ImageName(ref)) + return "", fmt.Errorf("error reading manifest from %q: %w", transports.ImageName(ref), err) } if manifest.MIMETypeIsMultiImage(primaryManifestType) { lists, err := manifests.FromBlob(primaryManifestBytes) if err != nil { - return "", errors.Wrapf(err, "error parsing manifest list in %q", transports.ImageName(ref)) + return "", fmt.Errorf("error parsing manifest list in %q: %w", transports.ImageName(ref), err) } if all { for i, instance := range lists.OCIv1().Manifests { @@ -311,11 +312,11 @@ func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.Imag } else { list, err := manifest.ListFromBlob(primaryManifestBytes, primaryManifestType) if err != nil { - return "", errors.Wrapf(err, "error parsing manifest list in %q", transports.ImageName(ref)) + return "", fmt.Errorf("error parsing manifest list in %q: %w", transports.ImageName(ref), err) } instanceDigest, err := list.ChooseInstance(sys) if err != nil { - return "", errors.Wrapf(err, "error selecting image from manifest list in %q", transports.ImageName(ref)) + return "", fmt.Errorf("error selecting image from manifest list in %q: %w", transports.ImageName(ref), err) } added := false for i, instance := range lists.OCIv1().Manifests { @@ -357,11 +358,11 @@ func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.Imag if instanceInfo.OS == "" || instanceInfo.Architecture == "" { img, err := image.FromUnparsedImage(ctx, sys, image.UnparsedInstance(src, instanceInfo.instanceDigest)) if err != nil { - return "", errors.Wrapf(err, "error reading configuration blob from %q", transports.ImageName(ref)) + return "", fmt.Errorf("error reading configuration blob from %q: %w", transports.ImageName(ref), err) } config, err := img.OCIConfig(ctx) if err != nil { - return "", errors.Wrapf(err, "error reading info about config blob from %q", transports.ImageName(ref)) + return "", fmt.Errorf("error reading info about config blob from %q: %w", transports.ImageName(ref), err) } if instanceInfo.OS == "" { instanceInfo.OS = config.OS @@ -375,12 +376,12 @@ func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.Imag } manifestBytes, manifestType, err := src.GetManifest(ctx, instanceInfo.instanceDigest) if err != nil { - return "", errors.Wrapf(err, "error reading manifest from %q, instance %q", transports.ImageName(ref), instanceInfo.instanceDigest) + return "", fmt.Errorf("error reading manifest from %q, instance %q: %w", transports.ImageName(ref), instanceInfo.instanceDigest, err) } if instanceInfo.instanceDigest == nil { manifestDigest, err = manifest.Digest(manifestBytes) if err != nil { - return "", errors.Wrapf(err, "error computing digest of manifest from %q", transports.ImageName(ref)) + return "", fmt.Errorf("error computing digest of manifest from %q: %w", transports.ImageName(ref), err) } instanceInfo.instanceDigest = &manifestDigest instanceInfo.Size = int64(len(manifestBytes)) @@ -389,7 +390,7 @@ func (l *list) Add(ctx context.Context, sys *types.SystemContext, ref types.Imag } err = l.List.AddInstance(*instanceInfo.instanceDigest, instanceInfo.Size, manifestType, instanceInfo.OS, instanceInfo.Architecture, instanceInfo.OSVersion, instanceInfo.OSFeatures, instanceInfo.Variant, instanceInfo.Features, instanceInfo.Annotations) if err != nil { - return "", errors.Wrapf(err, "error adding instance with digest %q", *instanceInfo.instanceDigest) + return "", fmt.Errorf("error adding instance with digest %q: %w", *instanceInfo.instanceDigest, err) } if _, ok := l.instances[*instanceInfo.instanceDigest]; !ok { l.instances[*instanceInfo.instanceDigest] = transports.ImageName(ref) @@ -416,11 +417,11 @@ func (l *list) Remove(instanceDigest digest.Digest) error { func LockerForImage(store storage.Store, image string) (lockfile.Locker, error) { img, err := store.Image(image) if err != nil { - return nil, errors.Wrapf(err, "locating image %q for locating lock", image) + return nil, fmt.Errorf("locating image %q for locating lock: %w", image, err) } d := digest.NewDigestFromEncoded(digest.Canonical, img.ID) if err := d.Validate(); err != nil { - return nil, errors.Wrapf(err, "coercing image ID for %q into a digest", image) + return nil, fmt.Errorf("coercing image ID for %q into a digest: %w", image, err) } return store.GetDigestLock(d) } diff --git a/libimage/normalize.go b/libimage/normalize.go index 7af125283..be2d30206 100644 --- a/libimage/normalize.go +++ b/libimage/normalize.go @@ -1,10 +1,10 @@ package libimage import ( + "fmt" "strings" "github.com/containers/image/v5/docker/reference" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -18,12 +18,12 @@ func NormalizeName(name string) (reference.Named, error) { // NOTE: this code is in symmetrie with containers/image/pkg/shortnames. ref, err := reference.Parse(name) if err != nil { - return nil, errors.Wrapf(err, "error normalizing name %q", name) + return nil, fmt.Errorf("error normalizing name %q: %w", name, err) } named, ok := ref.(reference.Named) if !ok { - return nil, errors.Errorf("%q is not a named reference", name) + return nil, fmt.Errorf("%q is not a named reference", name) } // Enforce "localhost" if needed. diff --git a/libimage/pull.go b/libimage/pull.go index 2071cceca..86c9ebef1 100644 --- a/libimage/pull.go +++ b/libimage/pull.go @@ -2,6 +2,7 @@ package libimage import ( "context" + "errors" "fmt" "io" "runtime" @@ -23,7 +24,6 @@ import ( "github.com/containers/storage" digest "github.com/opencontainers/go-digest" ociSpec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -74,7 +74,7 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP // In fact, we need to since they are not parseable. if strings.HasPrefix(name, "sha256:") || (len(name) == 64 && !strings.ContainsAny(name, "/.:@")) { if pullPolicy == config.PullPolicyAlways { - return nil, errors.Errorf("pull policy is always but image has been referred to by ID (%s)", name) + return nil, fmt.Errorf("pull policy is always but image has been referred to by ID (%s)", name) } local, _, err := r.LookupImage(name, nil) if err != nil { @@ -113,7 +113,7 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP } if options.AllTags && ref.Transport().Name() != registryTransport.Transport.Name() { - return nil, errors.Errorf("pulling all tags is not supported for %s transport", ref.Transport().Name()) + return nil, fmt.Errorf("pulling all tags is not supported for %s transport", ref.Transport().Name()) } if r.eventChannel != nil { @@ -163,7 +163,7 @@ func (r *Runtime) Pull(ctx context.Context, name string, pullPolicy config.PullP for _, name := range pulledImages { image, _, err := r.LookupImage(name, nil) if err != nil { - return nil, errors.Wrapf(err, "error locating pulled image %q name in containers storage", name) + return nil, fmt.Errorf("error locating pulled image %q name in containers storage: %w", name, err) } // Note that we can ignore the 2nd return value here. Some @@ -258,7 +258,7 @@ func (r *Runtime) copyFromDefault(ctx context.Context, ref types.ImageReference, storageName = ref.StringWithinTransport() named := ref.DockerReference() if named == nil { - return nil, errors.Errorf("could not get an image name for storage reference %q", ref) + return nil, fmt.Errorf("could not get an image name for storage reference %q", ref) } imageName = named.String() @@ -276,7 +276,7 @@ func (r *Runtime) copyFromDefault(ctx context.Context, ref types.ImageReference, // Create a storage reference. destRef, err := storageTransport.Transport.ParseStoreReference(r.store, storageName) if err != nil { - return nil, errors.Wrapf(err, "parsing %q", storageName) + return nil, fmt.Errorf("parsing %q: %w", storageName, err) } _, err = c.copy(ctx, ref, destRef) @@ -318,7 +318,7 @@ func (r *Runtime) storageReferencesReferencesFromArchiveReader(ctx context.Conte for _, destName := range destNames { destRef, err := storageTransport.Transport.ParseStoreReference(r.store, destName) if err != nil { - return nil, nil, errors.Wrapf(err, "error parsing dest reference name %#v", destName) + return nil, nil, fmt.Errorf("error parsing dest reference name %#v: %w", destName, err) } references = append(references, destRef) } @@ -393,13 +393,13 @@ func (r *Runtime) copyFromRegistry(ctx context.Context, ref types.ImageReference for _, tag := range tags { select { // Let's be gentle with Podman remote. case <-ctx.Done(): - return nil, errors.Errorf("pulling cancelled") + return nil, fmt.Errorf("pulling cancelled") default: // We can continue. } tagged, err := reference.WithTag(named, tag) if err != nil { - return nil, errors.Wrapf(err, "error creating tagged reference (name %s, tag %s)", named.String(), tag) + return nil, fmt.Errorf("error creating tagged reference (name %s, tag %s): %w", named.String(), tag, err) } pulled, err := r.copySingleImageFromRegistry(ctx, tagged.String(), pullPolicy, options) if err != nil { @@ -423,30 +423,30 @@ func (r *Runtime) imagesIDsForManifest(manifestBytes []byte, sys *types.SystemCo if manifest.MIMETypeIsMultiImage(manifestType) { list, err := manifest.ListFromBlob(manifestBytes, manifestType) if err != nil { - return nil, errors.Wrapf(err, "parsing manifest list") + return nil, fmt.Errorf("parsing manifest list: %w", err) } d, err := list.ChooseInstance(sys) if err != nil { - return nil, errors.Wrapf(err, "choosing instance from manifest list") + return nil, fmt.Errorf("choosing instance from manifest list: %w", err) } imageDigest = d } else { d, err := manifest.Digest(manifestBytes) if err != nil { - return nil, errors.Wrapf(err, "digesting manifest") + return nil, fmt.Errorf("digesting manifest") } imageDigest = d } images, err := r.store.ImagesByDigest(imageDigest) if err != nil { - return nil, errors.Wrapf(err, "listing images by manifest digest") + return nil, fmt.Errorf("listing images by manifest digest: %w", err) } results := make([]string, 0, len(images)) for _, image := range images { results = append(results, image.ID) } if len(results) == 0 { - return nil, errors.Wrapf(storage.ErrImageUnknown, "identifying new image by manifest digest") + return nil, fmt.Errorf("identifying new image by manifest digest: %w", storage.ErrImageUnknown) } return results, nil } @@ -483,7 +483,7 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str lookupImageOptions.OS = options.OS } localImage, resolvedImageName, err = r.LookupImage(imageName, lookupImageOptions) - if err != nil && errors.Cause(err) != storage.ErrImageUnknown { + if err != nil && !errors.Is(err, storage.ErrImageUnknown) { logrus.Errorf("Looking up %s in local storage: %v", imageName, err) } @@ -515,7 +515,7 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str return []string{resolvedImageName}, nil } logrus.Debugf("Pull policy %q but no local image has been found for %s", pullPolicy, imageName) - return nil, errors.Wrap(storage.ErrImageUnknown, imageName) + return nil, fmt.Errorf("%s: %w", imageName, storage.ErrImageUnknown) } if pullPolicy == config.PullPolicyMissing && localImage != nil { @@ -526,7 +526,7 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str if localImage != nil && strings.HasPrefix(localImage.ID(), imageName) { switch pullPolicy { case config.PullPolicyAlways: - return nil, errors.Errorf("pull policy is always but image has been referred to by ID (%s)", imageName) + return nil, fmt.Errorf("pull policy is always but image has been referred to by ID (%s)", imageName) default: return []string{resolvedImageName}, nil } @@ -648,7 +648,7 @@ func (r *Runtime) copySingleImageFromRegistry(ctx context.Context, imageName str } if len(pullErrors) == 0 { - return nil, errors.Errorf("internal error: no image pulled (pull policy %s)", pullPolicy) + return nil, fmt.Errorf("internal error: no image pulled (pull policy %s)", pullPolicy) } return nil, resolved.FormatPullErrors(pullErrors) diff --git a/libimage/runtime.go b/libimage/runtime.go index 7e975b81d..6030a179b 100644 --- a/libimage/runtime.go +++ b/libimage/runtime.go @@ -2,6 +2,7 @@ package libimage import ( "context" + "errors" "fmt" "os" "strings" @@ -15,7 +16,6 @@ import ( "github.com/containers/storage" deepcopy "github.com/jinzhu/copier" jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -160,7 +160,7 @@ func (r *Runtime) storageToImage(storageImage *storage.Image, ref types.ImageRef // storage. Note that it may return false if an image corrupted. func (r *Runtime) Exists(name string) (bool, error) { image, _, err := r.LookupImage(name, nil) - if err != nil && errors.Cause(err) != storage.ErrImageUnknown { + if err != nil && !errors.Is(err, storage.ErrImageUnknown) { return false, err } if image == nil { @@ -227,7 +227,7 @@ func (r *Runtime) LookupImage(name string, options *LookupImageOptions) (*Image, storageRef, err := alltransports.ParseImageName(name) if err == nil { if storageRef.Transport().Name() != storageTransport.Transport.Name() { - return nil, "", errors.Errorf("unsupported transport %q for looking up local images", storageRef.Transport().Name()) + return nil, "", fmt.Errorf("unsupported transport %q for looking up local images", storageRef.Transport().Name()) } img, err := storageTransport.Transport.GetStoreImage(r.store, storageRef) if err != nil { @@ -266,7 +266,7 @@ func (r *Runtime) LookupImage(name string, options *LookupImageOptions) (*Image, if img != nil { return img, originalName, nil } - return nil, "", errors.Wrap(storage.ErrImageUnknown, originalName) + return nil, "", fmt.Errorf("%s: %w", originalName, storage.ErrImageUnknown) } // Unless specified, set the platform specified in the system context @@ -288,7 +288,7 @@ func (r *Runtime) LookupImage(name string, options *LookupImageOptions) (*Image, // "localhost/" prefixed images into account as well. candidates, err := shortnames.ResolveLocally(&r.systemContext, name) if err != nil { - return nil, "", errors.Wrap(storage.ErrImageUnknown, name) + return nil, "", fmt.Errorf("%s: %w", name, storage.ErrImageUnknown) } // Backwards compat: normalize to docker.io as some users may very well // rely on that. @@ -324,7 +324,7 @@ func (r *Runtime) LookupImage(name string, options *LookupImageOptions) (*Image, func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *LookupImageOptions) (*Image, error) { logrus.Debugf("Trying %q ...", candidate) img, err := r.store.Image(candidate) - if err != nil && errors.Cause(err) != storage.ErrImageUnknown { + if err != nil && !errors.Is(err, storage.ErrImageUnknown) { return nil, err } if img == nil { @@ -342,7 +342,7 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *Loo // find a matching instance in the local containers storage. isManifestList, err := image.IsManifestList(context.Background()) if err != nil { - if errors.Cause(err) == os.ErrNotExist { + if errors.Is(err, os.ErrNotExist) { // We must be tolerant toward corrupted images. // See containers/podman commit fd9dd7065d44. logrus.Warnf("Failed to determine if an image is a manifest list: %v, ignoring the error", err) @@ -356,7 +356,7 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *Loo } // return ErrNotAManifestList if lookupManifest is set otherwise try resolving image. if options.lookupManifest { - return nil, errors.Wrapf(ErrNotAManifestList, candidate) + return nil, fmt.Errorf("%s: %w", candidate, ErrNotAManifestList) } } @@ -372,7 +372,7 @@ func (r *Runtime) lookupImageInLocalStorage(name, candidate string, options *Loo logrus.Debug("No matching instance was found: returning manifest list instead") return image, nil } - return nil, errors.Wrap(storage.ErrImageUnknown, err.Error()) + return nil, fmt.Errorf("%v: %w", err, storage.ErrImageUnknown) } ref, err = storageTransport.Transport.ParseStoreReference(r.store, "@"+instance.ID()) if err != nil { @@ -434,7 +434,7 @@ func (r *Runtime) lookupImageInDigestsAndRepoTags(name string, options *LookupIm } named, isNamed := ref.(reference.Named) if !isNamed { - return nil, "", errors.Wrap(storage.ErrImageUnknown, name) + return nil, "", fmt.Errorf("%s: %w", name, storage.ErrImageUnknown) } digested, isDigested := named.(reference.Digested) @@ -454,11 +454,11 @@ func (r *Runtime) lookupImageInDigestsAndRepoTags(name string, options *LookupIm } } - return nil, "", errors.Wrap(storage.ErrImageUnknown, name) + return nil, "", fmt.Errorf("%s: %w", name, storage.ErrImageUnknown) } if !shortnames.IsShortName(name) { - return nil, "", errors.Wrap(storage.ErrImageUnknown, name) + return nil, "", fmt.Errorf("%s: %w", name, storage.ErrImageUnknown) } named = reference.TagNameOnly(named) // Make sure to add ":latest" if needed @@ -486,7 +486,7 @@ func (r *Runtime) lookupImageInDigestsAndRepoTags(name string, options *LookupIm } } - return nil, "", errors.Wrap(storage.ErrImageUnknown, name) + return nil, "", fmt.Errorf("%s: %w", name, storage.ErrImageUnknown) } // ResolveName resolves the specified name. If the name resolves to a local @@ -499,7 +499,7 @@ func (r *Runtime) ResolveName(name string) (string, error) { return "", nil } image, resolvedName, err := r.LookupImage(name, nil) - if err != nil && errors.Cause(err) != storage.ErrImageUnknown { + if err != nil && !errors.Is(err, storage.ErrImageUnknown) { return "", err } @@ -713,7 +713,7 @@ func (r *Runtime) RemoveImages(ctx context.Context, names []string, options *Rem for _, id := range toDelete { del, exists := deleteMap[id] if !exists { - appendError(errors.Errorf("internal error: ID %s not in found in image-deletion map", id)) + appendError(fmt.Errorf("internal error: ID %s not in found in image-deletion map", id)) continue } if len(del.referencedBy) == 0 { diff --git a/libimage/save.go b/libimage/save.go index fed86d4ef..a42bbb497 100644 --- a/libimage/save.go +++ b/libimage/save.go @@ -2,6 +2,8 @@ package libimage import ( "context" + "errors" + "fmt" "strings" "time" @@ -13,7 +15,6 @@ import ( ociTransport "github.com/containers/image/v5/oci/layout" "github.com/containers/image/v5/types" ociv1 "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -47,10 +48,10 @@ func (r *Runtime) Save(ctx context.Context, names []string, format, path string, // All formats support saving 1. default: if format != "docker-archive" { - return errors.Errorf("unsupported format %q for saving multiple images (only docker-archive)", format) + return fmt.Errorf("unsupported format %q for saving multiple images (only docker-archive)", format) } if len(options.AdditionalTags) > 0 { - return errors.Errorf("cannot save multiple images with multiple tags") + return fmt.Errorf("cannot save multiple images with multiple tags") } } @@ -58,7 +59,7 @@ func (r *Runtime) Save(ctx context.Context, names []string, format, path string, switch format { case "oci-archive", "oci-dir", "docker-dir": if len(names) > 1 { - return errors.Errorf("%q does not support saving multiple images (%v)", format, names) + return fmt.Errorf("%q does not support saving multiple images (%v)", format, names) } return r.saveSingleImage(ctx, names[0], format, path, options) @@ -67,7 +68,7 @@ func (r *Runtime) Save(ctx context.Context, names []string, format, path string, return r.saveDockerArchive(ctx, names, path, options) } - return errors.Errorf("unsupported format %q for saving images", format) + return fmt.Errorf("unsupported format %q for saving images", format) } // saveSingleImage saves the specified image name to the specified path. @@ -109,7 +110,7 @@ func (r *Runtime) saveSingleImage(ctx context.Context, name, format, path string options.ManifestMIMEType = manifest.DockerV2Schema2MediaType default: - return errors.Errorf("unsupported format %q for saving images", format) + return fmt.Errorf("unsupported format %q for saving images", format) } if err != nil { @@ -143,7 +144,7 @@ func (r *Runtime) saveDockerArchive(ctx context.Context, names []string, path st if err == nil { tagged, withTag := named.(reference.NamedTagged) if !withTag { - return errors.Errorf("invalid additional tag %q: normalized to untagged %q", tag, named.String()) + return fmt.Errorf("invalid additional tag %q: normalized to untagged %q", tag, named.String()) } additionalTags = append(additionalTags, tagged) } @@ -195,7 +196,7 @@ func (r *Runtime) saveDockerArchive(ctx context.Context, names []string, path st for _, id := range orderedIDs { local, exists := localImages[id] if !exists { - return errors.Errorf("internal error: saveDockerArchive: ID %s not found in local map", id) + return fmt.Errorf("internal error: saveDockerArchive: ID %s not found in local map", id) } copyOpts := options.CopyOptions diff --git a/libimage/search.go b/libimage/search.go index 204bcc8c7..0b58055b4 100644 --- a/libimage/search.go +++ b/libimage/search.go @@ -13,7 +13,6 @@ import ( "github.com/containers/image/v5/transports/alltransports" "github.com/containers/image/v5/types" "github.com/hashicorp/go-multierror" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sync/semaphore" ) @@ -84,11 +83,11 @@ func ParseSearchFilter(filter []string) (*SearchFilter, error) { switch arr[0] { case define.SearchFilterStars: if len(arr) < 2 { - return nil, errors.Errorf("invalid filter %q, should be stars=", filter) + return nil, fmt.Errorf("invalid filter %q, should be stars=", filter) } stars, err := strconv.Atoi(arr[1]) if err != nil { - return nil, errors.Wrapf(err, "incorrect value type for stars filter") + return nil, fmt.Errorf("incorrect value type for stars filter: %w", err) } sFilter.Stars = stars case define.SearchFilterAutomated: @@ -104,7 +103,7 @@ func ParseSearchFilter(filter []string) (*SearchFilter, error) { sFilter.IsOfficial = types.OptionalBoolTrue } default: - return nil, errors.Errorf("invalid filter type %q", f) + return nil, fmt.Errorf("invalid filter type %q", f) } } return sFilter, nil @@ -273,16 +272,16 @@ func searchRepositoryTags(ctx context.Context, sys *types.SystemContext, registr dockerPrefix := "docker://" imageRef, err := alltransports.ParseImageName(fmt.Sprintf("%s/%s", registry, term)) if err == nil && imageRef.Transport().Name() != registryTransport.Transport.Name() { - return nil, errors.Errorf("reference %q must be a docker reference", term) + return nil, fmt.Errorf("reference %q must be a docker reference", term) } else if err != nil { imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, fmt.Sprintf("%s/%s", registry, term))) if err != nil { - return nil, errors.Errorf("reference %q must be a docker reference", term) + return nil, fmt.Errorf("reference %q must be a docker reference", term) } } tags, err := registryTransport.GetRepositoryTags(ctx, sys, imageRef) if err != nil { - return nil, errors.Errorf("error getting repository tags: %v", err) + return nil, fmt.Errorf("error getting repository tags: %v", err) } limit := searchMaxQueries if len(tags) < limit { diff --git a/libnetwork/cni/cni_conversion.go b/libnetwork/cni/cni_conversion.go index 61cbf5953..de6adbdc7 100644 --- a/libnetwork/cni/cni_conversion.go +++ b/libnetwork/cni/cni_conversion.go @@ -5,6 +5,7 @@ package cni import ( "encoding/json" + "errors" "fmt" "io/ioutil" "net" @@ -19,7 +20,6 @@ import ( "github.com/containers/common/libnetwork/types" "github.com/containers/common/libnetwork/util" pkgutil "github.com/containers/common/pkg/util" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) @@ -36,7 +36,7 @@ func createNetworkFromCNIConfigList(conf *libcni.NetworkConfigList, confPath str cniJSON := make(map[string]interface{}) err := json.Unmarshal(conf.Bytes, &cniJSON) if err != nil { - return nil, errors.Wrapf(err, "failed to unmarshal network config %s", conf.Name) + return nil, fmt.Errorf("failed to unmarshal network config %s: %w", conf.Name, err) } if args, ok := cniJSON["args"]; ok { if key, ok := args.(map[string]interface{}); ok { @@ -60,7 +60,7 @@ func createNetworkFromCNIConfigList(conf *libcni.NetworkConfigList, confPath str var bridge hostLocalBridge err := json.Unmarshal(firstPlugin.Bytes, &bridge) if err != nil { - return nil, errors.Wrapf(err, "failed to unmarshal the bridge plugin config in %s", confPath) + return nil, fmt.Errorf("failed to unmarshal the bridge plugin config in %s: %w", confPath, err) } network.NetworkInterface = bridge.BrName @@ -86,7 +86,7 @@ func createNetworkFromCNIConfigList(conf *libcni.NetworkConfigList, confPath str var vlan VLANConfig err := json.Unmarshal(firstPlugin.Bytes, &vlan) if err != nil { - return nil, errors.Wrapf(err, "failed to unmarshal the macvlan plugin config in %s", confPath) + return nil, fmt.Errorf("failed to unmarshal the macvlan plugin config in %s: %w", confPath, err) } network.NetworkInterface = vlan.Master @@ -165,7 +165,7 @@ func convertIPAMConfToNetwork(network *types.Network, ipam *ipamConfig, confPath if ipam.Gateway != "" { gateway = net.ParseIP(ipam.Gateway) if gateway == nil { - return errors.Errorf("failed to parse gateway ip %s", ipam.Gateway) + return fmt.Errorf("failed to parse gateway ip %s", ipam.Gateway) } // convert to 4 byte if ipv4 util.NormalizeIP(&gateway) @@ -173,7 +173,7 @@ func convertIPAMConfToNetwork(network *types.Network, ipam *ipamConfig, confPath // only add a gateway address if the network is not internal gateway, err = util.FirstIPInSubnet(sub) if err != nil { - return errors.Errorf("failed to get first ip in subnet %s", sub.String()) + return fmt.Errorf("failed to get first ip in subnet %s", sub.String()) } } s.Gateway = gateway @@ -183,13 +183,13 @@ func convertIPAMConfToNetwork(network *types.Network, ipam *ipamConfig, confPath if ipam.RangeStart != "" { rangeStart = net.ParseIP(ipam.RangeStart) if rangeStart == nil { - return errors.Errorf("failed to parse range start ip %s", ipam.RangeStart) + return fmt.Errorf("failed to parse range start ip %s", ipam.RangeStart) } } if ipam.RangeEnd != "" { rangeEnd = net.ParseIP(ipam.RangeEnd) if rangeEnd == nil { - return errors.Errorf("failed to parse range end ip %s", ipam.RangeEnd) + return fmt.Errorf("failed to parse range end ip %s", ipam.RangeEnd) } } if rangeStart != nil || rangeEnd != nil { @@ -281,7 +281,7 @@ func (n *cniNetwork) createCNIConfigListFromNetwork(network *types.Network, writ case types.NoneIPAMDriver: // do nothing default: - return nil, "", errors.Errorf("unsupported ipam driver %q", ipamDriver) + return nil, "", fmt.Errorf("unsupported ipam driver %q", ipamDriver) } opts, err := parseOptions(network.Options, network.Driver) @@ -319,7 +319,7 @@ func (n *cniNetwork) createCNIConfigListFromNetwork(network *types.Network, writ plugins = append(plugins, newVLANPlugin(types.IPVLANNetworkDriver, network.NetworkInterface, opts.vlanPluginMode, opts.mtu, ipamConf)) default: - return nil, "", errors.Errorf("driver %q is not supported by cni", network.Driver) + return nil, "", fmt.Errorf("driver %q is not supported by cni", network.Driver) } ncList["plugins"] = plugins b, err := json.MarshalIndent(ncList, "", " ") @@ -358,7 +358,7 @@ func convertSpecgenPortsToCNIPorts(ports []types.PortMapping) ([]cniPortMapEntry for _, protocol := range protocols { if !pkgutil.StringInSlice(protocol, []string{"tcp", "udp", "sctp"}) { - return nil, errors.Errorf("unknown port protocol %s", protocol) + return nil, fmt.Errorf("unknown port protocol %s", protocol) } cniPort := cniPortMapEntry{ HostPort: int(port.HostPort), @@ -420,14 +420,14 @@ func parseOptions(networkOptions map[string]string, networkDriver string) (*opti switch networkDriver { case types.MacVLANNetworkDriver: if !pkgutil.StringInSlice(v, types.ValidMacVLANModes) { - return nil, errors.Errorf("unknown macvlan mode %q", v) + return nil, fmt.Errorf("unknown macvlan mode %q", v) } case types.IPVLANNetworkDriver: if !pkgutil.StringInSlice(v, types.ValidIPVLANModes) { - return nil, errors.Errorf("unknown ipvlan mode %q", v) + return nil, fmt.Errorf("unknown ipvlan mode %q", v) } default: - return nil, errors.Errorf("cannot set option \"mode\" with driver %q", networkDriver) + return nil, fmt.Errorf("cannot set option \"mode\" with driver %q", networkDriver) } opt.vlanPluginMode = v @@ -441,7 +441,7 @@ func parseOptions(networkOptions map[string]string, networkDriver string) (*opti } default: - return nil, errors.Errorf("unsupported network option %s", k) + return nil, fmt.Errorf("unsupported network option %s", k) } } return opt, nil diff --git a/libnetwork/cni/config.go b/libnetwork/cni/config.go index c86196c17..aa94e73d1 100644 --- a/libnetwork/cni/config.go +++ b/libnetwork/cni/config.go @@ -4,13 +4,14 @@ package cni import ( + "errors" + "fmt" "net" "os" internalutil "github.com/containers/common/libnetwork/internal/util" "github.com/containers/common/libnetwork/types" pkgutil "github.com/containers/common/pkg/util" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -43,7 +44,7 @@ func (n *cniNetwork) networkCreate(newNetwork *types.Network, defaultNet bool) ( // FIXME: Should we use a different type for network create without the ID field? // the caller is not allowed to set a specific ID if newNetwork.ID != "" { - return nil, errors.Wrap(types.ErrInvalidArg, "ID can not be set for network create") + return nil, fmt.Errorf("ID can not be set for network create: %w", types.ErrInvalidArg) } err := internalutil.CommonNetworkCreate(n, newNetwork) @@ -83,7 +84,7 @@ func (n *cniNetwork) networkCreate(newNetwork *types.Network, defaultNet bool) ( return nil, err } default: - return nil, errors.Wrapf(types.ErrInvalidArg, "unsupported driver %s", newNetwork.Driver) + return nil, fmt.Errorf("unsupported driver %s: %w", newNetwork.Driver, types.ErrInvalidArg) } err = internalutil.ValidateSubnets(newNetwork, !newNetwork.Internal, usedNetworks) @@ -127,7 +128,7 @@ func (n *cniNetwork) NetworkRemove(nameOrID string) error { // Removing the default network is not allowed. if network.libpodNet.Name == n.defaultNetwork { - return errors.Errorf("default network %s cannot be removed", n.defaultNetwork) + return fmt.Errorf("default network %s cannot be removed", n.defaultNetwork) } // Remove the bridge network interface on the host. @@ -193,7 +194,7 @@ func createIPMACVLAN(network *types.Network) error { return err } if !pkgutil.StringInSlice(network.NetworkInterface, interfaceNames) { - return errors.Errorf("parent interface %s does not exist", network.NetworkInterface) + return fmt.Errorf("parent interface %s does not exist", network.NetworkInterface) } } @@ -224,10 +225,10 @@ func validateIPAMDriver(n *types.Network) error { case "", types.HostLocalIPAMDriver: case types.DHCPIPAMDriver, types.NoneIPAMDriver: if len(n.Subnets) > 0 { - return errors.Errorf("%s ipam driver is set but subnets are given", ipamDriver) + return fmt.Errorf("%s ipam driver is set but subnets are given", ipamDriver) } default: - return errors.Errorf("unsupported ipam driver %q", ipamDriver) + return fmt.Errorf("unsupported ipam driver %q", ipamDriver) } return nil } diff --git a/libnetwork/cni/network.go b/libnetwork/cni/network.go index 561f309d0..fce8f0066 100644 --- a/libnetwork/cni/network.go +++ b/libnetwork/cni/network.go @@ -7,6 +7,8 @@ import ( "context" "crypto/sha256" "encoding/hex" + "errors" + "fmt" "os" "path/filepath" "strings" @@ -16,7 +18,6 @@ import ( "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/config" "github.com/containers/storage/pkg/lockfile" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -94,7 +95,7 @@ func NewCNINetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) { } defaultNet, err := types.ParseCIDR(defaultSubnet) if err != nil { - return nil, errors.Wrap(err, "failed to parse default subnet") + return nil, fmt.Errorf("failed to parse default subnet: %w", err) } defaultSubnetPools := conf.DefaultsubnetPools @@ -201,7 +202,7 @@ func (n *cniNetwork) loadNetworks() error { if networks[n.defaultNetwork] == nil { networkInfo, err := n.createDefaultNetwork() if err != nil { - return errors.Wrapf(err, "failed to create default network %s", n.defaultNetwork) + return fmt.Errorf("failed to create default network %s: %w", n.defaultNetwork, err) } networks[n.defaultNetwork] = networkInfo } @@ -243,7 +244,7 @@ func (n *cniNetwork) getNetwork(nameOrID string) (*network, error) { if strings.HasPrefix(val.libpodNet.ID, nameOrID) { if net != nil { - return nil, errors.Errorf("more than one result for network ID %s", nameOrID) + return nil, fmt.Errorf("more than one result for network ID %s", nameOrID) } net = val } @@ -251,7 +252,7 @@ func (n *cniNetwork) getNetwork(nameOrID string) (*network, error) { if net != nil { return net, nil } - return nil, errors.Wrapf(types.ErrNoSuchNetwork, "unable to find network with name or ID %s", nameOrID) + return nil, fmt.Errorf("unable to find network with name or ID %s: %w", nameOrID, types.ErrNoSuchNetwork) } // getNetworkIDFromName creates a network ID from the name. It is just the diff --git a/libnetwork/cni/run.go b/libnetwork/cni/run.go index 35236cf25..2da8da1ad 100644 --- a/libnetwork/cni/run.go +++ b/libnetwork/cni/run.go @@ -5,6 +5,7 @@ package cni import ( "context" + "fmt" "net" "os" "strings" @@ -15,7 +16,6 @@ import ( "github.com/containers/common/libnetwork/internal/util" "github.com/containers/common/libnetwork/types" "github.com/hashicorp/go-multierror" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -36,7 +36,7 @@ func (n *cniNetwork) Setup(namespacePath string, options types.SetupOptions) (ma err = setupLoopback(namespacePath) if err != nil { - return nil, errors.Wrapf(err, "failed to set the loopback adapter up") + return nil, fmt.Errorf("failed to set the loopback adapter up: %w", err) } var retErr error @@ -108,7 +108,7 @@ func CNIResultToStatus(res cnitypes.Result) (types.StatusBlock, error) { for _, nameserver := range cniResult.DNS.Nameservers { ip := net.ParseIP(nameserver) if ip == nil { - return result, errors.Errorf("failed to parse cni nameserver ip %s", nameserver) + return result, fmt.Errorf("failed to parse cni nameserver ip %s", nameserver) } nameservers = append(nameservers, ip) } @@ -133,7 +133,7 @@ func CNIResultToStatus(res cnitypes.Result) (types.StatusBlock, error) { continue } if len(cniResult.Interfaces) <= *ip.Interface { - return result, errors.Errorf("invalid cni result, interface index %d out of range", *ip.Interface) + return result, fmt.Errorf("invalid cni result, interface index %d out of range", *ip.Interface) } // when we have a ip for this interface add it to the subnets @@ -236,7 +236,7 @@ func (n *cniNetwork) teardown(namespacePath string, options types.TeardownOption logrus.Warnf("Failed to load cached network config: %v, falling back to loading network %s from disk", err, name) network := n.networks[name] if network == nil { - multiErr = multierror.Append(multiErr, errors.Wrapf(types.ErrNoSuchNetwork, "network %s", name)) + multiErr = multierror.Append(multiErr, fmt.Errorf("network %s: %w", name, types.ErrNoSuchNetwork)) continue } cniConfList = network.cniNet @@ -258,7 +258,7 @@ func getCachedNetworkConfig(cniConf *libcni.CNIConfig, name string, rt *libcni.R if err != nil { return nil, nil, err } else if confBytes == nil { - return nil, nil, errors.Errorf("network %s not found in CNI cache", name) + return nil, nil, fmt.Errorf("network %s not found in CNI cache", name) } cniConfList, err = libcni.ConfListFromBytes(confBytes) diff --git a/libnetwork/internal/util/bridge.go b/libnetwork/internal/util/bridge.go index bfa72808d..7197a23bf 100644 --- a/libnetwork/internal/util/bridge.go +++ b/libnetwork/internal/util/bridge.go @@ -1,23 +1,23 @@ package util import ( + "fmt" "net" "github.com/containers/common/libnetwork/types" "github.com/containers/common/libnetwork/util" "github.com/containers/common/pkg/config" pkgutil "github.com/containers/common/pkg/util" - "github.com/pkg/errors" ) func CreateBridge(n NetUtil, network *types.Network, usedNetworks []*net.IPNet, subnetPools []config.SubnetPool) error { if network.NetworkInterface != "" { bridges := GetBridgeInterfaceNames(n) if pkgutil.StringInSlice(network.NetworkInterface, bridges) { - return errors.Errorf("bridge name %s already in use", network.NetworkInterface) + return fmt.Errorf("bridge name %s already in use", network.NetworkInterface) } if !types.NameRegex.MatchString(network.NetworkInterface) { - return errors.Wrapf(types.RegexError, "bridge name %s invalid", network.NetworkInterface) + return fmt.Errorf("bridge name %s invalid: %w", network.NetworkInterface, types.RegexError) } } else { var err error diff --git a/libnetwork/internal/util/create.go b/libnetwork/internal/util/create.go index d4d574065..1bd2c3279 100644 --- a/libnetwork/internal/util/create.go +++ b/libnetwork/internal/util/create.go @@ -1,8 +1,9 @@ package util import ( + "fmt" + "github.com/containers/common/libnetwork/types" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -22,10 +23,10 @@ func CommonNetworkCreate(n NetUtil, network *types.Network) error { // validate the name when given if network.Name != "" { if !types.NameRegex.MatchString(network.Name) { - return errors.Wrapf(types.RegexError, "network name %s invalid", network.Name) + return fmt.Errorf("network name %s invalid: %w", network.Name, types.RegexError) } if _, err := n.Network(network.Name); err == nil { - return errors.Wrapf(types.ErrNetworkExists, "network name %s already used", network.Name) + return fmt.Errorf("network name %s already used: %w", network.Name, types.ErrNetworkExists) } } else { name, err = GetFreeDeviceName(n) diff --git a/libnetwork/internal/util/ip.go b/libnetwork/internal/util/ip.go index 6dc5d9325..7afc30f34 100644 --- a/libnetwork/internal/util/ip.go +++ b/libnetwork/internal/util/ip.go @@ -2,9 +2,9 @@ package util import ( "crypto/rand" + "errors" + "fmt" "net" - - "github.com/pkg/errors" ) func incByte(subnet *net.IPNet, idx int, shift uint) error { @@ -31,7 +31,7 @@ func NextSubnet(subnet *net.IPNet) (*net.IPNet, error) { } ones, bits := newSubnet.Mask.Size() if ones == 0 { - return nil, errors.Errorf("%s has only one subnet", subnet.String()) + return nil, fmt.Errorf("%s has only one subnet", subnet.String()) } zeroes := uint(bits - ones) shift := zeroes % 8 diff --git a/libnetwork/internal/util/parse.go b/libnetwork/internal/util/parse.go index 1f68df0bb..2bda3b122 100644 --- a/libnetwork/internal/util/parse.go +++ b/libnetwork/internal/util/parse.go @@ -1,9 +1,8 @@ package util import ( + "fmt" "strconv" - - "github.com/pkg/errors" ) // ParseMTU parses the mtu option @@ -16,7 +15,7 @@ func ParseMTU(mtu string) (int, error) { return 0, err } if m < 0 { - return 0, errors.Errorf("mtu %d is less than zero", m) + return 0, fmt.Errorf("mtu %d is less than zero", m) } return m, nil } @@ -31,7 +30,7 @@ func ParseVlan(vlan string) (int, error) { return 0, err } if v < 0 || v > 4094 { - return 0, errors.Errorf("vlan ID %d must be between 0 and 4094", v) + return 0, fmt.Errorf("vlan ID %d must be between 0 and 4094", v) } return v, nil } diff --git a/libnetwork/internal/util/validate.go b/libnetwork/internal/util/validate.go index 4dd44110a..14f4052d8 100644 --- a/libnetwork/internal/util/validate.go +++ b/libnetwork/internal/util/validate.go @@ -1,11 +1,12 @@ package util import ( + "errors" + "fmt" "net" "github.com/containers/common/libnetwork/types" "github.com/containers/common/libnetwork/util" - "github.com/pkg/errors" ) // ValidateSubnet will validate a given Subnet. It checks if the @@ -25,18 +26,18 @@ func ValidateSubnet(s *types.Subnet, addGateway bool, usedNetworks []*net.IPNet) // the network address and not a random ip in the subnet. _, n, err := net.ParseCIDR(s.Subnet.String()) if err != nil { - return errors.Wrap(err, "subnet invalid") + return fmt.Errorf("subnet invalid: %w", err) } // check that the new subnet does not conflict with existing ones if NetworkIntersectsWithNetworks(n, usedNetworks) { - return errors.Errorf("subnet %s is already used on the host or by another config", n.String()) + return fmt.Errorf("subnet %s is already used on the host or by another config", n.String()) } s.Subnet = types.IPNet{IPNet: *n} if s.Gateway != nil { if !s.Subnet.Contains(s.Gateway) { - return errors.Errorf("gateway %s not in subnet %s", s.Gateway, &s.Subnet) + return fmt.Errorf("gateway %s not in subnet %s", s.Gateway, &s.Subnet) } util.NormalizeIP(&s.Gateway) } else if addGateway { @@ -50,13 +51,13 @@ func ValidateSubnet(s *types.Subnet, addGateway bool, usedNetworks []*net.IPNet) if s.LeaseRange != nil { if s.LeaseRange.StartIP != nil { if !s.Subnet.Contains(s.LeaseRange.StartIP) { - return errors.Errorf("lease range start ip %s not in subnet %s", s.LeaseRange.StartIP, &s.Subnet) + return fmt.Errorf("lease range start ip %s not in subnet %s", s.LeaseRange.StartIP, &s.Subnet) } util.NormalizeIP(&s.LeaseRange.StartIP) } if s.LeaseRange.EndIP != nil { if !s.Subnet.Contains(s.LeaseRange.EndIP) { - return errors.Errorf("lease range end ip %s not in subnet %s", s.LeaseRange.EndIP, &s.Subnet) + return fmt.Errorf("lease range end ip %s not in subnet %s", s.LeaseRange.EndIP, &s.Subnet) } util.NormalizeIP(&s.LeaseRange.EndIP) } @@ -107,7 +108,7 @@ func ValidateSetupOptions(n NetUtil, namespacePath string, options types.SetupOp // validatePerNetworkOpts checks that all given static ips are in a subnet on this network func validatePerNetworkOpts(network *types.Network, netOpts *types.PerNetworkOptions) error { if netOpts.InterfaceName == "" { - return errors.Errorf("interface name on network %s is empty", network.Name) + return fmt.Errorf("interface name on network %s is empty", network.Name) } if network.IPAMOptions[types.Driver] == types.HostLocalIPAMDriver { outer: @@ -117,7 +118,7 @@ func validatePerNetworkOpts(network *types.Network, netOpts *types.PerNetworkOpt continue outer } } - return errors.Errorf("requested static ip %s not in any subnet on network %s", ip.String(), network.Name) + return fmt.Errorf("requested static ip %s not in any subnet on network %s", ip.String(), network.Name) } } return nil diff --git a/libnetwork/netavark/config.go b/libnetwork/netavark/config.go index 2aa943744..647143652 100644 --- a/libnetwork/netavark/config.go +++ b/libnetwork/netavark/config.go @@ -5,6 +5,8 @@ package netavark import ( "encoding/json" + "errors" + "fmt" "net" "os" "path/filepath" @@ -15,7 +17,6 @@ import ( "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/util" "github.com/containers/storage/pkg/stringid" - "github.com/pkg/errors" ) // NetworkCreate will take a partial filled Network and fill the @@ -45,7 +46,7 @@ func (n *netavarkNetwork) networkCreate(newNetwork *types.Network, defaultNet bo // FIXME: Should we use a different type for network create without the ID field? // the caller is not allowed to set a specific ID if newNetwork.ID != "" { - return nil, errors.Wrap(types.ErrInvalidArg, "ID can not be set for network create") + return nil, fmt.Errorf("ID can not be set for network create: %w", types.ErrInvalidArg) } // generate random network ID @@ -116,7 +117,7 @@ func (n *netavarkNetwork) networkCreate(newNetwork *types.Network, defaultNet bo // rust only support "true" or "false" while go can parse 1 and 0 as well so we need to change it newNetwork.Options[types.IsolateOption] = strconv.FormatBool(val) default: - return nil, errors.Errorf("unsupported bridge network option %s", key) + return nil, fmt.Errorf("unsupported bridge network option %s", key) } } case types.MacVLANNetworkDriver: @@ -125,7 +126,7 @@ func (n *netavarkNetwork) networkCreate(newNetwork *types.Network, defaultNet bo return nil, err } default: - return nil, errors.Wrapf(types.ErrInvalidArg, "unsupported driver %s", newNetwork.Driver) + return nil, fmt.Errorf("unsupported driver %s: %w", newNetwork.Driver, types.ErrInvalidArg) } // when we do not have ipam we must disable dns @@ -165,7 +166,7 @@ func createMacvlan(network *types.Network) error { return err } if !util.StringInSlice(network.NetworkInterface, interfaceNames) { - return errors.Errorf("parent interface %s does not exist", network.NetworkInterface) + return fmt.Errorf("parent interface %s does not exist", network.NetworkInterface) } } @@ -173,12 +174,12 @@ func createMacvlan(network *types.Network) error { switch network.IPAMOptions[types.Driver] { case "": if len(network.Subnets) == 0 { - return errors.Errorf("macvlan driver needs at least one subnet specified, DHCP is not yet supported with netavark") + return fmt.Errorf("macvlan driver needs at least one subnet specified, DHCP is not yet supported with netavark") } network.IPAMOptions[types.Driver] = types.HostLocalIPAMDriver case types.HostLocalIPAMDriver: if len(network.Subnets) == 0 { - return errors.Errorf("macvlan driver needs at least one subnet specified, when the host-local ipam driver is set") + return fmt.Errorf("macvlan driver needs at least one subnet specified, when the host-local ipam driver is set") } } @@ -187,7 +188,7 @@ func createMacvlan(network *types.Network) error { switch key { case types.ModeOption: if !util.StringInSlice(value, types.ValidMacVLANModes) { - return errors.Errorf("unknown macvlan mode %q", value) + return fmt.Errorf("unknown macvlan mode %q", value) } case types.MTUOption: _, err := internalutil.ParseMTU(value) @@ -195,7 +196,7 @@ func createMacvlan(network *types.Network) error { return err } default: - return errors.Errorf("unsupported macvlan network option %s", key) + return fmt.Errorf("unsupported macvlan network option %s", key) } } return nil @@ -218,7 +219,7 @@ func (n *netavarkNetwork) NetworkRemove(nameOrID string) error { // Removing the default network is not allowed. if network.Name == n.defaultNetwork { - return errors.Errorf("default network %s cannot be removed", n.defaultNetwork) + return fmt.Errorf("default network %s cannot be removed", n.defaultNetwork) } file := filepath.Join(n.networkConfigDir, network.Name+".json") @@ -282,7 +283,7 @@ func validateIPAMDriver(n *types.Network) error { case types.DHCPIPAMDriver: return errors.New("dhcp ipam driver is not yet supported with netavark") default: - return errors.Errorf("unsupported ipam driver %q", ipamDriver) + return fmt.Errorf("unsupported ipam driver %q", ipamDriver) } return nil } diff --git a/libnetwork/netavark/ipam.go b/libnetwork/netavark/ipam.go index 89820f1d6..fa5800ee4 100644 --- a/libnetwork/netavark/ipam.go +++ b/libnetwork/netavark/ipam.go @@ -10,7 +10,6 @@ import ( "github.com/containers/common/libnetwork/types" "github.com/containers/common/libnetwork/util" - "github.com/pkg/errors" "go.etcd.io/bbolt" ) @@ -180,7 +179,7 @@ func getFreeIPFromBucket(bucket *bbolt.Bucket, subnet *types.Subnet) (net.IP, er lastIP, err := util.LastIPInSubnet(&subnet.Subnet.IPNet) // this error should never happen but lets check anyways to prevent panics if err != nil { - return nil, errors.Wrap(err, "failed to get lastIP") + return nil, fmt.Errorf("failed to get lastIP: %w", err) } // ipv4 uses the last ip in a subnet for broadcast so we cannot use it if util.IsIPv4(lastIP) { diff --git a/libnetwork/netavark/network.go b/libnetwork/netavark/network.go index 0d03cd5e6..577e3cf36 100644 --- a/libnetwork/netavark/network.go +++ b/libnetwork/netavark/network.go @@ -5,6 +5,8 @@ package netavark import ( "encoding/json" + "errors" + "fmt" "io/ioutil" "os" "path/filepath" @@ -16,7 +18,6 @@ import ( "github.com/containers/common/pkg/config" "github.com/containers/storage/pkg/lockfile" "github.com/containers/storage/pkg/unshare" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -105,7 +106,7 @@ func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) { } defaultNet, err := types.ParseCIDR(defaultSubnet) if err != nil { - return nil, errors.Wrap(err, "failed to parse default subnet") + return nil, fmt.Errorf("failed to parse default subnet: %w", err) } if err := os.MkdirAll(conf.NetworkConfigDir, 0o755); err != nil { @@ -221,7 +222,7 @@ func (n *netavarkNetwork) loadNetworks() error { if networks[n.defaultNetwork] == nil { networkInfo, err := n.createDefaultNetwork() if err != nil { - return errors.Wrapf(err, "failed to create default network %s", n.defaultNetwork) + return fmt.Errorf("failed to create default network %s: %w", n.defaultNetwork, err) } networks[n.defaultNetwork] = networkInfo } @@ -242,7 +243,7 @@ func parseNetwork(network *types.Network) error { } if len(network.ID) != 64 { - return errors.Errorf("invalid network ID %q", network.ID) + return fmt.Errorf("invalid network ID %q", network.ID) } // add gateway when not internal or dns enabled @@ -284,7 +285,7 @@ func (n *netavarkNetwork) getNetwork(nameOrID string) (*types.Network, error) { if strings.HasPrefix(val.ID, nameOrID) { if net != nil { - return nil, errors.Errorf("more than one result for network ID %s", nameOrID) + return nil, fmt.Errorf("more than one result for network ID %s", nameOrID) } net = val } @@ -292,7 +293,7 @@ func (n *netavarkNetwork) getNetwork(nameOrID string) (*types.Network, error) { if net != nil { return net, nil } - return nil, errors.Wrapf(types.ErrNoSuchNetwork, "unable to find network with name or ID %s", nameOrID) + return nil, fmt.Errorf("unable to find network with name or ID %s: %w", nameOrID, types.ErrNoSuchNetwork) } // Implement the NetUtil interface for easy code sharing with other network interfaces. diff --git a/libnetwork/netavark/run.go b/libnetwork/netavark/run.go index 7f0a84140..b364f42d3 100644 --- a/libnetwork/netavark/run.go +++ b/libnetwork/netavark/run.go @@ -10,7 +10,6 @@ import ( "github.com/containers/common/libnetwork/internal/util" "github.com/containers/common/libnetwork/types" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -42,7 +41,7 @@ func (n *netavarkNetwork) Setup(namespacePath string, options types.SetupOptions netavarkOpts, err := n.convertNetOpts(options.NetworkOptions) if err != nil { - return nil, errors.Wrap(err, "failed to convert net opts") + return nil, fmt.Errorf("failed to convert net opts: %w", err) } // Warn users if one or more networks have dns enabled @@ -103,7 +102,7 @@ func (n *netavarkNetwork) Teardown(namespacePath string, options types.TeardownO netavarkOpts, err := n.convertNetOpts(options.NetworkOptions) if err != nil { - return errors.Wrap(err, "failed to convert net opts") + return fmt.Errorf("failed to convert net opts: %w", err) } retErr := n.execNetavark([]string{"teardown", namespacePath}, netavarkOpts, nil) diff --git a/libnetwork/types/define.go b/libnetwork/types/define.go index d37e529df..f84221458 100644 --- a/libnetwork/types/define.go +++ b/libnetwork/types/define.go @@ -1,9 +1,9 @@ package types import ( + "errors" + "fmt" "regexp" - - "github.com/pkg/errors" ) var ( @@ -21,5 +21,5 @@ var ( // This must NOT be changed. NameRegex = regexp.MustCompile("^[a-zA-Z0-9][a-zA-Z0-9_.-]*$") // RegexError is thrown in presence of an invalid name. - RegexError = errors.Wrapf(ErrInvalidArg, "names must match [a-zA-Z0-9][a-zA-Z0-9_.-]*") + RegexError = fmt.Errorf("names must match [a-zA-Z0-9][a-zA-Z0-9_.-]*: %w", ErrInvalidArg) // nolint:revive // This lint is new and we do not want to break the API. ) diff --git a/libnetwork/util/filters.go b/libnetwork/util/filters.go index 58d79d25b..a8ef8a413 100644 --- a/libnetwork/util/filters.go +++ b/libnetwork/util/filters.go @@ -1,12 +1,12 @@ package util import ( + "fmt" "strings" "github.com/containers/common/libnetwork/types" "github.com/containers/common/pkg/filters" "github.com/containers/common/pkg/util" - "github.com/pkg/errors" ) func GenerateNetworkFilters(f map[string][]string) ([]types.FilterFunc, error) { @@ -75,6 +75,6 @@ func createPruneFilterFuncs(key string, filterValues []string) (types.FilterFunc return net.Created.Before(until) }, nil default: - return nil, errors.Errorf("invalid filter %q", key) + return nil, fmt.Errorf("invalid filter %q", key) } } diff --git a/pkg/apparmor/apparmor_linux.go b/pkg/apparmor/apparmor_linux.go index 1fd269255..7ba63ba74 100644 --- a/pkg/apparmor/apparmor_linux.go +++ b/pkg/apparmor/apparmor_linux.go @@ -6,6 +6,8 @@ package apparmor import ( "bufio" "bytes" + "errors" + "fmt" "io" "os" "os/exec" @@ -17,7 +19,6 @@ import ( "github.com/containers/common/pkg/apparmor/internal/supported" "github.com/containers/storage/pkg/unshare" runcaa "github.com/opencontainers/runc/libcontainer/apparmor" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -47,7 +48,7 @@ type profileData struct { func (p *profileData) generateDefault(apparmorParserPath string, out io.Writer) error { compiled, err := template.New("apparmor_profile").Parse(defaultProfileTemplate) if err != nil { - return errors.Wrap(err, "create AppArmor profile from template") + return fmt.Errorf("create AppArmor profile from template: %w", err) } if macroExists("tunables/global") { @@ -62,11 +63,15 @@ func (p *profileData) generateDefault(apparmorParserPath string, out io.Writer) ver, err := getAAParserVersion(apparmorParserPath) if err != nil { - return errors.Wrap(err, "get AppArmor version") + return fmt.Errorf("get AppArmor version: %w", err) } p.Version = ver - return errors.Wrap(compiled.Execute(out, p), "execute compiled profile") + if err := compiled.Execute(out, p); err != nil { + return fmt.Errorf("execute compiled profile: %w", err) + } + + return nil } // macrosExists checks if the passed macro exists. @@ -88,19 +93,19 @@ func InstallDefault(name string) error { apparmorParserPath, err := supported.NewAppArmorVerifier().FindAppArmorParserBinary() if err != nil { - return errors.Wrap(err, "find `apparmor_parser` binary") + return fmt.Errorf("find `apparmor_parser` binary: %w", err) } cmd := exec.Command(apparmorParserPath, "-Kr") pipe, err := cmd.StdinPipe() if err != nil { - return errors.Wrapf(err, "execute %s", apparmorParserPath) + return fmt.Errorf("execute %s: %w", apparmorParserPath, err) } if err := cmd.Start(); err != nil { if pipeErr := pipe.Close(); pipeErr != nil { logrus.Errorf("Unable to close AppArmor pipe: %q", pipeErr) } - return errors.Wrapf(err, "start %s command", apparmorParserPath) + return fmt.Errorf("start %s command: %w", apparmorParserPath, err) } if err := p.generateDefault(apparmorParserPath, pipe); err != nil { if pipeErr := pipe.Close(); pipeErr != nil { @@ -109,14 +114,18 @@ func InstallDefault(name string) error { if cmdErr := cmd.Wait(); cmdErr != nil { logrus.Errorf("Unable to wait for AppArmor command: %q", cmdErr) } - return errors.Wrap(err, "generate default profile into pipe") + return fmt.Errorf("generate default profile into pipe: %w", err) } if pipeErr := pipe.Close(); pipeErr != nil { logrus.Errorf("Unable to close AppArmor pipe: %q", pipeErr) } - return errors.Wrap(cmd.Wait(), "wait for AppArmor command") + if err := cmd.Wait(); err != nil { + return fmt.Errorf("wait for AppArmor command: %w", err) + } + + return nil } // DefaultContent returns the default profile content as byte slice. The @@ -128,11 +137,11 @@ func DefaultContent(name string) ([]byte, error) { apparmorParserPath, err := supported.NewAppArmorVerifier().FindAppArmorParserBinary() if err != nil { - return nil, errors.Wrap(err, "find `apparmor_parser` binary") + return nil, fmt.Errorf("find `apparmor_parser` binary: %w", err) } if err := p.generateDefault(apparmorParserPath, buffer); err != nil { - return nil, errors.Wrap(err, "generate default AppAmor profile") + return nil, fmt.Errorf("generate default AppAmor profile: %w", err) } return buffer.Bytes(), nil } @@ -141,15 +150,15 @@ func DefaultContent(name string) ([]byte, error) { // kernel. func IsLoaded(name string) (bool, error) { if name != "" && unshare.IsRootless() { - return false, errors.Wrapf(ErrApparmorRootless, "cannot load AppArmor profile %q", name) + return false, fmt.Errorf("cannot load AppArmor profile %q: %w", name, ErrApparmorRootless) } file, err := os.Open("/sys/kernel/security/apparmor/profiles") if err != nil { - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { return false, nil } - return false, errors.Wrap(err, "open AppArmor profile path") + return false, fmt.Errorf("open AppArmor profile path: %w", err) } defer file.Close() @@ -160,7 +169,7 @@ func IsLoaded(name string) (bool, error) { break } if err != nil { - return false, errors.Wrap(err, "reading AppArmor profile") + return false, fmt.Errorf("reading AppArmor profile: %w", err) } if strings.HasPrefix(p, name+" ") { return true, nil @@ -177,7 +186,7 @@ func execAAParser(apparmorParserPath, dir string, args ...string) (string, error output, err := c.Output() if err != nil { - return "", errors.Errorf("running `%s %s` failed with output: %s\nerror: %v", c.Path, strings.Join(c.Args, " "), output, err) + return "", fmt.Errorf("running `%s %s` failed with output: %s\nerror: %v", c.Path, strings.Join(c.Args, " "), output, err) } return string(output), nil @@ -187,7 +196,7 @@ func execAAParser(apparmorParserPath, dir string, args ...string) (string, error func getAAParserVersion(apparmorParserPath string) (int, error) { output, err := execAAParser(apparmorParserPath, "", "--version") if err != nil { - return -1, errors.Wrap(err, "execute apparmor_parser") + return -1, fmt.Errorf("execute apparmor_parser: %w", err) } return parseAAParserVersion(output) } @@ -206,7 +215,7 @@ func parseAAParserVersion(output string) (int, error) { // split by major minor version v := strings.Split(version, ".") if len(v) == 0 || len(v) > 3 { - return -1, errors.Errorf("parsing version failed for output: `%s`", output) + return -1, fmt.Errorf("parsing version failed for output: `%s`", output) } // Default the versions to 0. @@ -214,19 +223,19 @@ func parseAAParserVersion(output string) (int, error) { majorVersion, err := strconv.Atoi(v[0]) if err != nil { - return -1, errors.Wrap(err, "convert AppArmor major version") + return -1, fmt.Errorf("convert AppArmor major version: %w", err) } if len(v) > 1 { minorVersion, err = strconv.Atoi(v[1]) if err != nil { - return -1, errors.Wrap(err, "convert AppArmor minor version") + return -1, fmt.Errorf("convert AppArmor minor version: %w", err) } } if len(v) > 2 { patchLevel, err = strconv.Atoi(v[2]) if err != nil { - return -1, errors.Wrap(err, "convert AppArmor patch version") + return -1, fmt.Errorf("convert AppArmor patch version: %w", err) } } @@ -250,7 +259,7 @@ func CheckProfileAndLoadDefault(name string) (string, error) { // privileges. Return an error in case a specific profile is specified. if unshare.IsRootless() { if name != "" { - return "", errors.Wrapf(ErrApparmorRootless, "cannot load AppArmor profile %q", name) + return "", fmt.Errorf("cannot load AppArmor profile %q: %w", name, ErrApparmorRootless) } logrus.Debug("Skipping loading default AppArmor profile (rootless mode)") return "", nil @@ -261,7 +270,7 @@ func CheckProfileAndLoadDefault(name string) (string, error) { if name == "" { return "", nil } - return "", errors.Errorf("profile %q specified but AppArmor is disabled on the host", name) + return "", fmt.Errorf("profile %q specified but AppArmor is disabled on the host", name) } if name == "" { @@ -271,10 +280,10 @@ func CheckProfileAndLoadDefault(name string) (string, error) { // name. isLoaded, err := IsLoaded(name) if err != nil { - return "", errors.Wrapf(err, "verify if profile %s is loaded", name) + return "", fmt.Errorf("verify if profile %s is loaded: %w", name, err) } if !isLoaded { - return "", errors.Errorf("AppArmor profile %q specified but not loaded", name) + return "", fmt.Errorf("AppArmor profile %q specified but not loaded", name) } return name, nil } @@ -283,12 +292,12 @@ func CheckProfileAndLoadDefault(name string) (string, error) { // if it's loaded before installing it. isLoaded, err := IsLoaded(name) if err != nil { - return "", errors.Wrapf(err, "verify if profile %s is loaded", name) + return "", fmt.Errorf("verify if profile %s is loaded: %w", name, err) } if !isLoaded { err = InstallDefault(name) if err != nil { - return "", errors.Wrapf(err, "install profile %s", name) + return "", fmt.Errorf("install profile %s: %w", name, err) } logrus.Infof("Successfully loaded AppAmor profile %q", name) } else { diff --git a/pkg/apparmor/internal/supported/supported.go b/pkg/apparmor/internal/supported/supported.go index 778f4e3a2..1ee44156d 100644 --- a/pkg/apparmor/internal/supported/supported.go +++ b/pkg/apparmor/internal/supported/supported.go @@ -1,6 +1,8 @@ package supported import ( + "errors" + "fmt" "os" "os/exec" "path/filepath" @@ -8,7 +10,6 @@ import ( "github.com/containers/storage/pkg/unshare" runcaa "github.com/opencontainers/runc/libcontainer/apparmor" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -81,7 +82,7 @@ func (a *ApparmorVerifier) FindAppArmorParserBinary() (string, error) { return path, nil } - return "", errors.Errorf( + return "", fmt.Errorf( "%s binary neither found in %s nor $PATH", binary, sbin, ) } diff --git a/pkg/apparmor/internal/supported/supported_test.go b/pkg/apparmor/internal/supported/supported_test.go index aa29b8f93..6a3254309 100644 --- a/pkg/apparmor/internal/supported/supported_test.go +++ b/pkg/apparmor/internal/supported/supported_test.go @@ -1,12 +1,12 @@ package supported import ( + "errors" "io/ioutil" "os" "testing" "github.com/containers/common/pkg/apparmor/internal/supported/supportedfakes" - "github.com/pkg/errors" "github.com/stretchr/testify/require" ) diff --git a/pkg/auth/auth.go b/pkg/auth/auth.go index 188e06c12..770dc814d 100644 --- a/pkg/auth/auth.go +++ b/pkg/auth/auth.go @@ -3,6 +3,7 @@ package auth import ( "bufio" "context" + "errors" "fmt" "net/url" "os" @@ -14,7 +15,6 @@ import ( "github.com/containers/image/v5/pkg/docker/config" "github.com/containers/image/v5/pkg/sysregistriesv2" "github.com/containers/image/v5/types" - "github.com/pkg/errors" "github.com/sirupsen/logrus" terminal "golang.org/x/term" ) @@ -39,7 +39,7 @@ func CheckAuthFile(authfile string) error { return nil } if _, err := os.Stat(authfile); err != nil { - return errors.Wrap(err, "checking authfile") + return fmt.Errorf("checking authfile: %w", err) } return nil } @@ -97,12 +97,12 @@ func Login(ctx context.Context, systemContext *types.SystemContext, opts *LoginO authConfig, err := config.GetCredentials(systemContext, key) if err != nil { - return errors.Wrap(err, "get credentials") + return fmt.Errorf("get credentials: %w", err) } if opts.GetLoginSet { if authConfig.Username == "" { - return errors.Errorf("not logged into %s", key) + return fmt.Errorf("not logged into %s", key) } fmt.Fprintf(opts.Stdout, "%s\n", authConfig.Username) return nil @@ -139,7 +139,7 @@ func Login(ctx context.Context, systemContext *types.SystemContext, opts *LoginO username, password, err := getUserAndPass(opts, password, authConfig.Username) if err != nil { - return errors.Wrap(err, "getting username and password") + return fmt.Errorf("getting username and password: %w", err) } if err = docker.CheckAuth(ctx, systemContext, username, password, registry); err == nil { @@ -158,9 +158,9 @@ func Login(ctx context.Context, systemContext *types.SystemContext, opts *LoginO } if unauthorized, ok := err.(docker.ErrUnauthorizedForCredentials); ok { logrus.Debugf("error logging into %q: %v", key, unauthorized) - return errors.Errorf("error logging into %q: invalid username/password", key) + return fmt.Errorf("error logging into %q: invalid username/password", key) } - return errors.Wrapf(err, "authenticating creds for %q", key) + return fmt.Errorf("authenticating creds for %q: %w", key, err) } // parseCredentialsKey turns the provided argument into a valid credential key @@ -191,10 +191,10 @@ func parseCredentialsKey(arg string, acceptRepositories bool) (key, registry str // Ideally c/image should provide dedicated validation functionality. ref, err := reference.ParseNormalizedNamed(key) if err != nil { - return "", "", errors.Wrapf(err, "parse reference from %q", key) + return "", "", fmt.Errorf("parse reference from %q: %w", key, err) } if !reference.IsNameOnly(ref) { - return "", "", errors.Errorf("reference %q contains tag or digest", ref.String()) + return "", "", fmt.Errorf("reference %q contains tag or digest", ref.String()) } refRegistry := reference.Domain(ref) if refRegistry != registry { // This should never happen, check just to make sure @@ -232,7 +232,7 @@ func getUserAndPass(opts *LoginOptions, password, userFromAuthFile string) (user } username, err = reader.ReadString('\n') if err != nil { - return "", "", errors.Wrap(err, "reading username") + return "", "", fmt.Errorf("reading username: %w", err) } // If the user just hit enter, use the displayed user from the // the authentication file. This allows to do a lazy @@ -246,7 +246,7 @@ func getUserAndPass(opts *LoginOptions, password, userFromAuthFile string) (user fmt.Fprint(opts.Stdout, "Password: ") pass, err := terminal.ReadPassword(int(os.Stdin.Fd())) if err != nil { - return "", "", errors.Wrap(err, "reading password") + return "", "", fmt.Errorf("reading password: %w", err) } password = string(pass) fmt.Fprintln(opts.Stdout) @@ -298,14 +298,15 @@ func Logout(systemContext *types.SystemContext, opts *LogoutOptions, args []stri } err = config.RemoveAuthentication(systemContext, key) - switch errors.Cause(err) { - case nil: + if err == nil { fmt.Fprintf(opts.Stdout, "Removed login credentials for %s\n", key) return nil - case config.ErrNotLoggedIn: + } + + if errors.Is(err, config.ErrNotLoggedIn) { authConfig, err := config.GetCredentials(systemContext, key) if err != nil { - return errors.Wrap(err, "get credentials") + return fmt.Errorf("get credentials: %w", err) } authInvalid := docker.CheckAuth(context.Background(), systemContext, authConfig.Username, authConfig.Password, registry) @@ -313,10 +314,10 @@ func Logout(systemContext *types.SystemContext, opts *LogoutOptions, args []stri fmt.Printf("Not logged into %s with current tool. Existing credentials were established via docker login. Please use docker logout instead.\n", key) return nil } - return errors.Errorf("not logged into %s", key) - default: - return errors.Wrapf(err, "logging out of %q", key) + return fmt.Errorf("not logged into %s", key) } + + return fmt.Errorf("logging out of %q: %w", key, err) } // defaultRegistryWhenUnspecified returns first registry from search list of registry.conf @@ -324,7 +325,7 @@ func Logout(systemContext *types.SystemContext, opts *LogoutOptions, args []stri func defaultRegistryWhenUnspecified(systemContext *types.SystemContext) (string, error) { registriesFromFile, err := sysregistriesv2.UnqualifiedSearchRegistries(systemContext) if err != nil { - return "", errors.Wrap(err, "getting registry from registry.conf, please specify a registry") + return "", fmt.Errorf("getting registry from registry.conf, please specify a registry: %w", err) } if len(registriesFromFile) == 0 { return "", errors.New("no registries found in registries.conf, a registry must be provided") diff --git a/pkg/capabilities/capabilities.go b/pkg/capabilities/capabilities.go index b8e3fbcb5..3bf25e086 100644 --- a/pkg/capabilities/capabilities.go +++ b/pkg/capabilities/capabilities.go @@ -6,11 +6,12 @@ package capabilities // changed significantly to fit the needs of libpod. import ( + "errors" + "fmt" "sort" "strings" "sync" - "github.com/pkg/errors" "github.com/syndtr/gocapability/capability" ) @@ -115,7 +116,7 @@ func NormalizeCapabilities(caps []string) ([]string, error) { c = "CAP_" + c } if !stringInSlice(c, capabilityList) { - return nil, errors.Wrapf(ErrUnknownCapability, "%q", c) + return nil, fmt.Errorf("%q: %w", c, ErrUnknownCapability) } normalized = append(normalized, c) } @@ -127,7 +128,7 @@ func NormalizeCapabilities(caps []string) ([]string, error) { func ValidateCapabilities(caps []string) error { for _, c := range caps { if !stringInSlice(c, capabilityList) { - return errors.Wrapf(ErrUnknownCapability, "%q", c) + return fmt.Errorf("%q: %w", c, ErrUnknownCapability) } } return nil @@ -176,14 +177,14 @@ func MergeCapabilities(base, adds, drops []string) ([]string, error) { } else { for _, add := range capAdd { if stringInSlice(add, capDrop) { - return nil, errors.Errorf("capability %q cannot be dropped and added", add) + return nil, fmt.Errorf("capability %q cannot be dropped and added", add) } } } for _, drop := range capDrop { if stringInSlice(drop, capAdd) { - return nil, errors.Errorf("capability %q cannot be dropped and added", drop) + return nil, fmt.Errorf("capability %q cannot be dropped and added", drop) } } diff --git a/pkg/cgroups/blkio.go b/pkg/cgroups/blkio.go index a72a641c8..e157e6faf 100644 --- a/pkg/cgroups/blkio.go +++ b/pkg/cgroups/blkio.go @@ -5,6 +5,7 @@ package cgroups import ( "bufio" + "errors" "fmt" "os" "path/filepath" @@ -12,7 +13,6 @@ import ( "strings" spec "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" ) type blkioHandler struct{} @@ -101,10 +101,10 @@ func (c *blkioHandler) Stat(ctr *CgroupControl, m *Metrics) error { p := filepath.Join(BlkioRoot, "blkio.throttle.io_service_bytes_recursive") f, err := os.Open(p) if err != nil { - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { return nil } - return errors.Wrapf(err, "open %s", p) + return fmt.Errorf("open %s: %w", p, err) } defer f.Close() @@ -143,7 +143,7 @@ func (c *blkioHandler) Stat(ctr *CgroupControl, m *Metrics) error { ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry) } if err := scanner.Err(); err != nil { - return errors.Wrapf(err, "parse %s", p) + return fmt.Errorf("parse %s: %w", p, err) } } m.Blkio = BlkioMetrics{IoServiceBytesRecursive: ioServiceBytesRecursive} diff --git a/pkg/cgroups/blkio_linux.go b/pkg/cgroups/blkio_linux.go index 98b8ae541..ced461e69 100644 --- a/pkg/cgroups/blkio_linux.go +++ b/pkg/cgroups/blkio_linux.go @@ -5,6 +5,8 @@ package cgroups import ( "bufio" + "errors" + "fmt" "os" "path/filepath" "strconv" @@ -14,7 +16,6 @@ import ( "github.com/opencontainers/runc/libcontainer/cgroups/fs" "github.com/opencontainers/runc/libcontainer/cgroups/fs2" "github.com/opencontainers/runc/libcontainer/configs" - "github.com/pkg/errors" ) type linuxBlkioHandler struct { @@ -111,10 +112,10 @@ func (c *linuxBlkioHandler) Stat(ctr *CgroupControl, m *cgroups.Stats) error { p := filepath.Join(BlkioRoot, "blkio.throttle.io_service_bytes_recursive") f, err := os.Open(p) if err != nil { - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { return nil } - return errors.Wrapf(err, "open %s", p) + return fmt.Errorf("open %s: %w", p, err) } defer f.Close() @@ -153,7 +154,7 @@ func (c *linuxBlkioHandler) Stat(ctr *CgroupControl, m *cgroups.Stats) error { ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry) } if err := scanner.Err(); err != nil { - return errors.Wrapf(err, "parse %s", p) + return fmt.Errorf("parse %s: %w", p, err) } } m.BlkioStats.IoServiceBytesRecursive = ioServiceBytesRecursive diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go index eb903d3c3..9c93618df 100644 --- a/pkg/cgroups/cgroups.go +++ b/pkg/cgroups/cgroups.go @@ -6,6 +6,7 @@ package cgroups import ( "bufio" "context" + "errors" "fmt" "io/ioutil" "math" @@ -18,7 +19,6 @@ import ( systemdDbus "github.com/coreos/go-systemd/v22/dbus" "github.com/godbus/dbus/v5" spec "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -145,7 +145,7 @@ func getAvailableControllers(exclude map[string]controllerHandler, cgroup2 bool) } controllersFileBytes, err := ioutil.ReadFile(controllersFile) if err != nil { - return nil, errors.Wrapf(err, "failed while reading controllers for cgroup v2 from %q", controllersFile) + return nil, fmt.Errorf("failed while reading controllers for cgroup v2 from %q: %w", controllersFile, err) } for _, controllerName := range strings.Fields(string(controllersFileBytes)) { c := controller{ @@ -264,7 +264,7 @@ func (c *CgroupControl) initialize() (err error) { }() if c.cgroup2 { if err := createCgroupv2Path(filepath.Join(cgroupRoot, c.path)); err != nil { - return errors.Wrapf(err, "error creating cgroup path %s", c.path) + return fmt.Errorf("error creating cgroup path %s: %w", c.path, err) } } for name, handler := range handlers { @@ -285,7 +285,7 @@ func (c *CgroupControl) initialize() (err error) { } path := c.getCgroupv1Path(ctr.name) if err := os.MkdirAll(path, 0o755); err != nil { - return errors.Wrapf(err, "error creating cgroup path for %s", ctr.name) + return fmt.Errorf("error creating cgroup path for %s: %w", ctr.name, err) } } } @@ -304,7 +304,7 @@ func readFileAsUint64(path string) (uint64, error) { } ret, err := strconv.ParseUint(v, 10, 64) if err != nil { - return ret, errors.Wrapf(err, "parse %s from %s", v, path) + return ret, fmt.Errorf("parse %s from %s: %w", v, path, err) } return ret, nil } @@ -323,7 +323,7 @@ func readFileByKeyAsUint64(path, key string) (uint64, error) { } ret, err := strconv.ParseUint(v, 10, 64) if err != nil { - return ret, errors.Wrapf(err, "parse %s from %s", v, path) + return ret, fmt.Errorf("parse %s from %s: %w", v, path, err) } return ret, nil } @@ -498,7 +498,7 @@ func (c *CgroupControl) DeleteByPathConn(path string, conn *systemdDbus.Conn) er } p := c.getCgroupv1Path(ctr.name) if err := rmDirRecursively(p); err != nil { - lastError = errors.Wrapf(err, "remove %s", p) + lastError = fmt.Errorf("remove %s: %w", p, err) } } return lastError @@ -534,7 +534,7 @@ func (c *CgroupControl) AddPid(pid int) error { if c.cgroup2 { p := filepath.Join(cgroupRoot, c.path, "cgroup.procs") if err := ioutil.WriteFile(p, pidString, 0o644); err != nil { - return errors.Wrapf(err, "write %s", p) + return fmt.Errorf("write %s: %w", p, err) } return nil } @@ -557,7 +557,7 @@ func (c *CgroupControl) AddPid(pid int) error { } p := filepath.Join(c.getCgroupv1Path(n), "tasks") if err := ioutil.WriteFile(p, pidString, 0o644); err != nil { - return errors.Wrapf(err, "write %s", p) + return fmt.Errorf("write %s: %w", p, err) } } return nil @@ -569,7 +569,7 @@ func (c *CgroupControl) Stat() (*Metrics, error) { found := false for _, h := range handlers { if err := h.Stat(c, &m); err != nil { - if !os.IsNotExist(errors.Cause(err)) { + if !errors.Is(err, os.ErrNotExist) { return nil, err } logrus.Warningf("Failed to retrieve cgroup stats: %v", err) @@ -587,10 +587,10 @@ func readCgroup2MapPath(path string) (map[string][]string, error) { ret := map[string][]string{} f, err := os.Open(path) if err != nil { - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { return ret, nil } - return nil, errors.Wrapf(err, "open file %s", path) + return nil, fmt.Errorf("open file %s: %w", path, err) } defer f.Close() scanner := bufio.NewScanner(f) @@ -603,7 +603,7 @@ func readCgroup2MapPath(path string) (map[string][]string, error) { ret[parts[0]] = parts[1:] } if err := scanner.Err(); err != nil { - return nil, errors.Wrapf(err, "parsing file %s", path) + return nil, fmt.Errorf("parsing file %s: %w", path, err) } return ret, nil } diff --git a/pkg/cgroups/cgroups_linux.go b/pkg/cgroups/cgroups_linux.go index 4b72014bf..45f7bde29 100644 --- a/pkg/cgroups/cgroups_linux.go +++ b/pkg/cgroups/cgroups_linux.go @@ -6,6 +6,7 @@ package cgroups import ( "bufio" "context" + "errors" "fmt" "io/ioutil" "math" @@ -20,7 +21,6 @@ import ( "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/cgroups/fs2" "github.com/opencontainers/runc/libcontainer/configs" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -98,7 +98,7 @@ func getAvailableControllers(exclude map[string]controllerHandler, cgroup2 bool) } controllersFileBytes, err := ioutil.ReadFile(controllersFile) if err != nil { - return nil, errors.Wrapf(err, "failed while reading controllers for cgroup v2 from %q", controllersFile) + return nil, fmt.Errorf("failed while reading controllers for cgroup v2 from %q: %w", controllersFile, err) } for _, controllerName := range strings.Fields(string(controllersFileBytes)) { c := controller{ @@ -217,7 +217,7 @@ func (c *CgroupControl) initialize() (err error) { }() if c.cgroup2 { if err := createCgroupv2Path(filepath.Join(cgroupRoot, c.config.Path)); err != nil { - return errors.Wrapf(err, "error creating cgroup path %s", c.config.Path) + return fmt.Errorf("error creating cgroup path %s: %w", c.config.Path, err) } } for name, handler := range handlers { @@ -238,7 +238,7 @@ func (c *CgroupControl) initialize() (err error) { } path := c.getCgroupv1Path(ctr.name) if err := os.MkdirAll(path, 0o755); err != nil { - return errors.Wrapf(err, "error creating cgroup path for %s", ctr.name) + return fmt.Errorf("error creating cgroup path for %s: %w", ctr.name, err) } } } @@ -257,7 +257,7 @@ func readFileAsUint64(path string) (uint64, error) { } ret, err := strconv.ParseUint(v, 10, 64) if err != nil { - return ret, errors.Wrapf(err, "parse %s from %s", v, path) + return ret, fmt.Errorf("parse %s from %s: %w", v, path, err) } return ret, nil } @@ -276,7 +276,7 @@ func readFileByKeyAsUint64(path, key string) (uint64, error) { } ret, err := strconv.ParseUint(v, 10, 64) if err != nil { - return ret, errors.Wrapf(err, "parse %s from %s", v, path) + return ret, fmt.Errorf("parse %s from %s: %w", v, path, err) } return ret, nil } @@ -461,7 +461,7 @@ func (c *CgroupControl) DeleteByPathConn(path string, conn *systemdDbus.Conn) er } p := c.getCgroupv1Path(ctr.name) if err := rmDirRecursively(p); err != nil { - lastError = errors.Wrapf(err, "remove %s", p) + lastError = fmt.Errorf("remove %s: %w", p, err) } } return lastError @@ -517,7 +517,7 @@ func (c *CgroupControl) AddPid(pid int) error { } p := filepath.Join(c.getCgroupv1Path(n), "tasks") if err := ioutil.WriteFile(p, pidString, 0o644); err != nil { - return errors.Wrapf(err, "write %s", p) + return fmt.Errorf("write %s: %w", p, err) } } return nil @@ -529,7 +529,7 @@ func (c *CgroupControl) Stat() (*cgroups.Stats, error) { found := false for _, h := range handlers { if err := h.Stat(c, &m); err != nil { - if !os.IsNotExist(errors.Cause(err)) { + if !errors.Is(err, os.ErrNotExist) { return nil, err } logrus.Warningf("Failed to retrieve cgroup stats: %v", err) @@ -547,10 +547,10 @@ func readCgroup2MapPath(path string) (map[string][]string, error) { ret := map[string][]string{} f, err := os.Open(path) if err != nil { - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { return ret, nil } - return nil, errors.Wrapf(err, "open file %s", path) + return nil, fmt.Errorf("open file %s: %w", path, err) } defer f.Close() scanner := bufio.NewScanner(f) @@ -563,7 +563,7 @@ func readCgroup2MapPath(path string) (map[string][]string, error) { ret[parts[0]] = parts[1:] } if err := scanner.Err(); err != nil { - return nil, errors.Wrapf(err, "parsing file %s", path) + return nil, fmt.Errorf("parsing file %s: %w", path, err) } return ret, nil } diff --git a/pkg/cgroups/cgroups_supported.go b/pkg/cgroups/cgroups_supported.go index 3e7653672..419bc4ec3 100644 --- a/pkg/cgroups/cgroups_supported.go +++ b/pkg/cgroups/cgroups_supported.go @@ -5,6 +5,7 @@ package cgroups import ( "bufio" + "errors" "fmt" "io/ioutil" "os" @@ -15,7 +16,6 @@ import ( "syscall" "time" - "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -88,7 +88,7 @@ func UserOwnsCurrentSystemdCgroup() (bool, error) { } } if err := scanner.Err(); err != nil { - return false, errors.Wrapf(err, "parsing file /proc/self/cgroup") + return false, fmt.Errorf("parsing file /proc/self/cgroup: %w", err) } return true, nil } @@ -113,7 +113,7 @@ func rmDirRecursively(path string) error { } } - if err := os.Remove(path); err == nil || os.IsNotExist(err) { + if err := os.Remove(path); err == nil || errors.Is(err, os.ErrNotExist) { return nil } entries, err := ioutil.ReadDir(path) @@ -131,7 +131,7 @@ func rmDirRecursively(path string) error { attempts := 0 for { err := os.Remove(path) - if err == nil || os.IsNotExist(err) { + if err == nil || errors.Is(err, os.ErrNotExist) { return nil } if errors.Is(err, unix.EBUSY) { @@ -150,6 +150,6 @@ func rmDirRecursively(path string) error { continue } } - return errors.Wrapf(err, "remove %s", path) + return fmt.Errorf("remove %s: %w", path, err) } } diff --git a/pkg/cgroups/cpu.go b/pkg/cgroups/cpu.go index fff76b9e2..16293e74c 100644 --- a/pkg/cgroups/cpu.go +++ b/pkg/cgroups/cpu.go @@ -4,12 +4,12 @@ package cgroups import ( + "errors" "fmt" "os" "strconv" spec "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" ) type cpuHandler struct{} @@ -66,21 +66,21 @@ func (c *cpuHandler) Stat(ctr *CgroupControl, m *Metrics) error { } else { usage.Total, err = readAcct(ctr, "cpuacct.usage") if err != nil { - if !os.IsNotExist(errors.Cause(err)) { + if !errors.Is(err, os.ErrNotExist) { return err } usage.Total = 0 } usage.Kernel, err = readAcct(ctr, "cpuacct.usage_sys") if err != nil { - if !os.IsNotExist(errors.Cause(err)) { + if !errors.Is(err, os.ErrNotExist) { return err } usage.Kernel = 0 } usage.PerCPU, err = readAcctList(ctr, "cpuacct.usage_percpu") if err != nil { - if !os.IsNotExist(errors.Cause(err)) { + if !errors.Is(err, os.ErrNotExist) { return err } usage.PerCPU = nil diff --git a/pkg/cgroups/cpu_linux.go b/pkg/cgroups/cpu_linux.go index bca55575c..4931be6ef 100644 --- a/pkg/cgroups/cpu_linux.go +++ b/pkg/cgroups/cpu_linux.go @@ -4,6 +4,7 @@ package cgroups import ( + "errors" "os" "path/filepath" "strconv" @@ -12,7 +13,6 @@ import ( "github.com/opencontainers/runc/libcontainer/cgroups/fs" "github.com/opencontainers/runc/libcontainer/cgroups/fs2" "github.com/opencontainers/runc/libcontainer/configs" - "github.com/pkg/errors" ) type linuxCPUHandler struct { @@ -75,21 +75,21 @@ func (c *linuxCPUHandler) Stat(ctr *CgroupControl, m *cgroups.Stats) error { } else { cpu.CpuUsage.TotalUsage, err = readAcct(ctr, "cpuacct.usage") if err != nil { - if !os.IsNotExist(errors.Cause(err)) { + if !errors.Is(err, os.ErrNotExist) { return err } cpu.CpuUsage.TotalUsage = 0 } cpu.CpuUsage.UsageInKernelmode, err = readAcct(ctr, "cpuacct.usage_sys") if err != nil { - if !os.IsNotExist(errors.Cause(err)) { + if !errors.Is(err, os.ErrNotExist) { return err } cpu.CpuUsage.UsageInKernelmode = 0 } cpu.CpuUsage.PercpuUsage, err = readAcctList(ctr, "cpuacct.usage_percpu") if err != nil { - if !os.IsNotExist(errors.Cause(err)) { + if !errors.Is(err, os.ErrNotExist) { return err } cpu.CpuUsage.PercpuUsage = nil diff --git a/pkg/cgroups/utils.go b/pkg/cgroups/utils.go index 1fd45f40b..c7f86d7e1 100644 --- a/pkg/cgroups/utils.go +++ b/pkg/cgroups/utils.go @@ -2,14 +2,13 @@ package cgroups import ( "bytes" + "errors" "fmt" "io/ioutil" "os" "path/filepath" "strconv" "strings" - - "github.com/pkg/errors" ) var TestMode bool @@ -27,7 +26,7 @@ func readAcctList(ctr *CgroupControl, name string) ([]uint64, error) { p := filepath.Join(ctr.getCgroupv1Path(CPUAcct), name) data, err := ioutil.ReadFile(p) if err != nil { - return nil, errors.Wrapf(err, "reading %s", p) + return nil, fmt.Errorf("reading %s: %w", p, err) } r := []uint64{} for _, s := range strings.Split(string(data), " ") { @@ -37,7 +36,7 @@ func readAcctList(ctr *CgroupControl, name string) ([]uint64, error) { } v, err := strconv.ParseUint(s, 10, 64) if err != nil { - return nil, errors.Wrapf(err, "parsing %s", s) + return nil, fmt.Errorf("parsing %s: %w", s, err) } r = append(r, v) } @@ -93,7 +92,7 @@ func cpusetCopyFileFromParent(dir, file string, cgroupv2 bool) ([]byte, error) { } data, err := ioutil.ReadFile(parentPath) if err != nil { - return nil, errors.Wrapf(err, "open %s", path) + return nil, fmt.Errorf("open %s: %w", path, err) } if strings.Trim(string(data), "\n") != "" { return data, nil @@ -103,7 +102,7 @@ func cpusetCopyFileFromParent(dir, file string, cgroupv2 bool) ([]byte, error) { return nil, err } if err := ioutil.WriteFile(path, data, 0o644); err != nil { - return nil, errors.Wrapf(err, "write %s", path) + return nil, fmt.Errorf("write %s: %w", path, err) } return data, nil } @@ -165,12 +164,12 @@ func (c *CgroupControl) createCgroupDirectory(controller string) (bool, error) { return false, nil } - if !os.IsNotExist(err) { + if !errors.Is(err, os.ErrNotExist) { return false, err } if err := os.MkdirAll(cPath, 0o755); err != nil { - return false, errors.Wrapf(err, "error creating cgroup for %s", controller) + return false, fmt.Errorf("error creating cgroup for %s: %w", controller, err) } return true, nil } diff --git a/pkg/cgroups/utils_linux.go b/pkg/cgroups/utils_linux.go index bd37042cd..e4bd4d5df 100644 --- a/pkg/cgroups/utils_linux.go +++ b/pkg/cgroups/utils_linux.go @@ -5,6 +5,7 @@ package cgroups import ( "bytes" + "errors" "fmt" "os" "path" @@ -13,7 +14,6 @@ import ( "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/configs" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) diff --git a/pkg/chown/chown_unix.go b/pkg/chown/chown_unix.go index 61327fd24..be4b8cfa5 100644 --- a/pkg/chown/chown_unix.go +++ b/pkg/chown/chown_unix.go @@ -4,11 +4,10 @@ package chown import ( + "fmt" "os" "path/filepath" "syscall" - - "github.com/pkg/errors" ) // ChangeHostPathOwnership changes the uid and gid ownership of a directory or file within the host. @@ -17,11 +16,11 @@ func ChangeHostPathOwnership(path string, recursive bool, uid, gid int) error { // Validate if host path can be chowned isDangerous, err := DangerousHostPath(path) if err != nil { - return errors.Wrap(err, "failed to validate if host path is dangerous") + return fmt.Errorf("failed to validate if host path is dangerous: %w", err) } if isDangerous { - return errors.Errorf("chowning host path %q is not allowed. You can manually `chown -R %d:%d %s`", path, uid, gid, path) + return fmt.Errorf("chowning host path %q is not allowed. You can manually `chown -R %d:%d %s`", path, uid, gid, path) } // Chown host path @@ -42,13 +41,13 @@ func ChangeHostPathOwnership(path string, recursive bool, uid, gid int) error { return nil }) if err != nil { - return errors.Wrap(err, "failed to chown recursively host path") + return fmt.Errorf("failed to chown recursively host path: %w", err) } } else { // Get host path info f, err := os.Lstat(path) if err != nil { - return errors.Wrap(err, "failed to get host path information") + return fmt.Errorf("failed to get host path information: %w", err) } // Get current ownership @@ -57,7 +56,7 @@ func ChangeHostPathOwnership(path string, recursive bool, uid, gid int) error { if uid != currentUID || gid != currentGID { if err := os.Lchown(path, uid, gid); err != nil { - return errors.Wrap(err, "failed to chown host path") + return fmt.Errorf("failed to chown host path: %w", err) } } } diff --git a/pkg/chown/chown_windows.go b/pkg/chown/chown_windows.go index 0c4b8e1b5..8f3bba7ef 100644 --- a/pkg/chown/chown_windows.go +++ b/pkg/chown/chown_windows.go @@ -1,7 +1,7 @@ package chown import ( - "github.com/pkg/errors" + "errors" ) // ChangeHostPathOwnership changes the uid and gid ownership of a directory or file within the host. diff --git a/pkg/config/config.go b/pkg/config/config.go index e3d19ee88..bdceb28b3 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -694,7 +694,7 @@ func addConfigs(dirPath string, configs []string) ([]string, error) { } }, ) - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { err = nil } sort.Strings(newConfigs) @@ -1152,7 +1152,7 @@ func ReadCustomConfig() (*Config, error) { return nil, err } } else { - if !os.IsNotExist(err) { + if !errors.Is(err, os.ErrNotExist) { return nil, err } } diff --git a/pkg/configmaps/configmaps.go b/pkg/configmaps/configmaps.go index a607853f8..e0670b74f 100644 --- a/pkg/configmaps/configmaps.go +++ b/pkg/configmaps/configmaps.go @@ -1,6 +1,8 @@ package configmaps import ( + "errors" + "fmt" "os" "path/filepath" "regexp" @@ -10,7 +12,6 @@ import ( "github.com/containers/common/pkg/configmaps/filedriver" "github.com/containers/storage/pkg/lockfile" "github.com/containers/storage/pkg/stringid" - "github.com/pkg/errors" ) // maxConfigMapSize is the max size for configMap data - 512kB @@ -99,7 +100,7 @@ func NewManager(rootPath string) (*ConfigMapManager, error) { manager := new(ConfigMapManager) if !filepath.IsAbs(rootPath) { - return nil, errors.Wrapf(errInvalidPath, "path must be absolute: %s", rootPath) + return nil, fmt.Errorf("path must be absolute: %s: %w", rootPath, errInvalidPath) } // the lockfile functions require that the rootPath dir is executable if err := os.MkdirAll(rootPath, 0o700); err != nil { @@ -140,7 +141,7 @@ func (s *ConfigMapManager) Store(name string, data []byte, driverType string, dr return "", err } if exist { - return "", errors.Wrapf(errConfigMapNameInUse, name) + return "", fmt.Errorf("%s: %w", name, errConfigMapNameInUse) } secr := new(ConfigMap) @@ -152,7 +153,7 @@ func (s *ConfigMapManager) Store(name string, data []byte, driverType string, dr newID = newID[0:configMapIDLength] _, err := s.lookupConfigMap(newID) if err != nil { - if errors.Cause(err) == ErrNoSuchConfigMap { + if errors.Is(err, ErrNoSuchConfigMap) { secr.ID = newID break } else { @@ -172,12 +173,12 @@ func (s *ConfigMapManager) Store(name string, data []byte, driverType string, dr } err = driver.Store(secr.ID, data) if err != nil { - return "", errors.Wrapf(err, "error creating configMap %s", name) + return "", fmt.Errorf("error creating configMap %s: %w", name, err) } err = s.store(secr) if err != nil { - return "", errors.Wrapf(err, "error creating configMap %s", name) + return "", fmt.Errorf("error creating configMap %s: %w", name, err) } return secr.ID, nil @@ -207,12 +208,12 @@ func (s *ConfigMapManager) Delete(nameOrID string) (string, error) { err = driver.Delete(configMapID) if err != nil { - return "", errors.Wrapf(err, "error deleting configMap %s", nameOrID) + return "", fmt.Errorf("error deleting configMap %s: %w", nameOrID, err) } err = s.delete(configMapID) if err != nil { - return "", errors.Wrapf(err, "error deleting configMap %s", nameOrID) + return "", fmt.Errorf("error deleting configMap %s: %w", nameOrID, err) } return configMapID, nil } @@ -265,7 +266,7 @@ func (s *ConfigMapManager) LookupConfigMapData(nameOrID string) (*ConfigMap, []b // validateConfigMapName checks if the configMap name is valid. func validateConfigMapName(name string) error { if !configMapNameRegexp.MatchString(name) || len(name) > 64 || strings.HasSuffix(name, "-") || strings.HasSuffix(name, ".") { - return errors.Wrapf(errInvalidConfigMapName, "only 64 [a-zA-Z0-9-_.] characters allowed, and the start and end character must be [a-zA-Z0-9]: %s", name) + return fmt.Errorf("only 64 [a-zA-Z0-9-_.] characters allowed, and the start and end character must be [a-zA-Z0-9]: %s: %w", name, errInvalidConfigMapName) } return nil } @@ -276,7 +277,7 @@ func getDriver(name string, opts map[string]string) (ConfigMapsDriver, error) { if path, ok := opts["path"]; ok { return filedriver.NewDriver(path) } - return nil, errors.Wrap(errInvalidDriverOpt, "need path for filedriver") + return nil, fmt.Errorf("need path for filedriver: %w", errInvalidDriverOpt) } return nil, errInvalidDriver } diff --git a/pkg/configmaps/configmapsdb.go b/pkg/configmaps/configmapsdb.go index ce1bbc7bd..c4cd272f8 100644 --- a/pkg/configmaps/configmapsdb.go +++ b/pkg/configmaps/configmapsdb.go @@ -2,12 +2,12 @@ package configmaps import ( "encoding/json" + "errors" + "fmt" "io/ioutil" "os" "strings" "time" - - "github.com/pkg/errors" ) type db struct { @@ -70,21 +70,21 @@ func (s *ConfigMapManager) getNameAndID(nameOrID string) (name, id string, err e name, id, err = s.getExactNameAndID(nameOrID) if err == nil { return name, id, nil - } else if errors.Cause(err) != ErrNoSuchConfigMap { + } else if !errors.Is(err, ErrNoSuchConfigMap) { return "", "", err } // ID prefix may have been given, iterate through all IDs. // ID and partial ID has a max length of 25, so we return if its greater than that. if len(nameOrID) > configMapIDLength { - return "", "", errors.Wrapf(ErrNoSuchConfigMap, "no configmap with name or id %q", nameOrID) + return "", "", fmt.Errorf("no configmap with name or id %q: %w", nameOrID, ErrNoSuchConfigMap) } exists := false var foundID, foundName string for id, name := range s.db.IDToName { if strings.HasPrefix(id, nameOrID) { if exists { - return "", "", errors.Wrapf(errAmbiguous, "more than one result configmap with prefix %s", nameOrID) + return "", "", fmt.Errorf("more than one result configmap with prefix %s: %w", nameOrID, errAmbiguous) } exists = true foundID = id @@ -95,7 +95,7 @@ func (s *ConfigMapManager) getNameAndID(nameOrID string) (name, id string, err e if exists { return foundName, foundID, nil } - return "", "", errors.Wrapf(ErrNoSuchConfigMap, "no configmap with name or id %q", nameOrID) + return "", "", fmt.Errorf("no configmap with name or id %q: %w", nameOrID, ErrNoSuchConfigMap) } // getExactNameAndID takes a configmap's name or ID and returns both its name and full ID. @@ -114,7 +114,7 @@ func (s *ConfigMapManager) getExactNameAndID(nameOrID string) (name, id string, return name, id, nil } - return "", "", errors.Wrapf(ErrNoSuchConfigMap, "no configmap with name or id %q", nameOrID) + return "", "", fmt.Errorf("no configmap with name or id %q: %w", nameOrID, ErrNoSuchConfigMap) } // exactConfigMapExists checks if the configmap exists, given a name or ID @@ -122,7 +122,7 @@ func (s *ConfigMapManager) getExactNameAndID(nameOrID string) (name, id string, func (s *ConfigMapManager) exactConfigMapExists(nameOrID string) (bool, error) { _, _, err := s.getExactNameAndID(nameOrID) if err != nil { - if errors.Cause(err) == ErrNoSuchConfigMap { + if errors.Is(err, ErrNoSuchConfigMap) { return false, nil } return false, err @@ -157,7 +157,7 @@ func (s *ConfigMapManager) lookupConfigMap(nameOrID string) (*ConfigMap, error) return &configmap, nil } - return nil, errors.Wrapf(ErrNoSuchConfigMap, "no configmap with name or id %q", nameOrID) + return nil, fmt.Errorf("no configmap with name or id %q: %w", nameOrID, ErrNoSuchConfigMap) } // Store creates a new configmap in the configmaps database. diff --git a/pkg/configmaps/filedriver/filedriver.go b/pkg/configmaps/filedriver/filedriver.go index 801a5c9d9..8ced4467b 100644 --- a/pkg/configmaps/filedriver/filedriver.go +++ b/pkg/configmaps/filedriver/filedriver.go @@ -2,13 +2,14 @@ package filedriver import ( "encoding/json" + "errors" + "fmt" "io/ioutil" "os" "path/filepath" "sort" "github.com/containers/storage/pkg/lockfile" - "github.com/pkg/errors" ) // configMapsDataFile is the file where configMaps data/payload will be stored @@ -75,7 +76,7 @@ func (d *Driver) Lookup(id string) ([]byte, error) { if data, ok := configMapData[id]; ok { return data, nil } - return nil, errors.Wrapf(errNoSecretData, "%s", id) + return nil, fmt.Errorf("%s: %w", id, errNoSecretData) } // Store stores the bytes associated with an ID. An error is returned if the ID arleady exists @@ -88,7 +89,7 @@ func (d *Driver) Store(id string, data []byte) error { return err } if _, ok := configMapData[id]; ok { - return errors.Wrapf(errSecretIDExists, "%s", id) + return fmt.Errorf("%s: %w", id, errSecretIDExists) } configMapData[id] = data marshalled, err := json.MarshalIndent(configMapData, "", " ") @@ -113,7 +114,7 @@ func (d *Driver) Delete(id string) error { if _, ok := configMapData[id]; ok { delete(configMapData, id) } else { - return errors.Wrap(errNoSecretData, id) + return fmt.Errorf("%s: %w", id, errNoSecretData) } marshalled, err := json.MarshalIndent(configMapData, "", " ") if err != nil { @@ -131,7 +132,7 @@ func (d *Driver) getAllData() (map[string][]byte, error) { // check if the db file exists _, err := os.Stat(d.configMapsDataFilePath) if err != nil { - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { // the file will be created later on a store() return make(map[string][]byte), nil } diff --git a/pkg/filters/filters.go b/pkg/filters/filters.go index 53650efc9..dee66107f 100644 --- a/pkg/filters/filters.go +++ b/pkg/filters/filters.go @@ -8,14 +8,13 @@ import ( "time" "github.com/containers/common/pkg/timetype" - "github.com/pkg/errors" ) // ComputeUntilTimestamp extracts until timestamp from filters func ComputeUntilTimestamp(filterValues []string) (time.Time, error) { invalid := time.Time{} if len(filterValues) != 1 { - return invalid, errors.Errorf("specify exactly one timestamp for until") + return invalid, fmt.Errorf("specify exactly one timestamp for until") } ts, err := timetype.GetTimestamp(filterValues[0], time.Now()) if err != nil { diff --git a/pkg/formats/formats.go b/pkg/formats/formats.go index 2058be094..8d3090ad9 100644 --- a/pkg/formats/formats.go +++ b/pkg/formats/formats.go @@ -11,7 +11,6 @@ import ( "text/template" "github.com/ghodss/yaml" - "github.com/pkg/errors" terminal "golang.org/x/term" ) @@ -98,7 +97,7 @@ func (t StdoutTemplateArray) Out() error { t.Template = strings.ReplaceAll(strings.TrimSpace(t.Template[5:]), " ", "\t") headerTmpl, err := template.New("header").Funcs(headerFunctions).Parse(t.Template) if err != nil { - return errors.Wrap(err, parsingErrorStr) + return fmt.Errorf("%s: %w", parsingErrorStr, err) } err = headerTmpl.Execute(w, t.Fields) if err != nil { @@ -109,12 +108,12 @@ func (t StdoutTemplateArray) Out() error { t.Template = strings.ReplaceAll(t.Template, " ", "\t") tmpl, err := template.New("image").Funcs(basicFunctions).Parse(t.Template) if err != nil { - return errors.Wrap(err, parsingErrorStr) + return fmt.Errorf("%s: %w", parsingErrorStr, err) } for _, raw := range t.Output { basicTmpl := tmpl.Funcs(basicFunctions) if err := basicTmpl.Execute(w, raw); err != nil { - return errors.Wrap(err, parsingErrorStr) + return fmt.Errorf("%s: %w", parsingErrorStr, err) } fmt.Fprintln(w, "") } @@ -136,7 +135,7 @@ func (j JSONStruct) Out() error { func (t StdoutTemplate) Out() error { tmpl, err := template.New("image").Parse(t.Template) if err != nil { - return errors.Wrap(err, "template parsing error") + return fmt.Errorf("template parsing error: %w", err) } err = tmpl.Execute(os.Stdout, t.Output) if err != nil { diff --git a/pkg/hooks/1.0.0/hook.go b/pkg/hooks/1.0.0/hook.go index 244e8800f..71f940a64 100644 --- a/pkg/hooks/1.0.0/hook.go +++ b/pkg/hooks/1.0.0/hook.go @@ -3,12 +3,12 @@ package hook import ( "encoding/json" + "errors" "fmt" "os" "regexp" rspec "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" ) // Version is the hook configuration version defined in this package. @@ -50,16 +50,16 @@ func (hook *Hook) Validate(extensionStages []string) (err error) { for key, value := range hook.When.Annotations { if _, err = regexp.Compile(key); err != nil { - return errors.Wrapf(err, "invalid annotation key %q", key) + return fmt.Errorf("invalid annotation key %q: %w", key, err) } if _, err = regexp.Compile(value); err != nil { - return errors.Wrapf(err, "invalid annotation value %q", value) + return fmt.Errorf("invalid annotation value %q: %w", value, err) } } for _, command := range hook.When.Commands { if _, err = regexp.Compile(command); err != nil { - return errors.Wrapf(err, "invalid command %q", command) + return fmt.Errorf("invalid command %q: %w", command, err) } } diff --git a/pkg/hooks/1.0.0/hook_test.go b/pkg/hooks/1.0.0/hook_test.go index bd6d6b654..803dd98c7 100644 --- a/pkg/hooks/1.0.0/hook_test.go +++ b/pkg/hooks/1.0.0/hook_test.go @@ -1,6 +1,7 @@ package hook import ( + "errors" "os" "path/filepath" "runtime" @@ -99,7 +100,7 @@ func TestUnknownHookPath(t *testing.T) { t.Fatal("unexpected success") } assert.Regexp(t, "^stat does/not/exist: no such file or directory$", err.Error()) - if !os.IsNotExist(err) { + if !errors.Is(err, os.ErrNotExist) { t.Fatal("opaque wrapping for not-exist errors") } } diff --git a/pkg/hooks/1.0.0/when.go b/pkg/hooks/1.0.0/when.go index a65af048e..a1351890f 100644 --- a/pkg/hooks/1.0.0/when.go +++ b/pkg/hooks/1.0.0/when.go @@ -1,10 +1,11 @@ package hook import ( + "errors" + "fmt" "regexp" rspec "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" ) // When holds hook-injection conditions. @@ -52,12 +53,12 @@ func (when *When) Match(config *rspec.Spec, annotations map[string]string, hasBi for key, value := range annotations { match, err = regexp.MatchString(keyPattern, key) if err != nil { - return false, errors.Wrap(err, "annotation key") + return false, fmt.Errorf("annotation key: %w", err) } if match { match, err = regexp.MatchString(valuePattern, value) if err != nil { - return false, errors.Wrap(err, "annotation value") + return false, fmt.Errorf("annotation value: %w", err) } if match { break @@ -82,7 +83,7 @@ func (when *When) Match(config *rspec.Spec, annotations map[string]string, hasBi for _, cmdPattern := range when.Commands { match, err := regexp.MatchString(cmdPattern, command) if err != nil { - return false, errors.Wrap(err, "command") + return false, fmt.Errorf("command: %w", err) } if match { return true, nil diff --git a/pkg/hooks/exec/exec.go b/pkg/hooks/exec/exec.go index 2b7bc5f31..bc639245f 100644 --- a/pkg/hooks/exec/exec.go +++ b/pkg/hooks/exec/exec.go @@ -10,7 +10,6 @@ import ( "time" rspec "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -46,7 +45,7 @@ func Run(ctx context.Context, hook *rspec.Hook, state []byte, stdout io.Writer, go func() { err := cmd.Wait() if err != nil { - err = errors.Wrapf(err, "executing %v", cmd.Args) + err = fmt.Errorf("executing %v: %w", cmd.Args, err) } exit <- err }() diff --git a/pkg/hooks/exec/exec_test.go b/pkg/hooks/exec/exec_test.go index 1e105373d..9b8883f03 100644 --- a/pkg/hooks/exec/exec_test.go +++ b/pkg/hooks/exec/exec_test.go @@ -3,6 +3,7 @@ package exec import ( "bytes" "context" + "errors" "fmt" "os" "runtime" @@ -63,7 +64,7 @@ func TestRunFailedStart(t *testing.T) { if err == nil { t.Fatal("unexpected success") } - if !os.IsNotExist(err) { + if !errors.Is(err, os.ErrNotExist) { t.Fatal(err) } assert.Equal(t, err, hookErr) diff --git a/pkg/hooks/exec/runtimeconfigfilter.go b/pkg/hooks/exec/runtimeconfigfilter.go index 3ab3073b2..72d4b8979 100644 --- a/pkg/hooks/exec/runtimeconfigfilter.go +++ b/pkg/hooks/exec/runtimeconfigfilter.go @@ -4,12 +4,12 @@ import ( "bytes" "context" "encoding/json" + "fmt" "reflect" "time" "github.com/davecgh/go-spew/spew" spec "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" "github.com/pmezard/go-difflib/difflib" "github.com/sirupsen/logrus" ) @@ -43,7 +43,7 @@ func RuntimeConfigFilter(ctx context.Context, hooks []spec.Hook, config *spec.Sp err = json.Unmarshal(data, &newConfig) if err != nil { logrus.Debugf("invalid JSON from config-filter hook %d:\n%s", i, string(data)) - return nil, errors.Wrapf(err, "unmarshal output from config-filter hook %d", i) + return nil, fmt.Errorf("unmarshal output from config-filter hook %d: %w", i, err) } if !reflect.DeepEqual(config, &newConfig) { diff --git a/pkg/hooks/exec/runtimeconfigfilter_test.go b/pkg/hooks/exec/runtimeconfigfilter_test.go index 2c8ab1515..0e7901bc5 100644 --- a/pkg/hooks/exec/runtimeconfigfilter_test.go +++ b/pkg/hooks/exec/runtimeconfigfilter_test.go @@ -3,12 +3,12 @@ package exec import ( "context" "encoding/json" + "errors" "os" "testing" "time" spec "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" ) @@ -18,13 +18,14 @@ func TestRuntimeConfigFilter(t *testing.T) { rootUint32 := uint32(0) binUser := int(1) for _, tt := range []struct { - name string - contextTimeout time.Duration - hooks []spec.Hook - input *spec.Spec - expected *spec.Spec - expectedHookError string - expectedRunError error + name string + contextTimeout time.Duration + hooks []spec.Hook + input *spec.Spec + expected *spec.Spec + expectedHookError string + expectedRunError error + expectedRunErrorString string }{ { name: "no-op", @@ -231,7 +232,7 @@ func TestRuntimeConfigFilter(t *testing.T) { Path: "rootfs", }, }, - expectedRunError: unexpectedEndOfJSONInput, + expectedRunErrorString: unexpectedEndOfJSONInput.Error(), }, } { test := tt @@ -243,7 +244,13 @@ func TestRuntimeConfigFilter(t *testing.T) { defer cancel() } hookErr, err := RuntimeConfigFilter(ctx, test.hooks, test.input, DefaultPostKillTimeout) - assert.Equal(t, test.expectedRunError, errors.Cause(err)) + if test.expectedRunErrorString != "" { + // We have to compare the error strings in that case because + // errors.Is works differently. + assert.Contains(t, err.Error(), test.expectedRunErrorString) + } else { + assert.True(t, errors.Is(err, test.expectedRunError)) + } if test.expectedHookError == "" { if hookErr != nil { t.Fatal(hookErr) diff --git a/pkg/hooks/hooks.go b/pkg/hooks/hooks.go index e7212a5b4..6d3747e55 100644 --- a/pkg/hooks/hooks.go +++ b/pkg/hooks/hooks.go @@ -3,6 +3,7 @@ package hooks import ( "context" + "errors" "fmt" "os" "sort" @@ -11,7 +12,6 @@ import ( current "github.com/containers/common/pkg/hooks/1.0.0" rspec "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -57,7 +57,7 @@ func New(ctx context.Context, directories []string, extensionStages []string) (m for _, dir := range directories { err = ReadDir(dir, manager.extensionStages, manager.hooks) - if err != nil && !os.IsNotExist(err) { + if err != nil && !errors.Is(err, os.ErrNotExist) { return nil, err } } @@ -105,7 +105,7 @@ func (m *Manager) Hooks(config *rspec.Spec, annotations map[string]string, hasBi for _, namedHook := range hooks { match, err := namedHook.hook.When.Match(config, annotations, hasBindMounts) if err != nil { - return extensionStageHooks, errors.Wrapf(err, "matching hook %q", namedHook.name) + return extensionStageHooks, fmt.Errorf("matching hook %q: %w", namedHook.name, err) } if match { logrus.Debugf("hook %s matched; adding to stages %v", namedHook.name, namedHook.hook.Stages) diff --git a/pkg/hooks/monitor_test.go b/pkg/hooks/monitor_test.go index 7da85539a..9e80a1bbb 100644 --- a/pkg/hooks/monitor_test.go +++ b/pkg/hooks/monitor_test.go @@ -2,6 +2,7 @@ package hooks import ( "context" + "errors" "fmt" "io/ioutil" "os" @@ -318,7 +319,7 @@ func TestMonitorBadWatcher(t *testing.T) { sync := make(chan error, 2) go manager.Monitor(ctx, sync) err = <-sync - if !os.IsNotExist(err) { + if !errors.Is(err, os.ErrNotExist) { t.Fatal("opaque wrapping for not-exist errors") } } diff --git a/pkg/hooks/read.go b/pkg/hooks/read.go index b59f00b2c..25cf7be99 100644 --- a/pkg/hooks/read.go +++ b/pkg/hooks/read.go @@ -3,6 +3,8 @@ package hooks import ( "encoding/json" + "errors" + "fmt" "io/ioutil" "os" "path/filepath" @@ -10,7 +12,6 @@ import ( old "github.com/containers/common/pkg/hooks/0.1.0" current "github.com/containers/common/pkg/hooks/1.0.0" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -36,7 +37,7 @@ func Read(path string, extensionStages []string) (*current.Hook, error) { } hook, err := read(content) if err != nil { - return nil, errors.Wrapf(err, "parsing hook %q", path) + return nil, fmt.Errorf("parsing hook %q: %w", path, err) } err = hook.Validate(extensionStages) return hook, err @@ -45,16 +46,16 @@ func Read(path string, extensionStages []string) (*current.Hook, error) { func read(content []byte) (hook *current.Hook, err error) { var ver version if err := json.Unmarshal(content, &ver); err != nil { - return nil, errors.Wrap(err, "version check") + return nil, fmt.Errorf("version check: %w", err) } reader, ok := Readers[ver.Version] if !ok { - return nil, errors.Errorf("unrecognized hook version: %q", ver.Version) + return nil, fmt.Errorf("unrecognized hook version: %q", ver.Version) } hook, err = reader(content) if err != nil { - return hook, errors.Wrap(err, ver.Version) + return hook, fmt.Errorf("%s: %v", ver.Version, err) } return hook, err } @@ -75,7 +76,7 @@ func ReadDir(path string, extensionStages []string, hooks map[string]*current.Ho if err == ErrNoJSONSuffix { continue } - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { if err2, ok := err.(*os.PathError); ok && err2.Path == filePath { continue } @@ -83,7 +84,7 @@ func ReadDir(path string, extensionStages []string, hooks map[string]*current.Ho if res == nil { res = err } else { - res = errors.Wrapf(res, "%v", err) + res = fmt.Errorf("%v: %w", err, res) } continue } diff --git a/pkg/hooks/read_test.go b/pkg/hooks/read_test.go index 37c446b29..e7fad448d 100644 --- a/pkg/hooks/read_test.go +++ b/pkg/hooks/read_test.go @@ -1,6 +1,7 @@ package hooks import ( + "errors" "fmt" "io/ioutil" "os" @@ -23,7 +24,7 @@ func TestUnknownPath(t *testing.T) { t.Fatal("unexpected success") } assert.Regexp(t, "^open does/not/exist.json: no such file or directory$", err.Error()) - if !os.IsNotExist(err) { + if !errors.Is(err, os.ErrNotExist) { t.Fatal("opaque wrapping for not-exist errors") } } @@ -154,7 +155,7 @@ func TestUnknownDir(t *testing.T) { t.Fatal("unexpected success") } assert.Regexp(t, "^open does/not/exist: no such file or directory$", err.Error()) - if !os.IsNotExist(err) { + if !errors.Is(err, os.ErrNotExist) { t.Fatal("opaque wrapping for not-exist errors") } } diff --git a/pkg/manifests/manifests.go b/pkg/manifests/manifests.go index 75ffac06c..d2279ab0e 100644 --- a/pkg/manifests/manifests.go +++ b/pkg/manifests/manifests.go @@ -2,13 +2,14 @@ package manifests import ( "encoding/json" + "errors" + "fmt" "os" "github.com/containers/image/v5/manifest" digest "github.com/opencontainers/go-digest" imgspec "github.com/opencontainers/image-spec/specs-go" v1 "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" ) // List is a generic interface for manipulating a manifest list or an image @@ -73,7 +74,7 @@ func Create() List { // AddInstance adds an entry for the specified manifest digest, with assorted // additional information specified in parameters, to the list or index. func (l *list) AddInstance(manifestDigest digest.Digest, manifestSize int64, manifestType, osName, architecture, osVersion string, osFeatures []string, variant string, features, annotations []string) error { - if err := l.Remove(manifestDigest); err != nil && !os.IsNotExist(errors.Cause(err)) { + if err := l.Remove(manifestDigest); err != nil && !errors.Is(err, os.ErrNotExist) { return err } @@ -113,7 +114,7 @@ func (l *list) AddInstance(manifestDigest digest.Digest, manifestSize int64, man // Remove filters out any instances in the list which match the specified digest. func (l *list) Remove(instanceDigest digest.Digest) error { - err := errors.Wrapf(os.ErrNotExist, "no instance matching digest %q found in manifest list", instanceDigest) + err := fmt.Errorf("no instance matching digest %q found in manifest list: %w", instanceDigest, os.ErrNotExist) newDockerManifests := make([]manifest.Schema2ManifestDescriptor, 0, len(l.docker.Manifests)) for i := range l.docker.Manifests { if l.docker.Manifests[i].Digest != instanceDigest { @@ -141,7 +142,7 @@ func (l *list) findDocker(instanceDigest digest.Digest) (*manifest.Schema2Manife return &l.docker.Manifests[i], nil } } - return nil, errors.Wrapf(ErrDigestNotFound, "no Docker manifest matching digest %q was found in list", instanceDigest.String()) + return nil, fmt.Errorf("no Docker manifest matching digest %q was found in list: %w", instanceDigest.String(), ErrDigestNotFound) } func (l *list) findOCIv1(instanceDigest digest.Digest) (*v1.Descriptor, error) { @@ -150,7 +151,7 @@ func (l *list) findOCIv1(instanceDigest digest.Digest) (*v1.Descriptor, error) { return &l.oci.Manifests[i], nil } } - return nil, errors.Wrapf(ErrDigestNotFound, "no OCI manifest matching digest %q was found in list", instanceDigest.String()) + return nil, fmt.Errorf("no OCI manifest matching digest %q was found in list: %w", instanceDigest.String(), ErrDigestNotFound) } // SetURLs sets the URLs where the manifest might also be found. @@ -370,10 +371,10 @@ func FromBlob(manifestBytes []byte) (List, error) { } switch manifestType { default: - return nil, errors.Wrapf(ErrManifestTypeNotSupported, "unable to load manifest list: unsupported format %q", manifestType) + return nil, fmt.Errorf("unable to load manifest list: unsupported format %q: %w", manifestType, ErrManifestTypeNotSupported) case manifest.DockerV2ListMediaType: if err := json.Unmarshal(manifestBytes, &list.docker); err != nil { - return nil, errors.Wrapf(err, "unable to parse Docker manifest list from image") + return nil, fmt.Errorf("unable to parse Docker manifest list from image: %w", err) } for _, m := range list.docker.Manifests { list.oci.Manifests = append(list.oci.Manifests, v1.Descriptor{ @@ -391,7 +392,7 @@ func FromBlob(manifestBytes []byte) (List, error) { } case v1.MediaTypeImageIndex: if err := json.Unmarshal(manifestBytes, &list.oci); err != nil { - return nil, errors.Wrapf(err, "unable to parse OCIv1 manifest list") + return nil, fmt.Errorf("unable to parse OCIv1 manifest list: %w", err) } for _, m := range list.oci.Manifests { platform := m.Platform @@ -451,26 +452,26 @@ func (l *list) Serialize(mimeType string) ([]byte, error) { if l.preferOCI() { res, err = json.Marshal(&l.oci) if err != nil { - return nil, errors.Wrapf(err, "error marshalling OCI image index") + return nil, fmt.Errorf("error marshalling OCI image index: %w", err) } } else { res, err = json.Marshal(&l.docker) if err != nil { - return nil, errors.Wrapf(err, "error marshalling Docker manifest list") + return nil, fmt.Errorf("error marshalling Docker manifest list: %w", err) } } case v1.MediaTypeImageIndex: res, err = json.Marshal(&l.oci) if err != nil { - return nil, errors.Wrapf(err, "error marshalling OCI image index") + return nil, fmt.Errorf("error marshalling OCI image index: %w", err) } case manifest.DockerV2ListMediaType: res, err = json.Marshal(&l.docker) if err != nil { - return nil, errors.Wrapf(err, "error marshalling Docker manifest list") + return nil, fmt.Errorf("error marshalling Docker manifest list: %w", err) } default: - return nil, errors.Wrapf(ErrManifestTypeNotSupported, "serializing list to type %q not implemented", mimeType) + return nil, fmt.Errorf("serializing list to type %q not implemented: %w", mimeType, ErrManifestTypeNotSupported) } return res, nil } diff --git a/pkg/parse/parse.go b/pkg/parse/parse.go index 43b783e0c..15e932129 100644 --- a/pkg/parse/parse.go +++ b/pkg/parse/parse.go @@ -4,12 +4,12 @@ package parse // user input and is shared either amongst container engine subcommands import ( + "errors" + "fmt" "os" "path" "path/filepath" "strings" - - "github.com/pkg/errors" ) // ValidateVolumeOpts validates a volume's options @@ -21,7 +21,7 @@ func ValidateVolumeOpts(options []string) ([]string, error) { if strings.Contains(opt, "upperdir") { foundUpperDir++ if foundUpperDir > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 upperdir per overlay", strings.Join(options, ", ")) + return nil, fmt.Errorf("invalid options %q, can only specify 1 upperdir per overlay", strings.Join(options, ", ")) } finalOpts = append(finalOpts, opt) continue @@ -29,7 +29,7 @@ func ValidateVolumeOpts(options []string) ([]string, error) { if strings.Contains(opt, "workdir") { foundWorkDir++ if foundWorkDir > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 workdir per overlay", strings.Join(options, ", ")) + return nil, fmt.Errorf("invalid options %q, can only specify 1 workdir per overlay", strings.Join(options, ", ")) } finalOpts = append(finalOpts, opt) continue @@ -43,42 +43,42 @@ func ValidateVolumeOpts(options []string) ([]string, error) { case "noexec", "exec": foundExec++ if foundExec > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 'noexec' or 'exec' option", strings.Join(options, ", ")) + return nil, fmt.Errorf("invalid options %q, can only specify 1 'noexec' or 'exec' option", strings.Join(options, ", ")) } case "nodev", "dev": foundDev++ if foundDev > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 'nodev' or 'dev' option", strings.Join(options, ", ")) + return nil, fmt.Errorf("invalid options %q, can only specify 1 'nodev' or 'dev' option", strings.Join(options, ", ")) } case "nosuid", "suid": foundSuid++ if foundSuid > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 'nosuid' or 'suid' option", strings.Join(options, ", ")) + return nil, fmt.Errorf("invalid options %q, can only specify 1 'nosuid' or 'suid' option", strings.Join(options, ", ")) } case "rw", "ro": foundRWRO++ if foundRWRO > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 'rw' or 'ro' option", strings.Join(options, ", ")) + return nil, fmt.Errorf("invalid options %q, can only specify 1 'rw' or 'ro' option", strings.Join(options, ", ")) } case "z", "Z", "O": foundLabelChange++ if foundLabelChange > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 'z', 'Z', or 'O' option", strings.Join(options, ", ")) + return nil, fmt.Errorf("invalid options %q, can only specify 1 'z', 'Z', or 'O' option", strings.Join(options, ", ")) } case "U": foundChown++ if foundChown > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 'U' option", strings.Join(options, ", ")) + return nil, fmt.Errorf("invalid options %q, can only specify 1 'U' option", strings.Join(options, ", ")) } case "private", "rprivate", "shared", "rshared", "slave", "rslave", "unbindable", "runbindable": foundRootPropagation++ if foundRootPropagation > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 '[r]shared', '[r]private', '[r]slave' or '[r]unbindable' option", strings.Join(options, ", ")) + return nil, fmt.Errorf("invalid options %q, can only specify 1 '[r]shared', '[r]private', '[r]slave' or '[r]unbindable' option", strings.Join(options, ", ")) } case "bind", "rbind": bindType++ if bindType > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 '[r]bind' option", strings.Join(options, ", ")) + return nil, fmt.Errorf("invalid options %q, can only specify 1 '[r]bind' option", strings.Join(options, ", ")) } case "cached", "delegated": // The discarded ops are OS X specific volume options @@ -91,10 +91,10 @@ func ValidateVolumeOpts(options []string) ([]string, error) { case "copy", "nocopy": foundCopy++ if foundCopy > 1 { - return nil, errors.Errorf("invalid options %q, can only specify 1 'copy' or 'nocopy' option", strings.Join(options, ", ")) + return nil, fmt.Errorf("invalid options %q, can only specify 1 'copy' or 'nocopy' option", strings.Join(options, ", ")) } default: - return nil, errors.Errorf("invalid option type %q", opt) + return nil, fmt.Errorf("invalid option type %q", opt) } finalOpts = append(finalOpts, opt) } @@ -113,7 +113,7 @@ func Device(device string) (src, dest, permissions string, err error) { switch len(arr) { case 3: if !isValidDeviceMode(arr[2]) { - return "", "", "", errors.Errorf("invalid device mode: %s", arr[2]) + return "", "", "", fmt.Errorf("invalid device mode: %s", arr[2]) } permissions = arr[2] fallthrough @@ -122,7 +122,7 @@ func Device(device string) (src, dest, permissions string, err error) { permissions = arr[1] } else { if arr[1] == "" || arr[1][0] != '/' { - return "", "", "", errors.Errorf("invalid device mode: %s", arr[1]) + return "", "", "", fmt.Errorf("invalid device mode: %s", arr[1]) } dest = arr[1] } @@ -134,7 +134,7 @@ func Device(device string) (src, dest, permissions string, err error) { } fallthrough default: - return "", "", "", errors.Errorf("invalid device specification: %s", device) + return "", "", "", fmt.Errorf("invalid device specification: %s", device) } if dest == "" { @@ -184,7 +184,7 @@ func ValidateVolumeCtrDir(ctrDir string) error { return errors.New("container directory cannot be empty") } if !path.IsAbs(ctrDir) { - return errors.Errorf("invalid container path %q, must be an absolute path", ctrDir) + return fmt.Errorf("invalid container path %q, must be an absolute path", ctrDir) } return nil } diff --git a/pkg/parse/parse_unix.go b/pkg/parse/parse_unix.go index 6fb52a014..8b3599229 100644 --- a/pkg/parse/parse_unix.go +++ b/pkg/parse/parse_unix.go @@ -4,12 +4,12 @@ package parse import ( + "fmt" "os" "path/filepath" "github.com/containers/storage/pkg/unshare" "github.com/opencontainers/runc/libcontainer/devices" - "github.com/pkg/errors" ) func DeviceFromPath(device string) ([]devices.Device, error) { @@ -18,7 +18,7 @@ func DeviceFromPath(device string) ([]devices.Device, error) { return nil, err } if unshare.IsRootless() && src != dst { - return nil, errors.Errorf("Renaming device %s to %s is not supported in rootless containers", src, dst) + return nil, fmt.Errorf("Renaming device %s to %s is not supported in rootless containers", src, dst) } srcInfo, err := os.Stat(src) if err != nil { @@ -29,7 +29,7 @@ func DeviceFromPath(device string) ([]devices.Device, error) { devs := make([]devices.Device, 0, 1) dev, err := devices.DeviceFromPath(src, permissions) if err != nil { - return nil, errors.Wrapf(err, "%s is not a valid device", src) + return nil, fmt.Errorf("%s is not a valid device: %w", src, err) } dev.Path = dst devs = append(devs, *dev) @@ -39,7 +39,7 @@ func DeviceFromPath(device string) ([]devices.Device, error) { // If source device is a directory srcDevices, err := devices.GetDevices(src) if err != nil { - return nil, errors.Wrapf(err, "error getting source devices from directory %s", src) + return nil, fmt.Errorf("error getting source devices from directory %s: %w", src, err) } devs := make([]devices.Device, 0, len(srcDevices)) for _, d := range srcDevices { diff --git a/pkg/retry/retry.go b/pkg/retry/retry.go index 321131f69..a838c706a 100644 --- a/pkg/retry/retry.go +++ b/pkg/retry/retry.go @@ -12,7 +12,6 @@ import ( "github.com/docker/distribution/registry/api/errcode" errcodev2 "github.com/docker/distribution/registry/api/v2" "github.com/hashicorp/go-multierror" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -51,8 +50,6 @@ func IfNecessary(ctx context.Context, operation func() error, options *Options) } func isRetryable(err error) bool { - err = errors.Cause(err) - switch err { case nil: return false diff --git a/pkg/seccomp/conversion.go b/pkg/seccomp/conversion.go index cd599f0f3..01fe11cd5 100644 --- a/pkg/seccomp/conversion.go +++ b/pkg/seccomp/conversion.go @@ -7,7 +7,6 @@ import ( "fmt" "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" ) var ( @@ -108,7 +107,7 @@ func specToSeccomp(spec *specs.LinuxSeccomp) (*Seccomp, error) { for _, arch := range spec.Architectures { newArch, err := specArchToSeccompArch(arch) if err != nil { - return nil, errors.Wrap(err, "convert spec arch") + return nil, fmt.Errorf("convert spec arch: %w", err) } res.Architectures = append(res.Architectures, newArch) } @@ -116,7 +115,7 @@ func specToSeccomp(spec *specs.LinuxSeccomp) (*Seccomp, error) { // Convert default action newDefaultAction, err := specActionToSeccompAction(spec.DefaultAction) if err != nil { - return nil, errors.Wrap(err, "convert default action") + return nil, fmt.Errorf("convert default action: %w", err) } res.DefaultAction = newDefaultAction res.DefaultErrnoRet = spec.DefaultErrnoRet @@ -125,7 +124,7 @@ func specToSeccomp(spec *specs.LinuxSeccomp) (*Seccomp, error) { for _, call := range spec.Syscalls { newAction, err := specActionToSeccompAction(call.Action) if err != nil { - return nil, errors.Wrap(err, "convert action") + return nil, fmt.Errorf("convert action: %w", err) } for _, name := range call.Names { @@ -140,7 +139,7 @@ func specToSeccomp(spec *specs.LinuxSeccomp) (*Seccomp, error) { for _, arg := range call.Args { newOp, err := specOperatorToSeccompOperator(arg.Op) if err != nil { - return nil, errors.Wrap(err, "convert operator") + return nil, fmt.Errorf("convert operator: %w", err) } newArg := Arg{ @@ -164,7 +163,7 @@ func specArchToLibseccompArch(arch specs.Arch) (string, error) { if res, ok := specArchToLibseccompArchMap[arch]; ok { return res, nil } - return "", errors.Errorf( + return "", fmt.Errorf( "architecture %q is not valid for libseccomp", arch, ) } @@ -174,7 +173,7 @@ func specArchToSeccompArch(arch specs.Arch) (Arch, error) { if res, ok := specArchToSeccompArchMap[arch]; ok { return res, nil } - return "", errors.Errorf("architecture %q is not valid", arch) + return "", fmt.Errorf("architecture %q is not valid", arch) } // specActionToSeccompAction converts a spec action into a seccomp one. @@ -182,7 +181,7 @@ func specActionToSeccompAction(action specs.LinuxSeccompAction) (Action, error) if res, ok := specActionToSeccompActionMap[action]; ok { return res, nil } - return "", errors.Errorf( + return "", fmt.Errorf( "spec action %q is not valid internal action", action, ) } @@ -192,7 +191,7 @@ func specOperatorToSeccompOperator(operator specs.LinuxSeccompOperator) (Operato if op, ok := specOperatorToSeccompOperatorMap[operator]; ok { return op, nil } - return "", errors.Errorf( + return "", fmt.Errorf( "spec operator %q is not a valid internal operator", operator, ) } diff --git a/pkg/seccomp/filter.go b/pkg/seccomp/filter.go index 7f1783efb..72c95734b 100644 --- a/pkg/seccomp/filter.go +++ b/pkg/seccomp/filter.go @@ -7,8 +7,10 @@ package seccomp import ( + "errors" + "fmt" + specs "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" libseccomp "github.com/seccomp/libseccomp-golang" "golang.org/x/sys/unix" ) @@ -39,39 +41,39 @@ func BuildFilter(spec *specs.LinuxSeccomp) (*libseccomp.ScmpFilter, error) { profile, err := specToSeccomp(spec) if err != nil { - return nil, errors.Wrap(err, "convert spec to seccomp profile") + return nil, fmt.Errorf("convert spec to seccomp profile: %w", err) } defaultAction, err := toAction(profile.DefaultAction, profile.DefaultErrnoRet) if err != nil { - return nil, errors.Wrapf(err, "convert default action %s", profile.DefaultAction) + return nil, fmt.Errorf("convert default action %s: %w", profile.DefaultAction, err) } filter, err := libseccomp.NewFilter(defaultAction) if err != nil { - return nil, errors.Wrapf(err, "create filter for default action %s", defaultAction) + return nil, fmt.Errorf("create filter for default action %s: %w", defaultAction, err) } // Add extra architectures for _, arch := range spec.Architectures { libseccompArch, err := specArchToLibseccompArch(arch) if err != nil { - return nil, errors.Wrap(err, "convert spec arch") + return nil, fmt.Errorf("convert spec arch: %w", err) } scmpArch, err := libseccomp.GetArchFromString(libseccompArch) if err != nil { - return nil, errors.Wrapf(err, "validate Seccomp architecture %s", arch) + return nil, fmt.Errorf("validate Seccomp architecture %s: %w", arch, err) } if err := filter.AddArch(scmpArch); err != nil { - return nil, errors.Wrap(err, "add architecture to seccomp filter") + return nil, fmt.Errorf("add architecture to seccomp filter: %w", err) } } // Unset no new privs bit if err := filter.SetNoNewPrivsBit(false); err != nil { - return nil, errors.Wrap(err, "set no new privileges flag") + return nil, fmt.Errorf("set no new privileges flag: %w", err) } // Add a rule for each syscall @@ -81,7 +83,7 @@ func BuildFilter(spec *specs.LinuxSeccomp) (*libseccomp.ScmpFilter, error) { } if err = matchSyscall(filter, call); err != nil { - return nil, errors.Wrap(err, "filter matches syscall") + return nil, fmt.Errorf("filter matches syscall: %w", err) } } @@ -107,13 +109,13 @@ func matchSyscall(filter *libseccomp.ScmpFilter, call *Syscall) error { // Convert the call's action to the libseccomp equivalent callAct, err := toAction(call.Action, call.ErrnoRet) if err != nil { - return errors.Wrapf(err, "convert action %s", call.Action) + return fmt.Errorf("convert action %s: %w", call.Action, err) } // Unconditional match - just add the rule if len(call.Args) == 0 { if err = filter.AddRule(callNum, callAct); err != nil { - return errors.Wrapf(err, "add seccomp filter rule for syscall %s", call.Name) + return fmt.Errorf("add seccomp filter rule for syscall %s: %w", call.Name, err) } } else { // Linux system calls can have at most 6 arguments @@ -127,7 +129,7 @@ func matchSyscall(filter *libseccomp.ScmpFilter, call *Syscall) error { for _, cond := range call.Args { newCond, err := toCondition(cond) if err != nil { - return errors.Wrapf(err, "create seccomp syscall condition for syscall %s", call.Name) + return fmt.Errorf("create seccomp syscall condition for syscall %s: %w", call.Name, err) } argCounts[cond.Index]++ @@ -150,13 +152,13 @@ func matchSyscall(filter *libseccomp.ScmpFilter, call *Syscall) error { condArr := []libseccomp.ScmpCondition{cond} if err = filter.AddRuleConditional(callNum, callAct, condArr); err != nil { - return errors.Wrapf(err, "add seccomp rule for syscall %s", call.Name) + return fmt.Errorf("add seccomp rule for syscall %s: %w", call.Name, err) } } } else if err = filter.AddRuleConditional(callNum, callAct, conditions); err != nil { // No conditions share same argument // Use new, proper behavior - return errors.Wrapf(err, "add seccomp rule for syscall %s", call.Name) + return fmt.Errorf("add seccomp rule for syscall %s: %w", call.Name, err) } } @@ -189,7 +191,7 @@ func toAction(act Action, errnoRet *uint) (libseccomp.ScmpAction, error) { case ActLog: return libseccomp.ActLog, nil default: - return libseccomp.ActInvalid, errors.Errorf("invalid action %s", act) + return libseccomp.ActInvalid, fmt.Errorf("invalid action %s", act) } } @@ -202,14 +204,14 @@ func toCondition(arg *Arg) (cond libseccomp.ScmpCondition, err error) { op, err := toCompareOp(arg.Op) if err != nil { - return cond, errors.Wrap(err, "convert compare operator") + return cond, fmt.Errorf("convert compare operator: %w", err) } condition, err := libseccomp.MakeCondition( arg.Index, op, arg.Value, arg.ValueTwo, ) if err != nil { - return cond, errors.Wrap(err, "make condition") + return cond, fmt.Errorf("make condition: %w", err) } return condition, nil @@ -234,6 +236,6 @@ func toCompareOp(op Operator) (libseccomp.ScmpCompareOp, error) { case OpMaskedEqual: return libseccomp.CompareMaskedEqual, nil default: - return libseccomp.CompareInvalid, errors.Errorf("invalid operator %s", op) + return libseccomp.CompareInvalid, fmt.Errorf("invalid operator %s", op) } } diff --git a/pkg/seccomp/validate.go b/pkg/seccomp/validate.go index 669ab04a2..80558c1f0 100644 --- a/pkg/seccomp/validate.go +++ b/pkg/seccomp/validate.go @@ -5,8 +5,7 @@ package seccomp import ( "encoding/json" - - "github.com/pkg/errors" + "fmt" ) // ValidateProfile does a basic validation for the provided seccomp profile @@ -14,16 +13,16 @@ import ( func ValidateProfile(content string) error { profile := &Seccomp{} if err := json.Unmarshal([]byte(content), &profile); err != nil { - return errors.Wrap(err, "decoding seccomp profile") + return fmt.Errorf("decoding seccomp profile: %w", err) } spec, err := setupSeccomp(profile, nil) if err != nil { - return errors.Wrap(err, "create seccomp spec") + return fmt.Errorf("create seccomp spec: %w", err) } if _, err := BuildFilter(spec); err != nil { - return errors.Wrap(err, "build seccomp filter") + return fmt.Errorf("build seccomp filter: %w", err) } return nil diff --git a/pkg/secrets/filedriver/filedriver.go b/pkg/secrets/filedriver/filedriver.go index 6b92714d0..f1b7ef3f2 100644 --- a/pkg/secrets/filedriver/filedriver.go +++ b/pkg/secrets/filedriver/filedriver.go @@ -2,13 +2,14 @@ package filedriver import ( "encoding/json" + "errors" + "fmt" "io/ioutil" "os" "path/filepath" "sort" "github.com/containers/storage/pkg/lockfile" - "github.com/pkg/errors" ) // secretsDataFile is the file where secrets data/payload will be stored @@ -75,7 +76,7 @@ func (d *Driver) Lookup(id string) ([]byte, error) { if data, ok := secretData[id]; ok { return data, nil } - return nil, errors.Wrapf(errNoSecretData, "%s", id) + return nil, fmt.Errorf("%s: %w", id, errNoSecretData) } // Store stores the bytes associated with an ID. An error is returned if the ID arleady exists @@ -88,7 +89,7 @@ func (d *Driver) Store(id string, data []byte) error { return err } if _, ok := secretData[id]; ok { - return errors.Wrapf(errSecretIDExists, "%s", id) + return fmt.Errorf("%s: %w", id, errSecretIDExists) } secretData[id] = data marshalled, err := json.MarshalIndent(secretData, "", " ") @@ -113,7 +114,7 @@ func (d *Driver) Delete(id string) error { if _, ok := secretData[id]; ok { delete(secretData, id) } else { - return errors.Wrap(errNoSecretData, id) + return fmt.Errorf("%s: %w", id, errNoSecretData) } marshalled, err := json.MarshalIndent(secretData, "", " ") if err != nil { @@ -131,7 +132,7 @@ func (d *Driver) getAllData() (map[string][]byte, error) { // check if the db file exists _, err := os.Stat(d.secretsDataFilePath) if err != nil { - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { // the file will be created later on a store() return make(map[string][]byte), nil } diff --git a/pkg/secrets/passdriver/passdriver.go b/pkg/secrets/passdriver/passdriver.go index 50967b7cf..7a658c02d 100644 --- a/pkg/secrets/passdriver/passdriver.go +++ b/pkg/secrets/passdriver/passdriver.go @@ -3,6 +3,8 @@ package passdriver import ( "bytes" "context" + "errors" + "fmt" "io" "io/ioutil" "os" @@ -10,8 +12,6 @@ import ( "path/filepath" "sort" "strings" - - "github.com/pkg/errors" ) var ( @@ -108,7 +108,7 @@ func NewDriver(opts map[string]string) (*Driver, error) { func (d *Driver) List() (secrets []string, err error) { files, err := ioutil.ReadDir(d.Root) if err != nil { - return nil, errors.Wrap(err, "failed to read secret directory") + return nil, fmt.Errorf("failed to read secret directory: %w", err) } for _, f := range files { fileName := f.Name() @@ -127,10 +127,10 @@ func (d *Driver) Lookup(id string) ([]byte, error) { return nil, err } if err := d.gpg(context.TODO(), nil, out, "--decrypt", key); err != nil { - return nil, errors.Wrapf(errNoSecretData, id) + return nil, fmt.Errorf("%s: %w", id, errNoSecretData) } if out.Len() == 0 { - return nil, errors.Wrapf(errNoSecretData, id) + return nil, fmt.Errorf("%s: %w", id, errNoSecretData) } return out.Bytes(), nil } @@ -138,7 +138,7 @@ func (d *Driver) Lookup(id string) ([]byte, error) { // Store saves the bytes associated with an ID. An error is returned if the ID already exists func (d *Driver) Store(id string, data []byte) error { if _, err := d.Lookup(id); err == nil { - return errors.Wrap(errSecretIDExists, id) + return fmt.Errorf("%s: %w", id, errSecretIDExists) } in := bytes.NewReader(data) key, err := d.getPath(id) @@ -155,7 +155,7 @@ func (d *Driver) Delete(id string) error { return err } if err := os.Remove(key); err != nil { - return errors.Wrap(errNoSecretData, id) + return fmt.Errorf("%s: %w", id, errNoSecretData) } return nil } diff --git a/pkg/secrets/passdriver/passdriver_test.go b/pkg/secrets/passdriver/passdriver_test.go index 9589a9bfb..83ec6bcb3 100644 --- a/pkg/secrets/passdriver/passdriver_test.go +++ b/pkg/secrets/passdriver/passdriver_test.go @@ -2,11 +2,11 @@ package passdriver import ( "context" + "fmt" "io/ioutil" "os" "testing" - "github.com/pkg/errors" "github.com/stretchr/testify/require" ) @@ -111,7 +111,7 @@ func TestLookup(t *testing.T) { { name: "lookup of a non-existing key fails", key: "invalid", - expErr: errors.Wrap(errNoSecretData, "invalid"), + expErr: fmt.Errorf("invalid: %w", errNoSecretData), }, { name: "lookup of a sneaky key fails", @@ -162,7 +162,7 @@ func TestDelete(t *testing.T) { { name: "deleting an non-existing item fails", key: "wrong", - expErr: errors.Wrap(errNoSecretData, "wrong"), + expErr: fmt.Errorf("wrong: %w", errNoSecretData), }, { name: "using a sneaky path fails", diff --git a/pkg/secrets/secrets.go b/pkg/secrets/secrets.go index e45995b2e..e23db1152 100644 --- a/pkg/secrets/secrets.go +++ b/pkg/secrets/secrets.go @@ -1,6 +1,8 @@ package secrets import ( + "errors" + "fmt" "os" "path/filepath" "regexp" @@ -12,7 +14,6 @@ import ( "github.com/containers/common/pkg/secrets/shelldriver" "github.com/containers/storage/pkg/lockfile" "github.com/containers/storage/pkg/stringid" - "github.com/pkg/errors" ) // maxSecretSize is the max size for secret data - 512kB @@ -105,7 +106,7 @@ func NewManager(rootPath string) (*SecretsManager, error) { manager := new(SecretsManager) if !filepath.IsAbs(rootPath) { - return nil, errors.Wrapf(errInvalidPath, "path must be absolute: %s", rootPath) + return nil, fmt.Errorf("path must be absolute: %s: %w", rootPath, errInvalidPath) } // the lockfile functions require that the rootPath dir is executable if err := os.MkdirAll(rootPath, 0o700); err != nil { @@ -146,7 +147,7 @@ func (s *SecretsManager) Store(name string, data []byte, driverType string, driv return "", err } if exist { - return "", errors.Wrapf(errSecretNameInUse, name) + return "", fmt.Errorf("%s: %w", name, errSecretNameInUse) } secr := new(Secret) @@ -158,7 +159,7 @@ func (s *SecretsManager) Store(name string, data []byte, driverType string, driv newID = newID[0:secretIDLength] _, err := s.lookupSecret(newID) if err != nil { - if errors.Cause(err) == ErrNoSuchSecret { + if errors.Is(err, ErrNoSuchSecret) { secr.ID = newID break } else { @@ -178,12 +179,12 @@ func (s *SecretsManager) Store(name string, data []byte, driverType string, driv } err = driver.Store(secr.ID, data) if err != nil { - return "", errors.Wrapf(err, "error creating secret %s", name) + return "", fmt.Errorf("error creating secret %s: %w", name, err) } err = s.store(secr) if err != nil { - return "", errors.Wrapf(err, "error creating secret %s", name) + return "", fmt.Errorf("error creating secret %s: %w", name, err) } return secr.ID, nil @@ -213,12 +214,12 @@ func (s *SecretsManager) Delete(nameOrID string) (string, error) { err = driver.Delete(secretID) if err != nil { - return "", errors.Wrapf(err, "error deleting secret %s", nameOrID) + return "", fmt.Errorf("error deleting secret %s: %w", nameOrID, err) } err = s.delete(secretID) if err != nil { - return "", errors.Wrapf(err, "error deleting secret %s", nameOrID) + return "", fmt.Errorf("error deleting secret %s: %w", nameOrID, err) } return secretID, nil } @@ -271,7 +272,7 @@ func (s *SecretsManager) LookupSecretData(nameOrID string) (*Secret, []byte, err // validateSecretName checks if the secret name is valid. func validateSecretName(name string) error { if !secretNameRegexp.MatchString(name) || len(name) > 64 || strings.HasSuffix(name, "-") || strings.HasSuffix(name, ".") { - return errors.Wrapf(errInvalidSecretName, "only 64 [a-zA-Z0-9-_.] characters allowed, and the start and end character must be [a-zA-Z0-9]: %s", name) + return fmt.Errorf("only 64 [a-zA-Z0-9-_.] characters allowed, and the start and end character must be [a-zA-Z0-9]: %s: %w", name, errInvalidSecretName) } return nil } @@ -283,7 +284,7 @@ func getDriver(name string, opts map[string]string) (SecretsDriver, error) { if path, ok := opts["path"]; ok { return filedriver.NewDriver(path) } - return nil, errors.Wrap(errInvalidDriverOpt, "need path for filedriver") + return nil, fmt.Errorf("need path for filedriver: %w", errInvalidDriverOpt) case "pass": return passdriver.NewDriver(opts) case "shell": diff --git a/pkg/secrets/secretsdb.go b/pkg/secrets/secretsdb.go index 8d21aa754..91b0b7eb0 100644 --- a/pkg/secrets/secretsdb.go +++ b/pkg/secrets/secretsdb.go @@ -2,12 +2,12 @@ package secrets import ( "encoding/json" + "errors" + "fmt" "io/ioutil" "os" "strings" "time" - - "github.com/pkg/errors" ) type db struct { @@ -70,21 +70,21 @@ func (s *SecretsManager) getNameAndID(nameOrID string) (name, id string, err err name, id, err = s.getExactNameAndID(nameOrID) if err == nil { return name, id, nil - } else if errors.Cause(err) != ErrNoSuchSecret { + } else if !errors.Is(err, ErrNoSuchSecret) { return "", "", err } // ID prefix may have been given, iterate through all IDs. // ID and partial ID has a max length of 25, so we return if its greater than that. if len(nameOrID) > secretIDLength { - return "", "", errors.Wrapf(ErrNoSuchSecret, "no secret with name or id %q", nameOrID) + return "", "", fmt.Errorf("no secret with name or id %q: %w", nameOrID, ErrNoSuchSecret) } exists := false var foundID, foundName string for id, name := range s.db.IDToName { if strings.HasPrefix(id, nameOrID) { if exists { - return "", "", errors.Wrapf(errAmbiguous, "more than one result secret with prefix %s", nameOrID) + return "", "", fmt.Errorf("more than one result secret with prefix %s: %w", nameOrID, errAmbiguous) } exists = true foundID = id @@ -95,7 +95,7 @@ func (s *SecretsManager) getNameAndID(nameOrID string) (name, id string, err err if exists { return foundName, foundID, nil } - return "", "", errors.Wrapf(ErrNoSuchSecret, "no secret with name or id %q", nameOrID) + return "", "", fmt.Errorf("no secret with name or id %q: %w", nameOrID, ErrNoSuchSecret) } // getExactNameAndID takes a secret's name or ID and returns both its name and full ID. @@ -114,7 +114,7 @@ func (s *SecretsManager) getExactNameAndID(nameOrID string) (name, id string, er return name, id, nil } - return "", "", errors.Wrapf(ErrNoSuchSecret, "no secret with name or id %q", nameOrID) + return "", "", fmt.Errorf("no secret with name or id %q: %w", nameOrID, ErrNoSuchSecret) } // exactSecretExists checks if the secret exists, given a name or ID @@ -122,7 +122,7 @@ func (s *SecretsManager) getExactNameAndID(nameOrID string) (name, id string, er func (s *SecretsManager) exactSecretExists(nameOrID string) (bool, error) { _, _, err := s.getExactNameAndID(nameOrID) if err != nil { - if errors.Cause(err) == ErrNoSuchSecret { + if errors.Is(err, ErrNoSuchSecret) { return false, nil } return false, err @@ -157,7 +157,7 @@ func (s *SecretsManager) lookupSecret(nameOrID string) (*Secret, error) { return &secret, nil } - return nil, errors.Wrapf(ErrNoSuchSecret, "no secret with name or id %q", nameOrID) + return nil, fmt.Errorf("no secret with name or id %q: %w", nameOrID, ErrNoSuchSecret) } // Store creates a new secret in the secrets database. diff --git a/pkg/secrets/shelldriver/shelldriver.go b/pkg/secrets/shelldriver/shelldriver.go index 8eac200f7..87dc317a9 100644 --- a/pkg/secrets/shelldriver/shelldriver.go +++ b/pkg/secrets/shelldriver/shelldriver.go @@ -3,13 +3,12 @@ package shelldriver import ( "bytes" "context" + "errors" "fmt" "os" "os/exec" "sort" "strings" - - "github.com/pkg/errors" ) var ( @@ -126,7 +125,7 @@ func (d *Driver) Lookup(id string) ([]byte, error) { err := cmd.Run() if err != nil { - return nil, errors.Wrap(errNoSecretData, id) + return nil, fmt.Errorf("%s: %w", id, errNoSecretData) } return buf.Bytes(), nil } @@ -163,7 +162,7 @@ func (d *Driver) Delete(id string) error { err := cmd.Run() if err != nil { - return errors.Wrap(errNoSecretData, id) + return fmt.Errorf("%s: %w", id, errNoSecretData) } return nil diff --git a/pkg/secrets/shelldriver/shelldriver_test.go b/pkg/secrets/shelldriver/shelldriver_test.go index 2c60ca1c4..4522960e9 100644 --- a/pkg/secrets/shelldriver/shelldriver_test.go +++ b/pkg/secrets/shelldriver/shelldriver_test.go @@ -6,7 +6,6 @@ import ( "os" "testing" - "github.com/pkg/errors" "github.com/stretchr/testify/require" ) @@ -100,7 +99,7 @@ func TestLookup(t *testing.T) { { name: "lookup of a non-existing key fails", key: "invalid", - expErr: errors.Wrap(errNoSecretData, "invalid"), + expErr: fmt.Errorf("invalid: %w", errNoSecretData), }, { name: "lookup of a sneaky key fails", @@ -151,7 +150,7 @@ func TestDelete(t *testing.T) { { name: "deleting an non-existing item fails", key: "wrong", - expErr: errors.Wrap(errNoSecretData, "wrong"), + expErr: fmt.Errorf("wrong: %w", errNoSecretData), }, { name: "using a sneaky path fails", diff --git a/pkg/subscriptions/subscriptions.go b/pkg/subscriptions/subscriptions.go index b111ae7ff..ff82b5a39 100644 --- a/pkg/subscriptions/subscriptions.go +++ b/pkg/subscriptions/subscriptions.go @@ -2,6 +2,8 @@ package subscriptions import ( "bufio" + "errors" + "fmt" "io/ioutil" "os" "path/filepath" @@ -11,7 +13,6 @@ import ( "github.com/containers/storage/pkg/idtools" rspec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/selinux/go-selinux/label" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -51,7 +52,7 @@ func readAll(root, prefix string, parentMode os.FileMode) ([]subscriptionData, e files, err := ioutil.ReadDir(path) if err != nil { - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { return data, nil } @@ -63,7 +64,7 @@ func readAll(root, prefix string, parentMode os.FileMode) ([]subscriptionData, e if err != nil { // If the file did not exist, might be a dangling symlink // Ignore the error - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { continue } return nil, err @@ -105,7 +106,7 @@ func getHostSubscriptionData(hostDir string, mode os.FileMode) ([]subscriptionDa var allSubscriptions []subscriptionData hostSubscriptions, err := readAll(hostDir, "", mode) if err != nil { - return nil, errors.Wrapf(err, "failed to read subscriptions from %q", hostDir) + return nil, fmt.Errorf("failed to read subscriptions from %q: %w", hostDir, err) } return append(allSubscriptions, hostSubscriptions...), nil } @@ -144,7 +145,7 @@ func getMountsMap(path string) (string, string, error) { //nolint case 2: return arr[0], arr[1], nil } - return "", "", errors.Errorf("unable to get host and container dir from path: %s", path) + return "", "", fmt.Errorf("unable to get host and container dir from path: %s", path) } // MountsWithUIDGID copies, adds, and mounts the subscriptions to the container root filesystem @@ -195,7 +196,7 @@ func MountsWithUIDGID(mountLabel, containerRunDir, mountFile, mountPoint string, if err := addFIPSModeSubscription(&subscriptionMounts, containerRunDir, mountPoint, mountLabel, uid, gid); err != nil { logrus.Errorf("Adding FIPS mode subscription to container: %v", err) } - case os.IsNotExist(err): + case errors.Is(err, os.ErrNotExist): logrus.Debug("/etc/system-fips does not exist on host, not mounting FIPS mode subscription") default: logrus.Errorf("stat /etc/system-fips failed for FIPS mode subscription: %v", err) @@ -222,7 +223,7 @@ func addSubscriptionsFromMountsFile(filePath, mountLabel, containerRunDir string // skip if the hostDirOrFile path doesn't exist fileInfo, err := os.Stat(hostDirOrFile) if err != nil { - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { logrus.Warnf("Path %q from %q doesn't exist, skipping", hostDirOrFile, filePath) continue } @@ -233,7 +234,7 @@ func addSubscriptionsFromMountsFile(filePath, mountLabel, containerRunDir string // In the event of a restart, don't want to copy subscriptions over again as they already would exist in ctrDirOrFileOnHost _, err = os.Stat(ctrDirOrFileOnHost) - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { hostDirOrFile, err = resolveSymbolicLink(hostDirOrFile) if err != nil { @@ -247,15 +248,15 @@ func addSubscriptionsFromMountsFile(filePath, mountLabel, containerRunDir string switch mode := fileInfo.Mode(); { case mode.IsDir(): if err = os.MkdirAll(ctrDirOrFileOnHost, mode.Perm()); err != nil { - return nil, errors.Wrap(err, "making container directory") + return nil, fmt.Errorf("making container directory: %w", err) } data, err := getHostSubscriptionData(hostDirOrFile, mode.Perm()) if err != nil { - return nil, errors.Wrap(err, "getting host subscription data") + return nil, fmt.Errorf("getting host subscription data: %w", err) } for _, s := range data { if err := s.saveTo(ctrDirOrFileOnHost); err != nil { - return nil, errors.Wrapf(err, "error saving data to container filesystem on host %q", ctrDirOrFileOnHost) + return nil, fmt.Errorf("error saving data to container filesystem on host %q: %w", ctrDirOrFileOnHost, err) } } case mode.IsRegular(): @@ -268,16 +269,16 @@ func addSubscriptionsFromMountsFile(filePath, mountLabel, containerRunDir string return nil, err } if err := ioutil.WriteFile(ctrDirOrFileOnHost, s.data, s.mode); err != nil { - return nil, errors.Wrap(err, "saving data to container filesystem") + return nil, fmt.Errorf("saving data to container filesystem: %w", err) } } default: - return nil, errors.Errorf("unsupported file type for: %q", hostDirOrFile) + return nil, fmt.Errorf("unsupported file type for: %q", hostDirOrFile) } err = label.Relabel(ctrDirOrFileOnHost, mountLabel, false) if err != nil { - return nil, errors.Wrap(err, "error applying correct labels") + return nil, fmt.Errorf("error applying correct labels: %w", err) } if uid != 0 || gid != 0 { if err := rchown(ctrDirOrFileOnHost, uid, gid); err != nil { @@ -311,20 +312,20 @@ func addSubscriptionsFromMountsFile(filePath, mountLabel, containerRunDir string func addFIPSModeSubscription(mounts *[]rspec.Mount, containerRunDir, mountPoint, mountLabel string, uid, gid int) error { subscriptionsDir := "/run/secrets" ctrDirOnHost := filepath.Join(containerRunDir, subscriptionsDir) - if _, err := os.Stat(ctrDirOnHost); os.IsNotExist(err) { + if _, err := os.Stat(ctrDirOnHost); errors.Is(err, os.ErrNotExist) { if err = idtools.MkdirAllAs(ctrDirOnHost, 0o755, uid, gid); err != nil { //nolint return err } if err = label.Relabel(ctrDirOnHost, mountLabel, false); err != nil { - return errors.Wrapf(err, "applying correct labels on %q", ctrDirOnHost) + return fmt.Errorf("applying correct labels on %q: %w", ctrDirOnHost, err) } } fipsFile := filepath.Join(ctrDirOnHost, "system-fips") // In the event of restart, it is possible for the FIPS mode file to already exist - if _, err := os.Stat(fipsFile); os.IsNotExist(err) { + if _, err := os.Stat(fipsFile); errors.Is(err, os.ErrNotExist) { file, err := os.Create(fipsFile) if err != nil { - return errors.Wrap(err, "creating system-fips file in container for FIPS mode") + return fmt.Errorf("creating system-fips file in container for FIPS mode: %w", err) } file.Close() } @@ -343,10 +344,10 @@ func addFIPSModeSubscription(mounts *[]rspec.Mount, containerRunDir, mountPoint, destDir := "/etc/crypto-policies/back-ends" srcOnHost := filepath.Join(mountPoint, srcBackendDir) if _, err := os.Stat(srcOnHost); err != nil { - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { return nil } - return errors.Wrap(err, "FIPS Backend directory") + return fmt.Errorf("FIPS Backend directory: %w", err) } if !mountExists(*mounts, destDir) { diff --git a/pkg/supplemented/supplemented.go b/pkg/supplemented/supplemented.go index 196176a1c..84201c998 100644 --- a/pkg/supplemented/supplemented.go +++ b/pkg/supplemented/supplemented.go @@ -3,6 +3,7 @@ package supplemented import ( "container/list" "context" + "fmt" "io" cp "github.com/containers/image/v5/copy" @@ -12,7 +13,6 @@ import ( "github.com/containers/image/v5/types" multierror "github.com/hashicorp/go-multierror" digest "github.com/opencontainers/go-digest" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -58,7 +58,7 @@ func Reference(ref types.ImageReference, supplemental []types.ImageReference, mu func (s *supplementedImageReference) NewImage(ctx context.Context, sys *types.SystemContext) (types.ImageCloser, error) { src, err := s.NewImageSource(ctx, sys) if err != nil { - return nil, errors.Wrapf(err, "error building a new Image using an ImageSource") + return nil, fmt.Errorf("error building a new Image using an ImageSource: %w", err) } return image.FromSource(ctx, sys, src) } @@ -75,7 +75,7 @@ func (s *supplementedImageReference) NewImageSource(ctx context.Context, sys *ty // Open the default instance for reading. top, err := s.ImageReference.NewImageSource(ctx, sys) if err != nil { - return nil, errors.Wrapf(err, "error opening %q as image source", transports.ImageName(s.ImageReference)) + return nil, fmt.Errorf("error opening %q as image source: %w", transports.ImageName(s.ImageReference), err) } defer func() { @@ -105,14 +105,14 @@ func (s *supplementedImageReference) NewImageSource(ctx context.Context, sys *ty // Mark this instance as being associated with this ImageSource. manifestDigest, err := manifest.Digest(manifestBytes) if err != nil { - return errors.Wrapf(err, "error computing digest over manifest %q", string(manifestBytes)) + return fmt.Errorf("error computing digest over manifest %q: %w", string(manifestBytes), err) } sources[manifestDigest] = src // Parse the manifest as a single image. man, err := manifest.FromBlob(manifestBytes, manifestType) if err != nil { - return errors.Wrapf(err, "error parsing manifest %q", string(manifestBytes)) + return fmt.Errorf("error parsing manifest %q: %w", string(manifestBytes), err) } // Log the config blob's digest and the blobs of its layers as associated with this manifest. @@ -135,14 +135,14 @@ func (s *supplementedImageReference) NewImageSource(ctx context.Context, sys *ty // Mark this instance as being associated with this ImageSource. manifestDigest, err := manifest.Digest(manifestBytes) if err != nil { - return errors.Wrapf(err, "error computing manifest digest") + return fmt.Errorf("error computing manifest digest: %w", err) } sources[manifestDigest] = src // Parse the manifest as a list of images. list, err := manifest.ListFromBlob(manifestBytes, manifestType) if err != nil { - return errors.Wrapf(err, "error parsing manifest blob %q as a %q", string(manifestBytes), manifestType) + return fmt.Errorf("error parsing manifest blob %q as a %q: %w", string(manifestBytes), manifestType, err) } // Figure out which of its instances we want to look at. @@ -151,7 +151,7 @@ func (s *supplementedImageReference) NewImageSource(ctx context.Context, sys *ty case cp.CopySystemImage: instance, err := list.ChooseInstance(sys) if err != nil { - return errors.Wrapf(err, "error selecting appropriate instance from list") + return fmt.Errorf("error selecting appropriate instance from list: %w", err) } chaseInstances = []digest.Digest{instance} case cp.CopySpecificImages: @@ -194,14 +194,14 @@ func (s *supplementedImageReference) NewImageSource(ctx context.Context, sys *ty } else { src, err = ref.NewImageSource(ctx, sys) if err != nil { - return nil, errors.Wrapf(err, "error opening %q as image source", transports.ImageName(ref)) + return nil, fmt.Errorf("error opening %q as image source: %w", transports.ImageName(ref), err) } } // Read the default manifest for the image. manifestBytes, manifestType, err := src.GetManifest(ctx, nil) if err != nil { - return nil, errors.Wrapf(err, "error reading default manifest from image %q", transports.ImageName(ref)) + return nil, fmt.Errorf("error reading default manifest from image %q: %w", transports.ImageName(ref), err) } // If this is the first image, mark it as our starting point. @@ -223,18 +223,18 @@ func (s *supplementedImageReference) NewImageSource(ctx context.Context, sys *ty // Record the digest of the ImageSource's default instance's manifest. manifestDigest, err := manifest.Digest(manifestBytes) if err != nil { - return nil, errors.Wrapf(err, "error computing digest of manifest from image %q", transports.ImageName(ref)) + return nil, fmt.Errorf("error computing digest of manifest from image %q: %w", transports.ImageName(ref), err) } sis.sourceDefaultInstances[src] = manifestDigest // If the ImageSource's default manifest is a list, parse each of its instances. if manifest.MIMETypeIsMultiImage(manifestType) { if err = addMulti(manifestBytes, manifestType, src); err != nil { - return nil, errors.Wrapf(err, "error adding multi-image %q", transports.ImageName(ref)) + return nil, fmt.Errorf("error adding multi-image %q: %w", transports.ImageName(ref), err) } } else { if err = addSingle(manifestBytes, manifestType, src); err != nil { - return nil, errors.Wrapf(err, "error adding single image %q", transports.ImageName(ref)) + return nil, fmt.Errorf("error adding single image %q: %w", transports.ImageName(ref), err) } } } @@ -257,22 +257,22 @@ func (s *supplementedImageReference) NewImageSource(ctx context.Context, sys *ty // Read the instance's manifest. manifestBytes, manifestType, err := manifestToRead.src.GetManifest(ctx, manifestToRead.instance) if err != nil { - // if errors.Cause(err) == storage.ErrImageUnknown || os.IsNotExist(errors.Cause(err)) { + // if errors.Is(err, storage.ErrImageUnknown) || errors.Is(err, os.ErrNotExist) { // Trust that we either don't need it, or that it's in another reference. // continue // } - return nil, errors.Wrapf(err, "error reading manifest for instance %q", manifestToRead.instance) + return nil, fmt.Errorf("error reading manifest for instance %q: %w", manifestToRead.instance, err) } if manifest.MIMETypeIsMultiImage(manifestType) { // Add the list's contents. if err = addMulti(manifestBytes, manifestType, manifestToRead.src); err != nil { - return nil, errors.Wrapf(err, "error adding single image instance %q", manifestToRead.instance) + return nil, fmt.Errorf("error adding single image instance %q: %w", manifestToRead.instance, err) } } else { // Add the single image's contents. if err = addSingle(manifestBytes, manifestType, manifestToRead.src); err != nil { - return nil, errors.Wrapf(err, "error adding single image instance %q", manifestToRead.instance) + return nil, fmt.Errorf("error adding single image instance %q: %w", manifestToRead.instance, err) } } } @@ -281,7 +281,7 @@ func (s *supplementedImageReference) NewImageSource(ctx context.Context, sys *ty } func (s *supplementedImageReference) DeleteImage(ctx context.Context, sys *types.SystemContext) error { - return errors.Errorf("deletion of images not implemented") + return fmt.Errorf("deletion of images not implemented") } func (s *supplementedImageSource) Close() error { @@ -313,17 +313,17 @@ func (s *supplementedImageSource) GetManifest(ctx context.Context, instanceDiges } return sourceInstance.GetManifest(ctx, requestInstanceDigest) } - return nil, "", errors.Wrapf(ErrDigestNotFound, "error getting manifest for digest %q", *instanceDigest) + return nil, "", fmt.Errorf("error getting manifest for digest %q: %w", *instanceDigest, ErrDigestNotFound) } func (s *supplementedImageSource) GetBlob(ctx context.Context, blob types.BlobInfo, bic types.BlobInfoCache) (io.ReadCloser, int64, error) { sourceInstance, ok := s.instancesByBlobDigest[blob.Digest] if !ok { - return nil, -1, errors.Wrapf(ErrBlobNotFound, "error blob %q in known instances", blob.Digest) + return nil, -1, fmt.Errorf("error blob %q in known instances: %w", blob.Digest, ErrBlobNotFound) } src, ok := s.sourceInstancesByInstance[sourceInstance] if !ok { - return nil, -1, errors.Wrapf(ErrDigestNotFound, "error getting image source for instance %q", sourceInstance) + return nil, -1, fmt.Errorf("error getting image source for instance %q: %w", sourceInstance, ErrDigestNotFound) } return src.GetBlob(ctx, blob, bic) } @@ -364,7 +364,7 @@ func (s *supplementedImageSource) GetSignatures(ctx context.Context, instanceDig if src != nil { return src.GetSignatures(ctx, requestInstanceDigest) } - return nil, errors.Wrapf(ErrDigestNotFound, "error finding instance for instance digest %q to read signatures", digest) + return nil, fmt.Errorf("error finding instance for instance digest %q to read signatures: %w", digest, ErrDigestNotFound) } func (s *supplementedImageSource) LayerInfosForCopy(ctx context.Context, instanceDigest *digest.Digest) ([]types.BlobInfo, error) { @@ -387,7 +387,7 @@ func (s *supplementedImageSource) LayerInfosForCopy(ctx context.Context, instanc if src != nil { blobInfos, err := src.LayerInfosForCopy(ctx, requestInstanceDigest) if err != nil { - return nil, errors.Wrapf(err, "error reading layer infos for copy from instance %q", instanceDigest) + return nil, fmt.Errorf("error reading layer infos for copy from instance %q: %w", instanceDigest, err) } var manifestDigest digest.Digest if instanceDigest != nil { @@ -398,5 +398,5 @@ func (s *supplementedImageSource) LayerInfosForCopy(ctx context.Context, instanc } return blobInfos, nil } - return nil, errors.Wrapf(ErrDigestNotFound, "error finding instance for instance digest %q to copy layers", errMsgDigest) + return nil, fmt.Errorf("error finding instance for instance digest %q to copy layers: %w", errMsgDigest, ErrDigestNotFound) } diff --git a/pkg/sysctl/sysctl.go b/pkg/sysctl/sysctl.go index e9ff4aaf3..0df4c90e6 100644 --- a/pkg/sysctl/sysctl.go +++ b/pkg/sysctl/sysctl.go @@ -3,8 +3,6 @@ package sysctl import ( "fmt" "strings" - - "github.com/pkg/errors" ) // Validate validates a list of sysctl and returns it. @@ -29,12 +27,12 @@ func Validate(strSlice []string) (map[string]string, error) { foundMatch := false arr := strings.Split(val, "=") if len(arr) < 2 { - return nil, errors.Errorf("%s is invalid, sysctl values must be in the form of KEY=VALUE", val) + return nil, fmt.Errorf("%s is invalid, sysctl values must be in the form of KEY=VALUE", val) } trimmed := fmt.Sprintf("%s=%s", strings.TrimSpace(arr[0]), strings.TrimSpace(arr[1])) if trimmed != val { - return nil, errors.Errorf("%q is invalid, extra spaces found", val) + return nil, fmt.Errorf("%q is invalid, extra spaces found", val) } if validSysctlMap[arr[0]] { @@ -50,7 +48,7 @@ func Validate(strSlice []string) (map[string]string, error) { } } if !foundMatch { - return nil, errors.Errorf("sysctl %q is not allowed", arr[0]) + return nil, fmt.Errorf("sysctl %q is not allowed", arr[0]) } } return sysctl, nil diff --git a/pkg/sysinfo/sysinfo_linux.go b/pkg/sysinfo/sysinfo_linux.go index 6420ba274..39cc5beb0 100644 --- a/pkg/sysinfo/sysinfo_linux.go +++ b/pkg/sysinfo/sysinfo_linux.go @@ -1,6 +1,8 @@ package sysinfo import ( + "errors" + "fmt" "io/ioutil" "os" "path" @@ -8,7 +10,6 @@ import ( "github.com/containers/common/pkg/cgroupv2" "github.com/opencontainers/runc/libcontainer/cgroups" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) @@ -16,7 +17,7 @@ import ( func findCgroupMountpoints() (map[string]string, error) { cgMounts, err := cgroups.GetCgroupMounts(false) if err != nil { - return nil, errors.Wrap(err, "parse cgroup information") + return nil, fmt.Errorf("parse cgroup information: %w", err) } mps := make(map[string]string) for _, m := range cgMounts { @@ -51,7 +52,7 @@ func New(quiet bool) *SysInfo { sysInfo.BridgeNFCallIP6TablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-ip6tables") // Check if AppArmor is supported. - if _, err := os.Stat("/sys/kernel/security/apparmor"); !os.IsNotExist(err) { + if _, err := os.Stat("/sys/kernel/security/apparmor"); !errors.Is(err, os.ErrNotExist) { sysInfo.AppArmor = true } diff --git a/pkg/sysinfo/sysinfo_linux_test.go b/pkg/sysinfo/sysinfo_linux_test.go index 29d96af57..4854b3aa0 100644 --- a/pkg/sysinfo/sysinfo_linux_test.go +++ b/pkg/sysinfo/sysinfo_linux_test.go @@ -1,6 +1,7 @@ package sysinfo import ( + "errors" "io/ioutil" "os" "path" @@ -87,7 +88,7 @@ func TestNewAppArmorEnabled(t *testing.T) { func TestNewAppArmorDisabled(t *testing.T) { // Check if AppArmor is supported. then it must be TRUE , else FALSE - if _, err := os.Stat("/sys/kernel/security/apparmor"); !os.IsNotExist(err) { + if _, err := os.Stat("/sys/kernel/security/apparmor"); !errors.Is(err, os.ErrNotExist) { t.Skip("App Armor Must be Disabled") } @@ -103,7 +104,7 @@ func TestNumCPU(t *testing.T) { } func TestNumMems(t *testing.T) { - if _, err := os.Stat("/proc/self/numa_maps"); !os.IsNotExist(err) { + if _, err := os.Stat("/proc/self/numa_maps"); !errors.Is(err, os.ErrNotExist) { t.Skip("NUMA must be supported") } cpuMems := NUMANodeCount() diff --git a/pkg/util/util_supported.go b/pkg/util/util_supported.go index 35201f932..6d7060af4 100644 --- a/pkg/util/util_supported.go +++ b/pkg/util/util_supported.go @@ -4,6 +4,7 @@ package util import ( + "errors" "fmt" "os" "path/filepath" @@ -11,7 +12,6 @@ import ( "syscall" "github.com/containers/storage/pkg/unshare" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -72,7 +72,7 @@ func GetRuntimeDir() (string, error) { } resolvedHome, err := filepath.EvalSymlinks(home) if err != nil { - rootlessRuntimeDirError = errors.Wrap(err, "cannot resolve home") + rootlessRuntimeDirError = fmt.Errorf("cannot resolve home: %w", err) return } runtimeDir = filepath.Join(resolvedHome, "rundir") diff --git a/pkg/util/util_windows.go b/pkg/util/util_windows.go index 1cffb21fc..1525bdc34 100644 --- a/pkg/util/util_windows.go +++ b/pkg/util/util_windows.go @@ -4,7 +4,7 @@ package util import ( - "github.com/pkg/errors" + "errors" ) // getRuntimeDir returns the runtime directory