diff --git a/copy/blob.go b/copy/blob.go index b1ee4635f..cfac3e6d5 100644 --- a/copy/blob.go +++ b/copy/blob.go @@ -9,7 +9,6 @@ import ( "github.com/containers/image/v5/internal/private" compressiontypes "github.com/containers/image/v5/pkg/compression/types" "github.com/containers/image/v5/types" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -36,7 +35,7 @@ func (ic *imageCopier) copyBlobFromStream(ctx context.Context, srcReader io.Read // read stream to the end, and validation does not happen. digestingReader, err := newDigestingReader(stream.reader, srcInfo.Digest) if err != nil { - return types.BlobInfo{}, perrors.Wrapf(err, "preparing to verify blob %s", srcInfo.Digest) + return types.BlobInfo{}, fmt.Errorf("preparing to verify blob %s: %w", srcInfo.Digest, err) } stream.reader = digestingReader @@ -107,7 +106,7 @@ func (ic *imageCopier) copyBlobFromStream(ctx context.Context, srcReader io.Read } uploadedInfo, err := ic.c.dest.PutBlobWithOptions(ctx, &errorAnnotationReader{stream.reader}, stream.info, options) if err != nil { - return types.BlobInfo{}, perrors.Wrap(err, "writing blob") + return types.BlobInfo{}, fmt.Errorf("writing blob: %w", err) } uploadedInfo.Annotations = stream.info.Annotations @@ -126,7 +125,7 @@ func (ic *imageCopier) copyBlobFromStream(ctx context.Context, srcReader io.Read logrus.Debugf("Consuming rest of the original blob to satisfy getOriginalLayerCopyWriter") _, err := io.Copy(io.Discard, originalLayerReader) if err != nil { - return types.BlobInfo{}, perrors.Wrapf(err, "reading input blob %s", srcInfo.Digest) + return types.BlobInfo{}, fmt.Errorf("reading input blob %s: %w", srcInfo.Digest, err) } } @@ -165,8 +164,8 @@ type errorAnnotationReader struct { // Read annotates the error happened during read func (r errorAnnotationReader) Read(b []byte) (n int, err error) { n, err = r.reader.Read(b) - if err != io.EOF { - return n, perrors.Wrapf(err, "happened during read") + if err != nil && err != io.EOF { + return n, fmt.Errorf("happened during read: %w", err) } return n, err } diff --git a/copy/compression.go b/copy/compression.go index 559e440ad..ff0e7945d 100644 --- a/copy/compression.go +++ b/copy/compression.go @@ -9,7 +9,6 @@ import ( "github.com/containers/image/v5/pkg/compression" compressiontypes "github.com/containers/image/v5/pkg/compression/types" "github.com/containers/image/v5/types" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -28,7 +27,7 @@ func blobPipelineDetectCompressionStep(stream *sourceStream, srcInfo types.BlobI // This requires us to “peek ahead” into the stream to read the initial part, which requires us to chain through another io.Reader returned by DetectCompression. format, decompressor, reader, err := compression.DetectCompressionFormat(stream.reader) // We could skip this in some cases, but let's keep the code path uniform if err != nil { - return bpDetectCompressionStepData{}, perrors.Wrapf(err, "reading blob %s", srcInfo.Digest) + return bpDetectCompressionStepData{}, fmt.Errorf("reading blob %s: %w", srcInfo.Digest, err) } stream.reader = reader diff --git a/copy/copy.go b/copy/copy.go index 6b3b0eeb1..a318d3f82 100644 --- a/copy/copy.go +++ b/copy/copy.go @@ -30,7 +30,6 @@ import ( encconfig "github.com/containers/ocicrypt/config" digest "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/vbauerster/mpb/v7" "golang.org/x/sync/semaphore" @@ -208,23 +207,31 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, publicDest, err := destRef.NewImageDestination(ctx, options.DestinationCtx) if err != nil { - return nil, perrors.Wrapf(err, "initializing destination %s", transports.ImageName(destRef)) + return nil, fmt.Errorf("initializing destination %s: %w", transports.ImageName(destRef), err) } dest := imagedestination.FromPublic(publicDest) defer func() { if err := dest.Close(); err != nil { - retErr = perrors.Wrapf(retErr, " (dest: %v)", err) + if retErr != nil { + retErr = fmt.Errorf(" (dest: %v): %w", err, retErr) + } else { + retErr = fmt.Errorf(" (dest: %v)", err) + } } }() publicRawSource, err := srcRef.NewImageSource(ctx, options.SourceCtx) if err != nil { - return nil, perrors.Wrapf(err, "initializing source %s", transports.ImageName(srcRef)) + return nil, fmt.Errorf("initializing source %s: %w", transports.ImageName(srcRef), err) } rawSource := imagesource.FromPublic(publicRawSource) defer func() { if err := rawSource.Close(); err != nil { - retErr = perrors.Wrapf(retErr, " (src: %v)", err) + if retErr != nil { + retErr = fmt.Errorf(" (src: %v): %w", err, retErr) + } else { + retErr = fmt.Errorf(" (src: %v)", err) + } } }() @@ -281,7 +288,7 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, unparsedToplevel := image.UnparsedInstance(rawSource, nil) multiImage, err := isMultiImage(ctx, unparsedToplevel) if err != nil { - return nil, perrors.Wrapf(err, "determining manifest MIME type for %s", transports.ImageName(srcRef)) + return nil, fmt.Errorf("determining manifest MIME type for %s: %w", transports.ImageName(srcRef), err) } if !multiImage { @@ -294,21 +301,21 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, // matches the current system to copy, and copy it. mfest, manifestType, err := unparsedToplevel.Manifest(ctx) if err != nil { - return nil, perrors.Wrapf(err, "reading manifest for %s", transports.ImageName(srcRef)) + return nil, fmt.Errorf("reading manifest for %s: %w", transports.ImageName(srcRef), err) } manifestList, err := manifest.ListFromBlob(mfest, manifestType) if err != nil { - return nil, perrors.Wrapf(err, "parsing primary manifest as list for %s", transports.ImageName(srcRef)) + return nil, fmt.Errorf("parsing primary manifest as list for %s: %w", transports.ImageName(srcRef), err) } instanceDigest, err := manifestList.ChooseInstance(options.SourceCtx) // try to pick one that matches options.SourceCtx if err != nil { - return nil, perrors.Wrapf(err, "choosing an image from manifest list %s", transports.ImageName(srcRef)) + return nil, fmt.Errorf("choosing an image from manifest list %s: %w", transports.ImageName(srcRef), err) } logrus.Debugf("Source is a manifest list; copying (only) instance %s for current system", instanceDigest) unparsedInstance := image.UnparsedInstance(rawSource, &instanceDigest) if copiedManifest, _, _, err = c.copyOneImage(ctx, policyContext, options, unparsedToplevel, unparsedInstance, nil); err != nil { - return nil, perrors.Wrap(err, "copying system image from manifest list") + return nil, fmt.Errorf("copying system image from manifest list: %w", err) } } else { /* options.ImageListSelection == CopyAllImages or options.ImageListSelection == CopySpecificImages, */ // If we were asked to copy multiple images and can't, that's an error. @@ -328,7 +335,7 @@ func Image(ctx context.Context, policyContext *signature.PolicyContext, destRef, } if err := c.dest.Commit(ctx, unparsedToplevel); err != nil { - return nil, perrors.Wrap(err, "committing the finished image") + return nil, fmt.Errorf("committing the finished image: %w", err) } return copiedManifest, nil @@ -355,7 +362,7 @@ func supportsMultipleImages(dest types.ImageDestination) bool { func compareImageDestinationManifestEqual(ctx context.Context, options *Options, src *image.SourcedImage, targetInstance *digest.Digest, dest types.ImageDestination) (bool, []byte, string, digest.Digest, error) { srcManifestDigest, err := manifest.Digest(src.ManifestBlob) if err != nil { - return false, nil, "", "", perrors.Wrapf(err, "calculating manifest digest") + return false, nil, "", "", fmt.Errorf("calculating manifest digest: %w", err) } destImageSource, err := dest.Reference().NewImageSource(ctx, options.DestinationCtx) @@ -372,7 +379,7 @@ func compareImageDestinationManifestEqual(ctx context.Context, options *Options, destManifestDigest, err := manifest.Digest(destManifest) if err != nil { - return false, nil, "", "", perrors.Wrapf(err, "calculating manifest digest") + return false, nil, "", "", fmt.Errorf("calculating manifest digest: %w", err) } logrus.Debugf("Comparing source and destination manifest digests: %v vs. %v", srcManifestDigest, destManifestDigest) @@ -390,11 +397,11 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur // Parse the list and get a copy of the original value after it's re-encoded. manifestList, manifestType, err := unparsedToplevel.Manifest(ctx) if err != nil { - return nil, perrors.Wrapf(err, "reading manifest list") + return nil, fmt.Errorf("reading manifest list: %w", err) } originalList, err := manifest.ListFromBlob(manifestList, manifestType) if err != nil { - return nil, perrors.Wrapf(err, "parsing manifest list %q", string(manifestList)) + return nil, fmt.Errorf("parsing manifest list %q: %w", string(manifestList), err) } updatedList := originalList.Clone() @@ -406,14 +413,14 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur c.Printf("Getting image list signatures\n") s, err := c.rawSource.GetSignaturesWithFormat(ctx, nil) if err != nil { - return nil, perrors.Wrap(err, "reading signatures") + return nil, fmt.Errorf("reading signatures: %w", err) } sigs = s } if len(sigs) != 0 { c.Printf("Checking if image list destination supports signatures\n") if err := c.dest.SupportsSignatures(ctx); err != nil { - return nil, perrors.Wrapf(err, "Can not copy signatures to %s", transports.ImageName(c.dest.Reference())) + return nil, fmt.Errorf("Can not copy signatures to %s: %w", transports.ImageName(c.dest.Reference()), err) } } @@ -425,7 +432,7 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur destIsDigestedReference = true matches, err := manifest.MatchesDigest(manifestList, digested.Digest()) if err != nil { - return nil, perrors.Wrapf(err, "computing digest of source image's manifest") + return nil, fmt.Errorf("computing digest of source image's manifest: %w", err) } if !matches { return nil, errors.New("Digest of source image's manifest would not match destination reference") @@ -457,7 +464,7 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur } selectedListType, otherManifestMIMETypeCandidates, err := c.determineListConversion(manifestType, c.dest.SupportedManifestMIMETypes(), forceListMIMEType) if err != nil { - return nil, perrors.Wrapf(err, "determining manifest list type to write to destination") + return nil, fmt.Errorf("determining manifest list type to write to destination: %w", err) } if selectedListType != originalList.MIMEType() { if cannotModifyManifestListReason != "" { @@ -499,7 +506,7 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur unparsedInstance := image.UnparsedInstance(c.rawSource, &instanceDigest) updatedManifest, updatedManifestType, updatedManifestDigest, err := c.copyOneImage(ctx, policyContext, options, unparsedToplevel, unparsedInstance, &instanceDigest) if err != nil { - return nil, perrors.Wrapf(err, "copying image %d/%d from manifest list", instancesCopied+1, imagesToCopy) + return nil, fmt.Errorf("copying image %d/%d from manifest list: %w", instancesCopied+1, imagesToCopy, err) } instancesCopied++ // Record the result of a possible conversion here. @@ -513,7 +520,7 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur // Now reset the digest/size/types of the manifests in the list to account for any conversions that we made. if err = updatedList.UpdateInstances(updates); err != nil { - return nil, perrors.Wrapf(err, "updating manifest list") + return nil, fmt.Errorf("updating manifest list: %w", err) } // Iterate through supported list types, preferred format first. @@ -528,7 +535,7 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur if thisListType != updatedList.MIMEType() { attemptedList, err = updatedList.ConvertToMIMEType(thisListType) if err != nil { - return nil, perrors.Wrapf(err, "converting manifest list to list with MIME type %q", thisListType) + return nil, fmt.Errorf("converting manifest list to list with MIME type %q: %w", thisListType, err) } } @@ -536,11 +543,11 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur // by serializing them both so that we can compare them. attemptedManifestList, err := attemptedList.Serialize() if err != nil { - return nil, perrors.Wrapf(err, "encoding updated manifest list (%q: %#v)", updatedList.MIMEType(), updatedList.Instances()) + return nil, fmt.Errorf("encoding updated manifest list (%q: %#v): %w", updatedList.MIMEType(), updatedList.Instances(), err) } originalManifestList, err := originalList.Serialize() if err != nil { - return nil, perrors.Wrapf(err, "encoding original manifest list for comparison (%q: %#v)", originalList.MIMEType(), originalList.Instances()) + return nil, fmt.Errorf("encoding original manifest list for comparison (%q: %#v): %w", originalList.MIMEType(), originalList.Instances(), err) } // If we can't just use the original value, but we have to change it, flag an error. @@ -587,7 +594,7 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur c.Printf("Storing list signatures\n") if err := c.dest.PutSignaturesWithFormat(ctx, sigs, nil); err != nil { - return nil, perrors.Wrap(err, "writing signatures") + return nil, fmt.Errorf("writing signatures: %w", err) } return manifestList, nil @@ -601,7 +608,7 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli multiImage, err := isMultiImage(ctx, unparsedImage) if err != nil { // FIXME FIXME: How to name a reference for the sub-image? - return nil, "", "", perrors.Wrapf(err, "determining manifest MIME type for %s", transports.ImageName(unparsedImage.Reference())) + return nil, "", "", fmt.Errorf("determining manifest MIME type for %s: %w", transports.ImageName(unparsedImage.Reference()), err) } if multiImage { return nil, "", "", fmt.Errorf("Unexpectedly received a manifest list instead of a manifest for a single image") @@ -611,11 +618,11 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli // (The multiImage check above only matches the MIME type, which we have received anyway. // Actual parsing of anything should be deferred.) if allowed, err := policyContext.IsRunningImageAllowed(ctx, unparsedImage); !allowed || err != nil { // Be paranoid and fail if either return value indicates so. - return nil, "", "", perrors.Wrap(err, "Source image rejected") + return nil, "", "", fmt.Errorf("Source image rejected: %w", err) } src, err := image.FromUnparsedImage(ctx, options.SourceCtx, unparsedImage) if err != nil { - return nil, "", "", perrors.Wrapf(err, "initializing image from source %s", transports.ImageName(c.rawSource.Reference())) + return nil, "", "", fmt.Errorf("initializing image from source %s: %w", transports.ImageName(c.rawSource.Reference()), err) } // If the destination is a digested reference, make a note of that, determine what digest value we're @@ -627,16 +634,16 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli destIsDigestedReference = true matches, err := manifest.MatchesDigest(src.ManifestBlob, digested.Digest()) if err != nil { - return nil, "", "", perrors.Wrapf(err, "computing digest of source image's manifest") + return nil, "", "", fmt.Errorf("computing digest of source image's manifest: %w", err) } if !matches { manifestList, _, err := unparsedToplevel.Manifest(ctx) if err != nil { - return nil, "", "", perrors.Wrapf(err, "reading manifest from source image") + return nil, "", "", fmt.Errorf("reading manifest from source image: %w", err) } matches, err = manifest.MatchesDigest(manifestList, digested.Digest()) if err != nil { - return nil, "", "", perrors.Wrapf(err, "computing digest of source image's manifest") + return nil, "", "", fmt.Errorf("computing digest of source image's manifest: %w", err) } if !matches { return nil, "", "", errors.New("Digest of source image's manifest would not match destination reference") @@ -656,14 +663,14 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli c.Printf("Getting image source signatures\n") s, err := src.UntrustedSignatures(ctx) if err != nil { - return nil, "", "", perrors.Wrap(err, "reading signatures") + return nil, "", "", fmt.Errorf("reading signatures: %w", err) } sigs = s } if len(sigs) != 0 { c.Printf("Checking if image destination supports signatures\n") if err := c.dest.SupportsSignatures(ctx); err != nil { - return nil, "", "", perrors.Wrapf(err, "Can not copy signatures to %s", transports.ImageName(c.dest.Reference())) + return nil, "", "", fmt.Errorf("Can not copy signatures to %s: %w", transports.ImageName(c.dest.Reference()), err) } } @@ -778,7 +785,7 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli // With ic.cannotModifyManifestReason != "", that would just be a string of repeated failures for the same reason, // so let’s bail out early and with a better error message. if ic.cannotModifyManifestReason != "" { - return nil, "", "", perrors.Wrapf(err, "Writing manifest failed and we cannot try conversions: %q", cannotModifyManifestReason) + return nil, "", "", fmt.Errorf("writing manifest failed and we cannot try conversions: %q: %w", cannotModifyManifestReason, err) } // errs is a list of errors when trying various manifest types. Also serves as an "upload succeeded" flag when set to nil. @@ -825,7 +832,7 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli c.Printf("Storing signatures\n") if err := c.dest.PutSignaturesWithFormat(ctx, sigs, targetInstance); err != nil { - return nil, "", "", perrors.Wrap(err, "writing signatures") + return nil, "", "", fmt.Errorf("writing signatures: %w", err) } return manifestBytes, retManifestType, retManifestDigest, nil @@ -845,11 +852,11 @@ func checkImageDestinationForCurrentRuntime(ctx context.Context, sys *types.Syst if dest.MustMatchRuntimeOS() { c, err := src.OCIConfig(ctx) if err != nil { - return perrors.Wrapf(err, "parsing image configuration") + return fmt.Errorf("parsing image configuration: %w", err) } wantedPlatforms, err := platform.WantedPlatforms(sys) if err != nil { - return perrors.Wrapf(err, "getting current platform information %#v", sys) + return fmt.Errorf("getting current platform information %#v: %w", sys, err) } options := newOrderedSet() @@ -1057,13 +1064,13 @@ func (ic *imageCopier) copyUpdatedConfigAndManifest(ctx context.Context, instanc } pi, err := ic.src.UpdatedImage(ctx, *ic.manifestUpdates) if err != nil { - return nil, "", perrors.Wrap(err, "creating an updated image manifest") + return nil, "", fmt.Errorf("creating an updated image manifest: %w", err) } pendingImage = pi } man, _, err := pendingImage.Manifest(ctx) if err != nil { - return nil, "", perrors.Wrap(err, "reading manifest") + return nil, "", fmt.Errorf("reading manifest: %w", err) } if err := ic.copyConfig(ctx, pendingImage); err != nil { @@ -1080,7 +1087,7 @@ func (ic *imageCopier) copyUpdatedConfigAndManifest(ctx context.Context, instanc } if err := ic.c.dest.PutManifest(ctx, man, instanceDigest); err != nil { logrus.Debugf("Error %v while writing manifest %q", err, string(man)) - return nil, "", perrors.Wrapf(err, "writing manifest") + return nil, "", fmt.Errorf("writing manifest: %w", err) } return man, manifestDigest, nil } @@ -1103,7 +1110,7 @@ func (ic *imageCopier) copyConfig(ctx context.Context, src types.Image) error { configBlob, err := src.ConfigBlob(ctx) if err != nil { - return types.BlobInfo{}, perrors.Wrapf(err, "reading config blob %s", srcInfo.Digest) + return types.BlobInfo{}, fmt.Errorf("reading config blob %s: %w", srcInfo.Digest, err) } destInfo, err := ic.copyBlobFromStream(ctx, bytes.NewReader(configBlob), srcInfo, nil, true, false, bar, -1, false) @@ -1183,7 +1190,7 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to SrcRef: srcRef, }) if err != nil { - return types.BlobInfo{}, "", perrors.Wrapf(err, "trying to reuse blob %s at destination", srcInfo.Digest) + return types.BlobInfo{}, "", fmt.Errorf("trying to reuse blob %s at destination: %w", srcInfo.Digest, err) } if reused { logrus.Debugf("Skipping blob %s (already present):", srcInfo.Digest) @@ -1257,7 +1264,7 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to srcStream, srcBlobSize, err := ic.c.rawSource.GetBlob(ctx, srcInfo, ic.c.blobInfoCache) if err != nil { - return types.BlobInfo{}, "", perrors.Wrapf(err, "reading blob %s", srcInfo.Digest) + return types.BlobInfo{}, "", fmt.Errorf("reading blob %s: %w", srcInfo.Digest, err) } defer srcStream.Close() @@ -1273,7 +1280,7 @@ func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, to return types.BlobInfo{}, "", ctx.Err() case diffIDResult := <-diffIDChan: if diffIDResult.err != nil { - return types.BlobInfo{}, "", perrors.Wrap(diffIDResult.err, "computing layer DiffID") + return types.BlobInfo{}, "", fmt.Errorf("computing layer DiffID: %w", diffIDResult.err) } logrus.Debugf("Computed DiffID %s for layer %s", diffIDResult.digest, srcInfo.Digest) // Don’t record any associations that involve encrypted data. This is a bit crude, diff --git a/copy/digesting_reader.go b/copy/digesting_reader.go index d8d08cd4c..901d10826 100644 --- a/copy/digesting_reader.go +++ b/copy/digesting_reader.go @@ -6,7 +6,6 @@ import ( "io" digest "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" ) type digestingReader struct { @@ -48,7 +47,7 @@ func (d *digestingReader) Read(p []byte) (int, error) { // Coverage: This should not happen, the hash.Hash interface requires // d.digest.Write to never return an error, and the io.Writer interface // requires n2 == len(input) if no error is returned. - return 0, perrors.Wrapf(err, "updating digest during verification: %d vs. %d", n2, n) + return 0, fmt.Errorf("updating digest during verification: %d vs. %d: %w", n2, n, err) } } if err == io.EOF { diff --git a/copy/encryption.go b/copy/encryption.go index 2025a9b71..5eae8bfcd 100644 --- a/copy/encryption.go +++ b/copy/encryption.go @@ -1,12 +1,12 @@ package copy import ( + "fmt" "strings" "github.com/containers/image/v5/types" "github.com/containers/ocicrypt" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" - perrors "github.com/pkg/errors" ) // isOciEncrypted returns a bool indicating if a mediatype is encrypted @@ -41,7 +41,7 @@ func (c *copier) blobPipelineDecryptionStep(stream *sourceStream, srcInfo types. } reader, decryptedDigest, err := ocicrypt.DecryptLayer(c.ociDecryptConfig, stream.reader, desc, false) if err != nil { - return nil, perrors.Wrapf(err, "decrypting layer %s", srcInfo.Digest) + return nil, fmt.Errorf("decrypting layer %s: %w", srcInfo.Digest, err) } stream.reader = reader @@ -92,7 +92,7 @@ func (c *copier) blobPipelineEncryptionStep(stream *sourceStream, toEncrypt bool } reader, finalizer, err := ocicrypt.EncryptLayer(c.ociEncryptConfig, stream.reader, desc) if err != nil { - return nil, perrors.Wrapf(err, "encrypting blob %s", srcInfo.Digest) + return nil, fmt.Errorf("encrypting blob %s: %w", srcInfo.Digest, err) } stream.reader = reader @@ -116,7 +116,7 @@ func (d *bpEncryptionStepData) updateCryptoOperationAndAnnotations(operation *ty encryptAnnotations, err := d.finalizer() if err != nil { - return perrors.Wrap(err, "Unable to finalize encryption") + return fmt.Errorf("Unable to finalize encryption: %w", err) } *operation = types.Encrypt if *annotations == nil { diff --git a/copy/sign.go b/copy/sign.go index 77f17ca0e..0ea06f4bb 100644 --- a/copy/sign.go +++ b/copy/sign.go @@ -8,18 +8,17 @@ import ( "github.com/containers/image/v5/signature" "github.com/containers/image/v5/signature/sigstore" "github.com/containers/image/v5/transports" - perrors "github.com/pkg/errors" ) // createSignature creates a new signature of manifest using keyIdentity. func (c *copier) createSignature(manifest []byte, keyIdentity string, passphrase string, identity reference.Named) (internalsig.Signature, error) { mech, err := signature.NewGPGSigningMechanism() if err != nil { - return nil, perrors.Wrap(err, "initializing GPG") + return nil, fmt.Errorf("initializing GPG: %w", err) } defer mech.Close() if err := mech.SupportsSigning(); err != nil { - return nil, perrors.Wrap(err, "Signing not supported") + return nil, fmt.Errorf("Signing not supported: %w", err) } if identity != nil { @@ -36,7 +35,7 @@ func (c *copier) createSignature(manifest []byte, keyIdentity string, passphrase c.Printf("Signing manifest using simple signing\n") newSig, err := signature.SignDockerManifestWithOptions(manifest, identity.String(), mech, keyIdentity, &signature.SignOptions{Passphrase: passphrase}) if err != nil { - return nil, perrors.Wrap(err, "creating signature") + return nil, fmt.Errorf("creating signature: %w", err) } return internalsig.SimpleSigningFromBlob(newSig), nil } diff --git a/directory/directory_dest.go b/directory/directory_dest.go index 87029f887..47a5c17cd 100644 --- a/directory/directory_dest.go +++ b/directory/directory_dest.go @@ -16,7 +16,6 @@ import ( "github.com/containers/image/v5/internal/signature" "github.com/containers/image/v5/types" "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -56,7 +55,7 @@ func newImageDestination(sys *types.SystemContext, ref dirReference) (private.Im // if the contents don't match throw an error dirExists, err := pathExists(ref.resolvedPath) if err != nil { - return nil, perrors.Wrapf(err, "checking for path %q", ref.resolvedPath) + return nil, fmt.Errorf("checking for path %q: %w", ref.resolvedPath, err) } if dirExists { isEmpty, err := isDirEmpty(ref.resolvedPath) @@ -67,7 +66,7 @@ func newImageDestination(sys *types.SystemContext, ref dirReference) (private.Im if !isEmpty { versionExists, err := pathExists(ref.versionPath()) if err != nil { - return nil, perrors.Wrapf(err, "checking if path exists %q", ref.versionPath()) + return nil, fmt.Errorf("checking if path exists %q: %w", ref.versionPath(), err) } if versionExists { contents, err := os.ReadFile(ref.versionPath()) @@ -83,20 +82,20 @@ func newImageDestination(sys *types.SystemContext, ref dirReference) (private.Im } // delete directory contents so that only one image is in the directory at a time if err = removeDirContents(ref.resolvedPath); err != nil { - return nil, perrors.Wrapf(err, "erasing contents in %q", ref.resolvedPath) + return nil, fmt.Errorf("erasing contents in %q: %w", ref.resolvedPath, err) } logrus.Debugf("overwriting existing container image directory %q", ref.resolvedPath) } } else { // create directory if it doesn't exist if err := os.MkdirAll(ref.resolvedPath, 0755); err != nil { - return nil, perrors.Wrapf(err, "unable to create directory %q", ref.resolvedPath) + return nil, fmt.Errorf("unable to create directory %q: %w", ref.resolvedPath, err) } } // create version file err = os.WriteFile(ref.versionPath(), []byte(version), 0644) if err != nil { - return nil, perrors.Wrapf(err, "creating version file %q", ref.versionPath()) + return nil, fmt.Errorf("creating version file %q: %w", ref.versionPath(), err) } d := &dirImageDestination{ diff --git a/docker/archive/reader.go b/docker/archive/reader.go index ea9392b80..875a15257 100644 --- a/docker/archive/reader.go +++ b/docker/archive/reader.go @@ -7,7 +7,6 @@ import ( "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/transports" "github.com/containers/image/v5/types" - perrors "github.com/pkg/errors" ) // Reader manages a single Docker archive, allows listing its contents and accessing @@ -75,7 +74,7 @@ func (r *Reader) List() ([][]types.ImageReference, error) { for _, tag := range image.RepoTags { parsedTag, err := reference.ParseNormalizedNamed(tag) if err != nil { - return nil, perrors.Wrapf(err, "Invalid tag %#v in manifest item @%d", tag, imageIndex) + return nil, fmt.Errorf("Invalid tag %#v in manifest item @%d: %w", tag, imageIndex, err) } nt, ok := parsedTag.(reference.NamedTagged) if !ok { @@ -83,14 +82,14 @@ func (r *Reader) List() ([][]types.ImageReference, error) { } ref, err := newReference(r.path, nt, -1, r.archive, nil) if err != nil { - return nil, perrors.Wrapf(err, "creating a reference for tag %#v in manifest item @%d", tag, imageIndex) + return nil, fmt.Errorf("creating a reference for tag %#v in manifest item @%d: %w", tag, imageIndex, err) } refs = append(refs, ref) } if len(refs) == 0 { ref, err := newReference(r.path, nil, imageIndex, r.archive, nil) if err != nil { - return nil, perrors.Wrapf(err, "creating a reference for manifest item @%d", imageIndex) + return nil, fmt.Errorf("creating a reference for manifest item @%d: %w", imageIndex, err) } refs = append(refs, ref) } diff --git a/docker/archive/transport.go b/docker/archive/transport.go index 00a4930e3..9044b340b 100644 --- a/docker/archive/transport.go +++ b/docker/archive/transport.go @@ -12,7 +12,6 @@ import ( ctrImage "github.com/containers/image/v5/internal/image" "github.com/containers/image/v5/transports" "github.com/containers/image/v5/types" - perrors "github.com/pkg/errors" ) func init() { @@ -73,7 +72,7 @@ func ParseReference(refString string) (types.ImageReference, error) { if len(parts[1]) > 0 && parts[1][0] == '@' { i, err := strconv.Atoi(parts[1][1:]) if err != nil { - return nil, perrors.Wrapf(err, "Invalid source index %s", parts[1]) + return nil, fmt.Errorf("Invalid source index %s: %w", parts[1], err) } if i < 0 { return nil, fmt.Errorf("Invalid source index @%d: must not be negative", i) @@ -82,7 +81,7 @@ func ParseReference(refString string) (types.ImageReference, error) { } else { ref, err := reference.ParseNormalizedNamed(parts[1]) if err != nil { - return nil, perrors.Wrapf(err, "docker-archive parsing reference") + return nil, fmt.Errorf("docker-archive parsing reference: %w", err) } ref = reference.TagNameOnly(ref) refTagged, isTagged := ref.(reference.NamedTagged) diff --git a/docker/archive/writer.go b/docker/archive/writer.go index c79f925ed..2d8fafe29 100644 --- a/docker/archive/writer.go +++ b/docker/archive/writer.go @@ -2,13 +2,13 @@ package archive import ( "errors" + "fmt" "io" "os" "github.com/containers/image/v5/docker/internal/tarfile" "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/types" - perrors "github.com/pkg/errors" ) // Writer manages a single in-progress Docker archive and allows adding images to it. @@ -61,7 +61,7 @@ func openArchiveForWriting(path string) (*os.File, error) { // only in a different way. Either way, it’s up to the user to not have two writers to the same path.) fh, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644) if err != nil { - return nil, perrors.Wrapf(err, "opening file %q", path) + return nil, fmt.Errorf("opening file %q: %w", path, err) } succeeded := false defer func() { @@ -71,7 +71,7 @@ func openArchiveForWriting(path string) (*os.File, error) { }() fhStat, err := fh.Stat() if err != nil { - return nil, perrors.Wrapf(err, "statting file %q", path) + return nil, fmt.Errorf("statting file %q: %w", path, err) } if fhStat.Mode().IsRegular() && fhStat.Size() != 0 { diff --git a/docker/daemon/daemon_dest.go b/docker/daemon/daemon_dest.go index a5914f61f..dc4aa70d3 100644 --- a/docker/daemon/daemon_dest.go +++ b/docker/daemon/daemon_dest.go @@ -11,7 +11,6 @@ import ( "github.com/containers/image/v5/internal/private" "github.com/containers/image/v5/types" "github.com/docker/docker/client" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -45,7 +44,7 @@ func newImageDestination(ctx context.Context, sys *types.SystemContext, ref daem c, err := newDockerClient(sys) if err != nil { - return nil, perrors.Wrap(err, "initializing docker engine client") + return nil, fmt.Errorf("initializing docker engine client: %w", err) } reader, writer := io.Pipe() @@ -87,7 +86,7 @@ func imageLoadGoroutine(ctx context.Context, c *client.Client, reader *io.PipeRe resp, err := c.ImageLoad(ctx, reader, true) if err != nil { - err = perrors.Wrap(err, "saving image to docker engine") + err = fmt.Errorf("saving image to docker engine: %w", err) return } defer resp.Body.Close() diff --git a/docker/daemon/daemon_src.go b/docker/daemon/daemon_src.go index 754e7ef2a..b57936654 100644 --- a/docker/daemon/daemon_src.go +++ b/docker/daemon/daemon_src.go @@ -2,11 +2,11 @@ package daemon import ( "context" + "fmt" "github.com/containers/image/v5/docker/internal/tarfile" "github.com/containers/image/v5/internal/private" "github.com/containers/image/v5/types" - perrors "github.com/pkg/errors" ) type daemonImageSource struct { @@ -26,13 +26,13 @@ type daemonImageSource struct { func newImageSource(ctx context.Context, sys *types.SystemContext, ref daemonReference) (private.ImageSource, error) { c, err := newDockerClient(sys) if err != nil { - return nil, perrors.Wrap(err, "initializing docker engine client") + return nil, fmt.Errorf("initializing docker engine client: %w", err) } // Per NewReference(), ref.StringWithinTransport() is either an image ID (config digest), or a !reference.NameOnly() reference. // Either way ImageSave should create a tarball with exactly one image. inputStream, err := c.ImageSave(ctx, []string{ref.StringWithinTransport()}) if err != nil { - return nil, perrors.Wrap(err, "loading image from docker engine") + return nil, fmt.Errorf("loading image from docker engine: %w", err) } defer inputStream.Close() diff --git a/docker/docker_client.go b/docker/docker_client.go index 88639e095..5de076740 100644 --- a/docker/docker_client.go +++ b/docker/docker_client.go @@ -31,7 +31,6 @@ import ( "github.com/docker/go-connections/tlsconfig" digest "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -218,7 +217,7 @@ func dockerCertDir(sys *types.SystemContext, hostPort string) (string, error) { func newDockerClientFromRef(sys *types.SystemContext, ref dockerReference, registryConfig *registryConfiguration, write bool, actions string) (*dockerClient, error) { auth, err := config.GetCredentialsForRef(sys, ref.ref) if err != nil { - return nil, perrors.Wrapf(err, "getting username and password") + return nil, fmt.Errorf("getting username and password: %w", err) } sigBase, err := registryConfig.lookasideStorageBaseURL(ref, write) @@ -273,7 +272,7 @@ func newDockerClient(sys *types.SystemContext, registry, reference string) (*doc skipVerify := false reg, err := sysregistriesv2.FindRegistry(sys, reference) if err != nil { - return nil, perrors.Wrapf(err, "loading registries") + return nil, fmt.Errorf("loading registries: %w", err) } if reg != nil { if reg.Blocked { @@ -301,7 +300,7 @@ func newDockerClient(sys *types.SystemContext, registry, reference string) (*doc func CheckAuth(ctx context.Context, sys *types.SystemContext, username, password, registry string) error { client, err := newDockerClient(sys, registry, registry) if err != nil { - return perrors.Wrapf(err, "creating new docker client") + return fmt.Errorf("creating new docker client: %w", err) } client.auth = types.DockerAuthConfig{ Username: username, @@ -350,7 +349,7 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima // We can't use GetCredentialsForRef here because we want to search the whole registry. auth, err := config.GetCredentials(sys, registry) if err != nil { - return nil, perrors.Wrapf(err, "getting username and password") + return nil, fmt.Errorf("getting username and password: %w", err) } // The /v2/_catalog endpoint has been disabled for docker.io therefore @@ -364,7 +363,7 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima client, err := newDockerClient(sys, hostname, registry) if err != nil { - return nil, perrors.Wrapf(err, "creating new docker client") + return nil, fmt.Errorf("creating new docker client: %w", err) } client.auth = auth if sys != nil { @@ -407,13 +406,13 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima resp, err := client.makeRequest(ctx, http.MethodGet, path, nil, nil, v2Auth, nil) if err != nil { logrus.Debugf("error getting search results from v2 endpoint %q: %v", registry, err) - return nil, perrors.Wrapf(err, "couldn't search registry %q", registry) + return nil, fmt.Errorf("couldn't search registry %q: %w", registry, err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { err := httpResponseToError(resp, "") logrus.Errorf("error getting search results from v2 endpoint %q: %v", registry, err) - return nil, perrors.Wrapf(err, "couldn't search registry %q", registry) + return nil, fmt.Errorf("couldn't search registry %q: %w", registry, err) } v2Res := &V2Results{} if err := json.NewDecoder(resp.Body).Decode(v2Res); err != nil { @@ -767,7 +766,7 @@ func (c *dockerClient) detectPropertiesHelper(ctx context.Context) error { err = ping("http") } if err != nil { - err = perrors.Wrapf(err, "pinging container registry %s", c.registry) + err = fmt.Errorf("pinging container registry %s: %w", c.registry, err) if c.sys != nil && c.sys.DockerDisableV1Ping { return err } @@ -819,7 +818,7 @@ func (c *dockerClient) fetchManifest(ctx context.Context, ref dockerReference, t logrus.Debugf("Content-Type from manifest GET is %q", res.Header.Get("Content-Type")) defer res.Body.Close() if res.StatusCode != http.StatusOK { - return nil, "", perrors.Wrapf(registryHTTPResponseToError(res), "reading manifest %s in %s", tagOrDigest, ref.ref.Name()) + return nil, "", fmt.Errorf("reading manifest %s in %s: %w", tagOrDigest, ref.ref.Name(), registryHTTPResponseToError(res)) } manblob, err := iolimits.ReadAtMost(res.Body, iolimits.MaxManifestBodySize) @@ -978,7 +977,7 @@ func (c *dockerClient) getExtensionsSignatures(ctx context.Context, ref dockerRe defer res.Body.Close() if res.StatusCode != http.StatusOK { - return nil, perrors.Wrapf(clientLib.HandleErrorResponse(res), "downloading signatures for %s in %s", manifestDigest, ref.ref.Name()) + return nil, fmt.Errorf("downloading signatures for %s in %s: %w", manifestDigest, ref.ref.Name(), clientLib.HandleErrorResponse(res)) } body, err := iolimits.ReadAtMost(res.Body, iolimits.MaxSignatureListBodySize) @@ -988,7 +987,7 @@ func (c *dockerClient) getExtensionsSignatures(ctx context.Context, ref dockerRe var parsedBody extensionSignatureList if err := json.Unmarshal(body, &parsedBody); err != nil { - return nil, perrors.Wrapf(err, "decoding signature list") + return nil, fmt.Errorf("decoding signature list: %w", err) } return &parsedBody, nil } diff --git a/docker/docker_image.go b/docker/docker_image.go index dfcff1d6c..3e8dbbee1 100644 --- a/docker/docker_image.go +++ b/docker/docker_image.go @@ -14,7 +14,6 @@ import ( "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/types" "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" ) // Image is a Docker-specific implementation of types.ImageCloser with a few extra methods @@ -67,7 +66,7 @@ func GetRepositoryTags(ctx context.Context, sys *types.SystemContext, ref types. path := fmt.Sprintf(tagsPath, reference.Path(dr.ref)) client, err := newDockerClientFromRef(sys, dr, registryConfig, false, "pull") if err != nil { - return nil, perrors.Wrap(err, "failed to create client") + return nil, fmt.Errorf("failed to create client: %w", err) } tags := make([]string, 0) @@ -135,7 +134,7 @@ func GetDigest(ctx context.Context, sys *types.SystemContext, ref types.ImageRef } client, err := newDockerClientFromRef(sys, dr, registryConfig, false, "pull") if err != nil { - return "", perrors.Wrap(err, "failed to create client") + return "", fmt.Errorf("failed to create client: %w", err) } path := fmt.Sprintf(manifestPath, reference.Path(dr.ref), tagOrDigest) @@ -150,7 +149,7 @@ func GetDigest(ctx context.Context, sys *types.SystemContext, ref types.ImageRef defer res.Body.Close() if res.StatusCode != http.StatusOK { - return "", perrors.Wrapf(registryHTTPResponseToError(res), "reading digest %s in %s", tagOrDigest, dr.ref.Name()) + return "", fmt.Errorf("reading digest %s in %s: %w", tagOrDigest, dr.ref.Name(), registryHTTPResponseToError(res)) } dig, err := digest.Parse(res.Header.Get("Docker-Content-Digest")) diff --git a/docker/docker_image_dest.go b/docker/docker_image_dest.go index 580e8bef4..6cd693b6b 100644 --- a/docker/docker_image_dest.go +++ b/docker/docker_image_dest.go @@ -31,7 +31,6 @@ import ( v2 "github.com/docker/distribution/registry/api/v2" "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -167,11 +166,11 @@ func (d *dockerImageDestination) PutBlobWithOptions(ctx context.Context, stream defer res.Body.Close() if res.StatusCode != http.StatusAccepted { logrus.Debugf("Error initiating layer upload, response %#v", *res) - return types.BlobInfo{}, perrors.Wrapf(registryHTTPResponseToError(res), "initiating layer upload to %s in %s", uploadPath, d.c.registry) + return types.BlobInfo{}, fmt.Errorf("initiating layer upload to %s in %s: %w", uploadPath, d.c.registry, registryHTTPResponseToError(res)) } uploadLocation, err := res.Location() if err != nil { - return types.BlobInfo{}, perrors.Wrap(err, "determining upload URL") + return types.BlobInfo{}, fmt.Errorf("determining upload URL: %w", err) } digester, stream := putblobdigest.DigestIfCanonicalUnknown(stream, inputInfo) @@ -190,11 +189,11 @@ func (d *dockerImageDestination) PutBlobWithOptions(ctx context.Context, stream } defer res.Body.Close() if !successStatus(res.StatusCode) { - return nil, perrors.Wrapf(registryHTTPResponseToError(res), "uploading layer chunked") + return nil, fmt.Errorf("uploading layer chunked: %w", registryHTTPResponseToError(res)) } uploadLocation, err := res.Location() if err != nil { - return nil, perrors.Wrap(err, "determining upload URL") + return nil, fmt.Errorf("determining upload URL: %w", err) } return uploadLocation, nil }() @@ -215,7 +214,7 @@ func (d *dockerImageDestination) PutBlobWithOptions(ctx context.Context, stream defer res.Body.Close() if res.StatusCode != http.StatusCreated { logrus.Debugf("Error uploading layer, response %#v", *res) - return types.BlobInfo{}, perrors.Wrapf(registryHTTPResponseToError(res), "uploading layer to %s", uploadLocation) + return types.BlobInfo{}, fmt.Errorf("uploading layer to %s: %w", uploadLocation, registryHTTPResponseToError(res)) } logrus.Debugf("Upload of layer %s complete", blobDigest) @@ -240,7 +239,7 @@ func (d *dockerImageDestination) blobExists(ctx context.Context, repo reference. return true, getBlobSize(res), nil case http.StatusUnauthorized: logrus.Debugf("... not authorized") - return false, -1, perrors.Wrapf(registryHTTPResponseToError(res), "checking whether a blob %s exists in %s", digest, repo.Name()) + return false, -1, fmt.Errorf("checking whether a blob %s exists in %s: %w", digest, repo.Name(), registryHTTPResponseToError(res)) case http.StatusNotFound: logrus.Debugf("... not present") return false, -1, nil @@ -274,7 +273,7 @@ func (d *dockerImageDestination) mountBlob(ctx context.Context, srcRepo referenc // NOTE: This does not really work in docker/distribution servers, which incorrectly require the "delete" action in the token's scope, and is thus entirely untested. uploadLocation, err := res.Location() if err != nil { - return perrors.Wrap(err, "determining upload URL after a mount attempt") + return fmt.Errorf("determining upload URL after a mount attempt: %w", err) } logrus.Debugf("... started an upload instead of mounting, trying to cancel at %s", uploadLocation.Redacted()) res2, err := d.c.makeRequestToResolvedURL(ctx, http.MethodDelete, uploadLocation, nil, nil, -1, v2Auth, extraScope) @@ -290,7 +289,7 @@ func (d *dockerImageDestination) mountBlob(ctx context.Context, srcRepo referenc return fmt.Errorf("Mounting %s from %s to %s started an upload instead", srcDigest, srcRepo.Name(), d.ref.ref.Name()) default: logrus.Debugf("Error mounting, response %#v", *res) - return perrors.Wrapf(registryHTTPResponseToError(res), "mounting %s from %s to %s", srcDigest, srcRepo.Name(), d.ref.ref.Name()) + return fmt.Errorf("mounting %s from %s to %s: %w", srcDigest, srcRepo.Name(), d.ref.ref.Name(), registryHTTPResponseToError(res)) } } @@ -416,12 +415,12 @@ func (d *dockerImageDestination) PutManifest(ctx context.Context, m []byte, inst // Double-check that the manifest we've been given matches the digest we've been given. matches, err := manifest.MatchesDigest(m, *instanceDigest) if err != nil { - return perrors.Wrapf(err, "digesting manifest in PutManifest") + return fmt.Errorf("digesting manifest in PutManifest: %w", err) } if !matches { manifestDigest, merr := manifest.Digest(m) if merr != nil { - return perrors.Wrapf(err, "Attempted to PutManifest using an explicitly specified digest (%q) that didn't match the manifest's digest (%v attempting to compute it)", instanceDigest.String(), merr) + return fmt.Errorf("Attempted to PutManifest using an explicitly specified digest (%q) that didn't match the manifest's digest: %w", instanceDigest.String(), merr) } return fmt.Errorf("Attempted to PutManifest using an explicitly specified digest (%q) that didn't match the manifest's digest (%q)", instanceDigest.String(), manifestDigest.String()) } @@ -460,7 +459,7 @@ func (d *dockerImageDestination) uploadManifest(ctx context.Context, m []byte, t defer res.Body.Close() if !successStatus(res.StatusCode) { rawErr := registryHTTPResponseToError(res) - err := perrors.Wrapf(rawErr, "uploading manifest %s to %s", tagOrDigest, d.ref.ref.Name()) + err := fmt.Errorf("uploading manifest %s to %s: %w", tagOrDigest, d.ref.ref.Name(), rawErr) if isManifestInvalidError(rawErr) { err = types.ManifestTypeRejectedError{Err: err} } @@ -832,7 +831,7 @@ sigExists: randBytes := make([]byte, 16) n, err := rand.Read(randBytes) if err != nil || n != 16 { - return perrors.Wrapf(err, "generating random signature len %d", n) + return fmt.Errorf("generating random signature len %d: %w", n, err) } signatureName = fmt.Sprintf("%s@%032x", manifestDigest.String(), randBytes) if _, ok := existingSigNames[signatureName]; !ok { @@ -858,7 +857,7 @@ sigExists: defer res.Body.Close() if res.StatusCode != http.StatusCreated { logrus.Debugf("Error uploading signature, status %d, %#v", res.StatusCode, res) - return perrors.Wrapf(registryHTTPResponseToError(res), "uploading signature to %s in %s", path, d.c.registry) + return fmt.Errorf("uploading signature to %s in %s: %w", path, d.c.registry, registryHTTPResponseToError(res)) } } diff --git a/docker/docker_image_src.go b/docker/docker_image_src.go index 929c2078e..b0e877971 100644 --- a/docker/docker_image_src.go +++ b/docker/docker_image_src.go @@ -25,7 +25,6 @@ import ( "github.com/containers/image/v5/pkg/sysregistriesv2" "github.com/containers/image/v5/types" digest "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -52,7 +51,7 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, ref dockerRef } registry, err := sysregistriesv2.FindRegistry(sys, ref.ref.Name()) if err != nil { - return nil, perrors.Wrapf(err, "loading registries configuration") + return nil, fmt.Errorf("loading registries configuration: %w", err) } if registry == nil { // No configuration was found for the provided reference, so use the @@ -109,7 +108,7 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, ref dockerRef // The paired [] at least have some chance of being unambiguous. extras = append(extras, fmt.Sprintf("[%s: %v]", attempts[i].ref.String(), attempts[i].err)) } - return nil, perrors.Wrapf(primary.err, "(Mirrors also failed: %s): %s", strings.Join(extras, "\n"), primary.ref.String()) + return nil, fmt.Errorf("(Mirrors also failed: %s): %s: %w", strings.Join(extras, "\n"), primary.ref.String(), primary.err) } } diff --git a/docker/internal/tarfile/dest.go b/docker/internal/tarfile/dest.go index b36f303a3..9a0ea683e 100644 --- a/docker/internal/tarfile/dest.go +++ b/docker/internal/tarfile/dest.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "errors" + "fmt" "io" "github.com/containers/image/v5/docker/reference" @@ -16,7 +17,6 @@ import ( "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/types" "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -108,11 +108,11 @@ func (d *Destination) PutBlobWithOptions(ctx context.Context, stream io.Reader, if options.IsConfig { buf, err := iolimits.ReadAtMost(stream, iolimits.MaxConfigBodySize) if err != nil { - return types.BlobInfo{}, perrors.Wrap(err, "reading Config file stream") + return types.BlobInfo{}, fmt.Errorf("reading Config file stream: %w", err) } d.config = buf if err := d.archive.sendFileLocked(d.archive.configPath(inputInfo.Digest), inputInfo.Size, bytes.NewReader(buf)); err != nil { - return types.BlobInfo{}, perrors.Wrap(err, "writing Config file") + return types.BlobInfo{}, fmt.Errorf("writing Config file: %w", err) } } else { if err := d.archive.sendFileLocked(d.archive.physicalLayerPath(inputInfo.Digest), inputInfo.Size, stream); err != nil { @@ -153,7 +153,7 @@ func (d *Destination) PutManifest(ctx context.Context, m []byte, instanceDigest // so the caller trying a different manifest kind would be pointless. var man manifest.Schema2 if err := json.Unmarshal(m, &man); err != nil { - return perrors.Wrap(err, "parsing manifest") + return fmt.Errorf("parsing manifest: %w", err) } if man.SchemaVersion != 2 || man.MediaType != manifest.DockerV2Schema2MediaType { return errors.New("Unsupported manifest type, need a Docker schema 2 manifest") diff --git a/docker/internal/tarfile/reader.go b/docker/internal/tarfile/reader.go index 0bced0bcc..eec7b84e5 100644 --- a/docker/internal/tarfile/reader.go +++ b/docker/internal/tarfile/reader.go @@ -14,7 +14,6 @@ import ( "github.com/containers/image/v5/internal/tmpdir" "github.com/containers/image/v5/pkg/compression" "github.com/containers/image/v5/types" - perrors "github.com/pkg/errors" ) // Reader is a ((docker save)-formatted) tar archive that allows random access to any component. @@ -31,7 +30,7 @@ type Reader struct { func NewReaderFromFile(sys *types.SystemContext, path string) (*Reader, error) { file, err := os.Open(path) if err != nil { - return nil, perrors.Wrapf(err, "opening file %q", path) + return nil, fmt.Errorf("opening file %q: %w", path, err) } defer file.Close() @@ -39,7 +38,7 @@ func NewReaderFromFile(sys *types.SystemContext, path string) (*Reader, error) { // as a source. Otherwise we pass the stream to NewReaderFromStream. stream, isCompressed, err := compression.AutoDecompress(file) if err != nil { - return nil, perrors.Wrapf(err, "detecting compression for file %q", path) + return nil, fmt.Errorf("detecting compression for file %q: %w", path, err) } defer stream.Close() if !isCompressed { @@ -56,7 +55,7 @@ func NewReaderFromStream(sys *types.SystemContext, inputStream io.Reader) (*Read // Save inputStream to a temporary file tarCopyFile, err := os.CreateTemp(tmpdir.TemporaryDirectoryForBigFiles(sys), "docker-tar") if err != nil { - return nil, perrors.Wrap(err, "creating temporary file") + return nil, fmt.Errorf("creating temporary file: %w", err) } defer tarCopyFile.Close() @@ -72,7 +71,7 @@ func NewReaderFromStream(sys *types.SystemContext, inputStream io.Reader) (*Read // giving users really confusing "invalid tar header" errors). uncompressedStream, _, err := compression.AutoDecompress(inputStream) if err != nil { - return nil, perrors.Wrap(err, "auto-decompressing input") + return nil, fmt.Errorf("auto-decompressing input: %w", err) } defer uncompressedStream.Close() @@ -81,7 +80,7 @@ func NewReaderFromStream(sys *types.SystemContext, inputStream io.Reader) (*Read // TODO: This can take quite some time, and should ideally be cancellable // using a context.Context. if _, err := io.Copy(tarCopyFile, uncompressedStream); err != nil { - return nil, perrors.Wrapf(err, "copying contents to temporary file %q", tarCopyFile.Name()) + return nil, fmt.Errorf("copying contents to temporary file %q: %w", tarCopyFile.Name(), err) } succeeded = true @@ -114,7 +113,7 @@ func newReader(path string, removeOnClose bool) (*Reader, error) { return nil, err } if err := json.Unmarshal(bytes, &r.Manifest); err != nil { - return nil, perrors.Wrap(err, "decoding tar manifest.json") + return nil, fmt.Errorf("decoding tar manifest.json: %w", err) } succeeded = true @@ -147,7 +146,7 @@ func (r *Reader) ChooseManifestItem(ref reference.NamedTagged, sourceIndex int) for tagIndex, tag := range r.Manifest[i].RepoTags { parsedTag, err := reference.ParseNormalizedNamed(tag) if err != nil { - return nil, -1, perrors.Wrapf(err, "Invalid tag %#v in manifest.json item @%d", tag, i) + return nil, -1, fmt.Errorf("Invalid tag %#v in manifest.json item @%d: %w", tag, i, err) } if parsedTag.String() == refString { return &r.Manifest[i], tagIndex, nil @@ -259,7 +258,7 @@ func findTarComponent(inputFile io.Reader, componentPath string) (*tar.Reader, * func (r *Reader) readTarComponent(path string, limit int) ([]byte, error) { file, err := r.openTarComponent(path) if err != nil { - return nil, perrors.Wrapf(err, "loading tar component %s", path) + return nil, fmt.Errorf("loading tar component %s: %w", path, err) } defer file.Close() bytes, err := iolimits.ReadAtMost(file, limit) diff --git a/docker/internal/tarfile/src.go b/docker/internal/tarfile/src.go index 8230d88c6..b63b5316e 100644 --- a/docker/internal/tarfile/src.go +++ b/docker/internal/tarfile/src.go @@ -20,7 +20,6 @@ import ( "github.com/containers/image/v5/pkg/compression" "github.com/containers/image/v5/types" digest "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" ) // Source is a partial implementation of types.ImageSource for reading from tarPath. @@ -96,7 +95,7 @@ func (s *Source) ensureCachedDataIsPresentPrivate() error { } var parsedConfig manifest.Schema2Image // There's a lot of info there, but we only really care about layer DiffIDs. if err := json.Unmarshal(configBytes, &parsedConfig); err != nil { - return perrors.Wrapf(err, "decoding tar config %s", tarManifest.Config) + return fmt.Errorf("decoding tar config %s: %w", tarManifest.Config, err) } if parsedConfig.RootFS == nil { return fmt.Errorf("Invalid image config (rootFS is not set): %s", tarManifest.Config) @@ -180,7 +179,7 @@ func (s *Source) prepareLayerData(tarManifest *ManifestItem, parsedConfig *manif // the slower method of checking if it's compressed. uncompressedStream, isCompressed, err := compression.AutoDecompress(t) if err != nil { - return nil, perrors.Wrapf(err, "auto-decompressing %s to determine its size", layerPath) + return nil, fmt.Errorf("auto-decompressing %s to determine its size: %w", layerPath, err) } defer uncompressedStream.Close() @@ -188,7 +187,7 @@ func (s *Source) prepareLayerData(tarManifest *ManifestItem, parsedConfig *manif if isCompressed { uncompressedSize, err = io.Copy(io.Discard, uncompressedStream) if err != nil { - return nil, perrors.Wrapf(err, "reading %s to find its size", layerPath) + return nil, fmt.Errorf("reading %s to find its size: %w", layerPath, err) } } li.size = uncompressedSize @@ -303,7 +302,7 @@ func (s *Source) GetBlob(ctx context.Context, info types.BlobInfo, cache types.B uncompressedStream, _, err := compression.AutoDecompress(underlyingStream) if err != nil { - return nil, 0, perrors.Wrapf(err, "auto-decompressing blob %s", info.Digest) + return nil, 0, fmt.Errorf("auto-decompressing blob %s: %w", info.Digest, err) } newStream := uncompressedReadCloser{ diff --git a/docker/internal/tarfile/writer.go b/docker/internal/tarfile/writer.go index 64743b58e..f6ee041c4 100644 --- a/docker/internal/tarfile/writer.go +++ b/docker/internal/tarfile/writer.go @@ -16,7 +16,6 @@ import ( "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/types" "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -95,16 +94,16 @@ func (w *Writer) ensureSingleLegacyLayerLocked(layerID string, layerDigest diges // See also the comment in physicalLayerPath. physicalLayerPath := w.physicalLayerPath(layerDigest) if err := w.sendSymlinkLocked(filepath.Join(layerID, legacyLayerFileName), filepath.Join("..", physicalLayerPath)); err != nil { - return perrors.Wrap(err, "creating layer symbolic link") + return fmt.Errorf("creating layer symbolic link: %w", err) } b := []byte("1.0") if err := w.sendBytesLocked(filepath.Join(layerID, legacyVersionFileName), b); err != nil { - return perrors.Wrap(err, "writing VERSION file") + return fmt.Errorf("writing VERSION file: %w", err) } if err := w.sendBytesLocked(filepath.Join(layerID, legacyConfigFileName), configBytes); err != nil { - return perrors.Wrap(err, "writing config json file") + return fmt.Errorf("writing config json file: %w", err) } w.legacyLayers[layerID] = struct{}{} @@ -129,7 +128,7 @@ func (w *Writer) writeLegacyMetadataLocked(layerDescriptors []manifest.Schema2De var config map[string]*json.RawMessage err := json.Unmarshal(configBytes, &config) if err != nil { - return perrors.Wrap(err, "unmarshaling config") + return fmt.Errorf("unmarshaling config: %w", err) } for _, attr := range [7]string{"architecture", "config", "container", "container_config", "created", "docker_version", "os"} { layerConfig[attr] = config[attr] @@ -153,7 +152,7 @@ func (w *Writer) writeLegacyMetadataLocked(layerDescriptors []manifest.Schema2De layerConfig["layer_id"] = chainID b, err := json.Marshal(layerConfig) // Note that layerConfig["id"] is not set yet at this point. if err != nil { - return perrors.Wrap(err, "marshaling layer config") + return fmt.Errorf("marshaling layer config: %w", err) } delete(layerConfig, "layer_id") layerID := digest.Canonical.FromBytes(b).Hex() @@ -161,7 +160,7 @@ func (w *Writer) writeLegacyMetadataLocked(layerDescriptors []manifest.Schema2De configBytes, err := json.Marshal(layerConfig) if err != nil { - return perrors.Wrap(err, "marshaling layer config") + return fmt.Errorf("marshaling layer config: %w", err) } if err := w.ensureSingleLegacyLayerLocked(layerID, l.Digest, configBytes); err != nil { @@ -281,10 +280,10 @@ func (w *Writer) Close() error { b, err = json.Marshal(w.repositories) if err != nil { - return perrors.Wrap(err, "marshaling repositories") + return fmt.Errorf("marshaling repositories: %w", err) } if err := w.sendBytesLocked(legacyRepositoriesFileName, b); err != nil { - return perrors.Wrap(err, "writing config json file") + return fmt.Errorf("writing config json file: %w", err) } if err := w.tar.Close(); err != nil { diff --git a/docker/registries_d.go b/docker/registries_d.go index f4163cc61..37087dd85 100644 --- a/docker/registries_d.go +++ b/docker/registries_d.go @@ -15,7 +15,6 @@ import ( "github.com/containers/storage/pkg/homedir" "github.com/ghodss/yaml" "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -135,7 +134,7 @@ func loadAndMergeConfig(dirPath string) (*registryConfiguration, error) { var config registryConfiguration err = yaml.Unmarshal(configBytes, &config) if err != nil { - return nil, perrors.Wrapf(err, "parsing %s", configPath) + return nil, fmt.Errorf("parsing %s: %w", configPath, err) } if config.DefaultDocker != nil { @@ -168,7 +167,7 @@ func (config *registryConfiguration) lookasideStorageBaseURL(dr dockerReference, if topLevel != "" { u, err := url.Parse(topLevel) if err != nil { - return nil, perrors.Wrapf(err, "Invalid signature storage URL %s", topLevel) + return nil, fmt.Errorf("Invalid signature storage URL %s: %w", topLevel, err) } url = u } else { diff --git a/go.mod b/go.mod index 65bca9199..061ba4dfa 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,6 @@ require ( github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198 github.com/opencontainers/selinux v1.10.1 github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f - github.com/pkg/errors v0.9.1 github.com/proglottis/gpgme v0.1.3 github.com/sigstore/sigstore v1.3.1-0.20220629021053-b95fc0d626c1 github.com/sirupsen/logrus v1.8.1 @@ -75,6 +74,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/opencontainers/runc v1.1.2 // indirect github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.12.1 // indirect github.com/prometheus/client_model v0.2.0 // indirect diff --git a/internal/image/docker_list.go b/internal/image/docker_list.go index 4a711440c..8afc40628 100644 --- a/internal/image/docker_list.go +++ b/internal/image/docker_list.go @@ -6,26 +6,25 @@ import ( "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/types" - perrors "github.com/pkg/errors" ) func manifestSchema2FromManifestList(ctx context.Context, sys *types.SystemContext, src types.ImageSource, manblob []byte) (genericManifest, error) { list, err := manifest.Schema2ListFromManifest(manblob) if err != nil { - return nil, perrors.Wrapf(err, "parsing schema2 manifest list") + return nil, fmt.Errorf("parsing schema2 manifest list: %w", err) } targetManifestDigest, err := list.ChooseInstance(sys) if err != nil { - return nil, perrors.Wrapf(err, "choosing image instance") + return nil, fmt.Errorf("choosing image instance: %w", err) } manblob, mt, err := src.GetManifest(ctx, &targetManifestDigest) if err != nil { - return nil, perrors.Wrapf(err, "fetching target platform image selected from manifest list") + return nil, fmt.Errorf("fetching target platform image selected from manifest list: %w", err) } matches, err := manifest.MatchesDigest(manblob, targetManifestDigest) if err != nil { - return nil, perrors.Wrap(err, "computing manifest digest") + return nil, fmt.Errorf("computing manifest digest: %w", err) } if !matches { return nil, fmt.Errorf("Image manifest does not match selected manifest digest %s", targetManifestDigest) diff --git a/internal/image/docker_schema2.go b/internal/image/docker_schema2.go index 68c5c79b9..23a21999a 100644 --- a/internal/image/docker_schema2.go +++ b/internal/image/docker_schema2.go @@ -17,7 +17,6 @@ import ( "github.com/containers/image/v5/types" "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -294,7 +293,7 @@ func (m *manifestSchema2) convertToManifestSchema1(ctx context.Context, options // and anyway this blob is so small that it’s easier to just copy it than to worry about figuring out another location where to get it. info, err := dest.PutBlob(ctx, bytes.NewReader(GzippedEmptyLayer), emptyLayerBlobInfo, none.NoCache, false) if err != nil { - return nil, perrors.Wrap(err, "uploading empty layer") + return nil, fmt.Errorf("uploading empty layer: %w", err) } if info.Digest != emptyLayerBlobInfo.Digest { return nil, fmt.Errorf("Internal error: Uploaded empty layer has digest %#v instead of %s", info.Digest, emptyLayerBlobInfo.Digest) diff --git a/internal/image/oci_index.go b/internal/image/oci_index.go index 12a80dc94..f4f76622c 100644 --- a/internal/image/oci_index.go +++ b/internal/image/oci_index.go @@ -6,26 +6,25 @@ import ( "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/types" - perrors "github.com/pkg/errors" ) func manifestOCI1FromImageIndex(ctx context.Context, sys *types.SystemContext, src types.ImageSource, manblob []byte) (genericManifest, error) { index, err := manifest.OCI1IndexFromManifest(manblob) if err != nil { - return nil, perrors.Wrapf(err, "parsing OCI1 index") + return nil, fmt.Errorf("parsing OCI1 index: %w", err) } targetManifestDigest, err := index.ChooseInstance(sys) if err != nil { - return nil, perrors.Wrapf(err, "choosing image instance") + return nil, fmt.Errorf("choosing image instance: %w", err) } manblob, mt, err := src.GetManifest(ctx, &targetManifestDigest) if err != nil { - return nil, perrors.Wrapf(err, "fetching target platform image selected from image index") + return nil, fmt.Errorf("fetching target platform image selected from image index: %w", err) } matches, err := manifest.MatchesDigest(manblob, targetManifestDigest) if err != nil { - return nil, perrors.Wrap(err, "computing manifest digest") + return nil, fmt.Errorf("computing manifest digest: %w", err) } if !matches { return nil, fmt.Errorf("Image manifest does not match selected manifest digest %s", targetManifestDigest) diff --git a/internal/image/unparsed.go b/internal/image/unparsed.go index 25d49f5e4..0f026501c 100644 --- a/internal/image/unparsed.go +++ b/internal/image/unparsed.go @@ -11,7 +11,6 @@ import ( "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/types" "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" ) // UnparsedImage implements types.UnparsedImage . @@ -61,7 +60,7 @@ func (i *UnparsedImage) Manifest(ctx context.Context) ([]byte, string, error) { if digest, haveDigest := i.expectedManifestDigest(); haveDigest { matches, err := manifest.MatchesDigest(m, digest) if err != nil { - return nil, "", perrors.Wrap(err, "computing manifest digest") + return nil, "", fmt.Errorf("computing manifest digest: %w", err) } if !matches { return nil, "", fmt.Errorf("Manifest does not match provided manifest digest %s", digest) diff --git a/manifest/docker_schema1.go b/manifest/docker_schema1.go index 8aa146c1e..e1f1fb9d9 100644 --- a/manifest/docker_schema1.go +++ b/manifest/docker_schema1.go @@ -12,7 +12,6 @@ import ( "github.com/containers/image/v5/types" "github.com/docker/docker/api/types/versions" "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" ) // Schema1FSLayers is an entry of the "fsLayers" array in docker/distribution schema 1. @@ -115,7 +114,7 @@ func (m *Schema1) initialize() error { m.ExtractedV1Compatibility = make([]Schema1V1Compatibility, len(m.History)) for i, h := range m.History { if err := json.Unmarshal([]byte(h.V1Compatibility), &m.ExtractedV1Compatibility[i]); err != nil { - return perrors.Wrapf(err, "parsing v2s1 history entry %d", i) + return fmt.Errorf("parsing v2s1 history entry %d: %w", i, err) } } return nil @@ -248,14 +247,14 @@ func (m *Schema1) ToSchema2Config(diffIDs []digest.Digest) ([]byte, error) { config := []byte(m.History[0].V1Compatibility) err := json.Unmarshal(config, &s1) if err != nil { - return nil, perrors.Wrapf(err, "decoding configuration") + return nil, fmt.Errorf("decoding configuration: %w", err) } // Images created with versions prior to 1.8.3 require us to re-encode the encoded object, // adding some fields that aren't "omitempty". if s1.DockerVersion != "" && versions.LessThan(s1.DockerVersion, "1.8.3") { config, err = json.Marshal(&s1) if err != nil { - return nil, perrors.Wrapf(err, "re-encoding compat image config %#v", s1) + return nil, fmt.Errorf("re-encoding compat image config %#v: %w", s1, err) } } // Build the history. @@ -282,7 +281,7 @@ func (m *Schema1) ToSchema2Config(diffIDs []digest.Digest) ([]byte, error) { raw := make(map[string]*json.RawMessage) err = json.Unmarshal(config, &raw) if err != nil { - return nil, perrors.Wrapf(err, "re-decoding compat image config %#v", s1) + return nil, fmt.Errorf("re-decoding compat image config %#v: %w", s1, err) } // Drop some fields. delete(raw, "id") diff --git a/manifest/docker_schema2.go b/manifest/docker_schema2.go index 3fe943f83..e79d0851f 100644 --- a/manifest/docker_schema2.go +++ b/manifest/docker_schema2.go @@ -9,7 +9,6 @@ import ( "github.com/containers/image/v5/pkg/strslice" "github.com/containers/image/v5/types" "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" ) // Schema2Descriptor is a “descriptor” in docker/distribution schema 2. @@ -246,7 +245,7 @@ func (m *Schema2) UpdateLayerInfos(layerInfos []types.BlobInfo) error { } mimeType, err := updatedMIMEType(schema2CompressionMIMETypeSets, mimeType, info) if err != nil { - return perrors.Wrapf(err, "preparing updated manifest, layer %q", info.Digest) + return fmt.Errorf("preparing updated manifest, layer %q: %w", info.Digest, err) } m.LayersDescriptors[i].MediaType = mimeType m.LayersDescriptors[i].Digest = info.Digest diff --git a/manifest/docker_schema2_list.go b/manifest/docker_schema2_list.go index 2bf383d8a..7e4cc5183 100644 --- a/manifest/docker_schema2_list.go +++ b/manifest/docker_schema2_list.go @@ -8,7 +8,6 @@ import ( "github.com/containers/image/v5/types" "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" - perrors "github.com/pkg/errors" ) // Schema2PlatformSpec describes the platform which a particular manifest is @@ -71,7 +70,7 @@ func (list *Schema2List) UpdateInstances(updates []ListUpdate) error { } for i := range updates { if err := updates[i].Digest.Validate(); err != nil { - return perrors.Wrapf(err, "update %d of %d passed to Schema2List.UpdateInstances contained an invalid digest", i+1, len(updates)) + return fmt.Errorf("update %d of %d passed to Schema2List.UpdateInstances contained an invalid digest: %w", i+1, len(updates), err) } list.Manifests[i].Digest = updates[i].Digest if updates[i].Size < 0 { @@ -91,7 +90,7 @@ func (list *Schema2List) UpdateInstances(updates []ListUpdate) error { func (list *Schema2List) ChooseInstance(ctx *types.SystemContext) (digest.Digest, error) { wantedPlatforms, err := platform.WantedPlatforms(ctx) if err != nil { - return "", perrors.Wrapf(err, "getting platform information %#v", ctx) + return "", fmt.Errorf("getting platform information %#v: %w", ctx, err) } for _, wantedPlatform := range wantedPlatforms { for _, d := range list.Manifests { @@ -115,7 +114,7 @@ func (list *Schema2List) ChooseInstance(ctx *types.SystemContext) (digest.Digest func (list *Schema2List) Serialize() ([]byte, error) { buf, err := json.Marshal(list) if err != nil { - return nil, perrors.Wrapf(err, "marshaling Schema2List %#v", list) + return nil, fmt.Errorf("marshaling Schema2List %#v: %w", list, err) } return buf, nil } @@ -190,7 +189,7 @@ func Schema2ListFromManifest(manifest []byte) (*Schema2List, error) { Manifests: []Schema2ManifestDescriptor{}, } if err := json.Unmarshal(manifest, &list); err != nil { - return nil, perrors.Wrapf(err, "unmarshaling Schema2List %q", string(manifest)) + return nil, fmt.Errorf("unmarshaling Schema2List %q: %w", string(manifest), err) } if err := validateUnambiguousManifestFormat(manifest, DockerV2ListMediaType, allowedFieldManifests); err != nil { diff --git a/manifest/oci.go b/manifest/oci.go index 6ab78ffec..fc325009c 100644 --- a/manifest/oci.go +++ b/manifest/oci.go @@ -12,7 +12,6 @@ import ( "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/specs-go" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" - perrors "github.com/pkg/errors" ) // BlobInfoFromOCI1Descriptor returns a types.BlobInfo based on the input OCI1 descriptor. @@ -139,7 +138,7 @@ func (m *OCI1) UpdateLayerInfos(layerInfos []types.BlobInfo) error { } mimeType, err := updatedMIMEType(oci1CompressionMIMETypeSets, mimeType, info) if err != nil { - return perrors.Wrapf(err, "preparing updated manifest, layer %q", info.Digest) + return fmt.Errorf("preparing updated manifest, layer %q: %w", info.Digest, err) } if info.CryptoOperation == types.Encrypt { encMediaType, err := getEncryptedMediaType(mimeType) diff --git a/manifest/oci_index.go b/manifest/oci_index.go index 7d55dbf1a..726207b9d 100644 --- a/manifest/oci_index.go +++ b/manifest/oci_index.go @@ -10,7 +10,6 @@ import ( "github.com/opencontainers/go-digest" imgspec "github.com/opencontainers/image-spec/specs-go" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" - perrors "github.com/pkg/errors" ) // OCI1Index is just an alias for the OCI index type, but one which we can @@ -55,7 +54,7 @@ func (index *OCI1Index) UpdateInstances(updates []ListUpdate) error { } for i := range updates { if err := updates[i].Digest.Validate(); err != nil { - return perrors.Wrapf(err, "update %d of %d passed to OCI1Index.UpdateInstances contained an invalid digest", i+1, len(updates)) + return fmt.Errorf("update %d of %d passed to OCI1Index.UpdateInstances contained an invalid digest: %w", i+1, len(updates), err) } index.Manifests[i].Digest = updates[i].Digest if updates[i].Size < 0 { @@ -75,7 +74,7 @@ func (index *OCI1Index) UpdateInstances(updates []ListUpdate) error { func (index *OCI1Index) ChooseInstance(ctx *types.SystemContext) (digest.Digest, error) { wantedPlatforms, err := platform.WantedPlatforms(ctx) if err != nil { - return "", perrors.Wrapf(err, "getting platform information %#v", ctx) + return "", fmt.Errorf("getting platform information %#v: %w", ctx, err) } for _, wantedPlatform := range wantedPlatforms { for _, d := range index.Manifests { @@ -108,7 +107,7 @@ func (index *OCI1Index) ChooseInstance(ctx *types.SystemContext) (digest.Digest, func (index *OCI1Index) Serialize() ([]byte, error) { buf, err := json.Marshal(index) if err != nil { - return nil, perrors.Wrapf(err, "marshaling OCI1Index %#v", index) + return nil, fmt.Errorf("marshaling OCI1Index %#v: %w", index, err) } return buf, nil } @@ -202,7 +201,7 @@ func OCI1IndexFromManifest(manifest []byte) (*OCI1Index, error) { }, } if err := json.Unmarshal(manifest, &index); err != nil { - return nil, perrors.Wrapf(err, "unmarshaling OCI1Index %q", string(manifest)) + return nil, fmt.Errorf("unmarshaling OCI1Index %q: %w", string(manifest), err) } if err := validateUnambiguousManifestFormat(manifest, imgspecv1.MediaTypeImageIndex, allowedFieldManifests); err != nil { diff --git a/oci/archive/oci_dest.go b/oci/archive/oci_dest.go index 23b89e8e2..f710be10b 100644 --- a/oci/archive/oci_dest.go +++ b/oci/archive/oci_dest.go @@ -2,6 +2,7 @@ package archive import ( "context" + "fmt" "io" "os" @@ -13,7 +14,6 @@ import ( "github.com/containers/image/v5/types" "github.com/containers/storage/pkg/archive" digest "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -29,12 +29,12 @@ type ociArchiveImageDestination struct { func newImageDestination(ctx context.Context, sys *types.SystemContext, ref ociArchiveReference) (private.ImageDestination, error) { tempDirRef, err := createOCIRef(sys, ref.image) if err != nil { - return nil, perrors.Wrapf(err, "creating oci reference") + return nil, fmt.Errorf("creating oci reference: %w", err) } unpackedDest, err := tempDirRef.ociRefExtracted.NewImageDestination(ctx, sys) if err != nil { if err := tempDirRef.deleteTempDir(); err != nil { - return nil, perrors.Wrapf(err, "deleting temp directory %q", tempDirRef.tempDirectory) + return nil, fmt.Errorf("deleting temp directory %q: %w", tempDirRef.tempDirectory, err) } return nil, err } @@ -158,7 +158,7 @@ func (d *ociArchiveImageDestination) PutSignaturesWithFormat(ctx context.Context // after the directory is made, it is tarred up into a file and the directory is deleted func (d *ociArchiveImageDestination) Commit(ctx context.Context, unparsedToplevel types.UnparsedImage) error { if err := d.unpackedDest.Commit(ctx, unparsedToplevel); err != nil { - return perrors.Wrapf(err, "storing image %q", d.ref.image) + return fmt.Errorf("storing image %q: %w", d.ref.image, err) } // path of directory to tar up @@ -173,13 +173,13 @@ func tarDirectory(src, dst string) error { // input is a stream of bytes from the archive of the directory at path input, err := archive.Tar(src, archive.Uncompressed) if err != nil { - return perrors.Wrapf(err, "retrieving stream of bytes from %q", src) + return fmt.Errorf("retrieving stream of bytes from %q: %w", src, err) } // creates the tar file outFile, err := os.Create(dst) if err != nil { - return perrors.Wrapf(err, "creating tar file %q", dst) + return fmt.Errorf("creating tar file %q: %w", dst, err) } defer outFile.Close() diff --git a/oci/archive/oci_src.go b/oci/archive/oci_src.go index b24fc77b2..e5ad2570e 100644 --- a/oci/archive/oci_src.go +++ b/oci/archive/oci_src.go @@ -3,6 +3,7 @@ package archive import ( "context" "errors" + "fmt" "io" "github.com/containers/image/v5/internal/imagesource" @@ -13,7 +14,6 @@ import ( "github.com/containers/image/v5/types" digest "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -30,13 +30,13 @@ type ociArchiveImageSource struct { func newImageSource(ctx context.Context, sys *types.SystemContext, ref ociArchiveReference) (private.ImageSource, error) { tempDirRef, err := createUntarTempDir(sys, ref) if err != nil { - return nil, perrors.Wrap(err, "creating temp directory") + return nil, fmt.Errorf("creating temp directory: %w", err) } unpackedSrc, err := tempDirRef.ociRefExtracted.NewImageSource(ctx, sys) if err != nil { if err := tempDirRef.deleteTempDir(); err != nil { - return nil, perrors.Wrapf(err, "deleting temp directory %q", tempDirRef.tempDirectory) + return nil, fmt.Errorf("deleting temp directory %q: %w", tempDirRef.tempDirectory, err) } return nil, err } @@ -63,7 +63,7 @@ func LoadManifestDescriptorWithContext(sys *types.SystemContext, imgRef types.Im } tempDirRef, err := createUntarTempDir(sys, ociArchRef) if err != nil { - return imgspecv1.Descriptor{}, perrors.Wrap(err, "creating temp directory") + return imgspecv1.Descriptor{}, fmt.Errorf("creating temp directory: %w", err) } defer func() { err := tempDirRef.deleteTempDir() @@ -72,7 +72,7 @@ func LoadManifestDescriptorWithContext(sys *types.SystemContext, imgRef types.Im descriptor, err := ocilayout.LoadManifestDescriptor(tempDirRef.ociRefExtracted) if err != nil { - return imgspecv1.Descriptor{}, perrors.Wrap(err, "loading index") + return imgspecv1.Descriptor{}, fmt.Errorf("loading index: %w", err) } return descriptor, nil } diff --git a/oci/archive/oci_transport.go b/oci/archive/oci_transport.go index e450815ec..53371796f 100644 --- a/oci/archive/oci_transport.go +++ b/oci/archive/oci_transport.go @@ -16,7 +16,6 @@ import ( "github.com/containers/image/v5/transports" "github.com/containers/image/v5/types" "github.com/containers/storage/pkg/archive" - perrors "github.com/pkg/errors" ) func init() { @@ -159,7 +158,7 @@ func (t *tempDirOCIRef) deleteTempDir() error { func createOCIRef(sys *types.SystemContext, image string) (tempDirOCIRef, error) { dir, err := os.MkdirTemp(tmpdir.TemporaryDirectoryForBigFiles(sys), "oci") if err != nil { - return tempDirOCIRef{}, perrors.Wrapf(err, "creating temp directory") + return tempDirOCIRef{}, fmt.Errorf("creating temp directory: %w", err) } ociRef, err := ocilayout.NewReference(dir, image) if err != nil { @@ -174,7 +173,7 @@ func createOCIRef(sys *types.SystemContext, image string) (tempDirOCIRef, error) func createUntarTempDir(sys *types.SystemContext, ref ociArchiveReference) (tempDirOCIRef, error) { tempDirRef, err := createOCIRef(sys, ref.image) if err != nil { - return tempDirOCIRef{}, perrors.Wrap(err, "creating oci reference") + return tempDirOCIRef{}, fmt.Errorf("creating oci reference: %w", err) } src := ref.resolvedFile dst := tempDirRef.tempDirectory @@ -186,9 +185,9 @@ func createUntarTempDir(sys *types.SystemContext, ref ociArchiveReference) (temp defer arch.Close() if err := archive.NewDefaultArchiver().Untar(arch, dst, &archive.TarOptions{NoLchown: true}); err != nil { if err := tempDirRef.deleteTempDir(); err != nil { - return tempDirOCIRef{}, perrors.Wrapf(err, "deleting temp directory %q", tempDirRef.tempDirectory) + return tempDirOCIRef{}, fmt.Errorf("deleting temp directory %q: %w", tempDirRef.tempDirectory, err) } - return tempDirOCIRef{}, perrors.Wrapf(err, "untarring file %q", tempDirRef.tempDirectory) + return tempDirOCIRef{}, fmt.Errorf("untarring file %q: %w", tempDirRef.tempDirectory, err) } return tempDirRef, nil } diff --git a/oci/layout/oci_src.go b/oci/layout/oci_src.go index 9641ad024..b2d963b01 100644 --- a/oci/layout/oci_src.go +++ b/oci/layout/oci_src.go @@ -3,6 +3,7 @@ package layout import ( "context" "errors" + "fmt" "io" "net/http" "net/url" @@ -18,7 +19,6 @@ import ( "github.com/docker/go-connections/tlsconfig" "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" - perrors "github.com/pkg/errors" ) type ociImageSource struct { @@ -170,19 +170,19 @@ func (s *ociImageSource) getExternalBlob(ctx context.Context, urls []string) (io hasSupportedURL = true req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil) if err != nil { - errWrap = perrors.Wrapf(errWrap, "fetching %s failed %s", u, err.Error()) + errWrap = fmt.Errorf("fetching %s failed %s: %w", u, err.Error(), errWrap) continue } resp, err := s.client.Do(req) if err != nil { - errWrap = perrors.Wrapf(errWrap, "fetching %s failed %s", u, err.Error()) + errWrap = fmt.Errorf("fetching %s failed %s: %w", u, err.Error(), errWrap) continue } if resp.StatusCode != http.StatusOK { resp.Body.Close() - errWrap = perrors.Wrapf(errWrap, "fetching %s failed, response code not 200", u) + errWrap = fmt.Errorf("fetching %s failed, response code not 200: %w", u, errWrap) continue } diff --git a/oci/layout/oci_transport.go b/oci/layout/oci_transport.go index 96974eac6..be22bed6d 100644 --- a/oci/layout/oci_transport.go +++ b/oci/layout/oci_transport.go @@ -17,7 +17,6 @@ import ( "github.com/containers/image/v5/types" "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" - perrors "github.com/pkg/errors" ) func init() { @@ -251,7 +250,7 @@ func (ref ociReference) indexPath() string { // blobPath returns a path for a blob within a directory using OCI image-layout conventions. func (ref ociReference) blobPath(digest digest.Digest, sharedBlobDir string) (string, error) { if err := digest.Validate(); err != nil { - return "", perrors.Wrapf(err, "unexpected digest reference %s", digest) + return "", fmt.Errorf("unexpected digest reference %s: %w", digest, err) } blobDir := filepath.Join(ref.dir, "blobs") if sharedBlobDir != "" { diff --git a/openshift/openshift-copies.go b/openshift/openshift-copies.go index 459c3e4d4..8df1bfc8b 100644 --- a/openshift/openshift-copies.go +++ b/openshift/openshift-copies.go @@ -19,7 +19,6 @@ import ( "github.com/containers/storage/pkg/homedir" "github.com/ghodss/yaml" "github.com/imdario/mergo" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/net/http2" ) @@ -579,7 +578,7 @@ func (rules *clientConfigLoadingRules) Load() (*clientcmdConfig, error) { continue } if err != nil { - errlist = append(errlist, perrors.Wrapf(err, "loading config file \"%s\"", filename)) + errlist = append(errlist, fmt.Errorf("loading config file \"%s\": %w", filename, err)) continue } @@ -692,7 +691,7 @@ func resolveLocalPaths(config *clientcmdConfig) error { } base, err := filepath.Abs(filepath.Dir(cluster.LocationOfOrigin)) if err != nil { - return perrors.Wrapf(err, "Could not determine the absolute path of config file %s", cluster.LocationOfOrigin) + return fmt.Errorf("Could not determine the absolute path of config file %s: %w", cluster.LocationOfOrigin, err) } if err := resolvePaths(getClusterFileReferences(cluster), base); err != nil { @@ -705,7 +704,7 @@ func resolveLocalPaths(config *clientcmdConfig) error { } base, err := filepath.Abs(filepath.Dir(authInfo.LocationOfOrigin)) if err != nil { - return perrors.Wrapf(err, "Could not determine the absolute path of config file %s", authInfo.LocationOfOrigin) + return fmt.Errorf("Could not determine the absolute path of config file %s: %w", authInfo.LocationOfOrigin, err) } if err := resolvePaths(getAuthInfoFileReferences(authInfo), base); err != nil { diff --git a/openshift/openshift_dest.go b/openshift/openshift_dest.go index 58f0eac70..d5dbaf27e 100644 --- a/openshift/openshift_dest.go +++ b/openshift/openshift_dest.go @@ -21,7 +21,6 @@ import ( "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/types" "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" ) type openshiftImageDestination struct { @@ -206,7 +205,7 @@ sigExists: randBytes := make([]byte, 16) n, err := rand.Read(randBytes) if err != nil || n != 16 { - return perrors.Wrapf(err, "generating random signature len %d", n) + return fmt.Errorf("generating random signature len %d: %w", n, err) } signatureName = fmt.Sprintf("%s@%032x", imageStreamImageName, randBytes) if _, ok := existingSigNames[signatureName]; !ok { diff --git a/openshift/openshift_transport.go b/openshift/openshift_transport.go index b23c4ae32..f7971a48f 100644 --- a/openshift/openshift_transport.go +++ b/openshift/openshift_transport.go @@ -12,7 +12,6 @@ import ( genericImage "github.com/containers/image/v5/internal/image" "github.com/containers/image/v5/transports" "github.com/containers/image/v5/types" - perrors "github.com/pkg/errors" ) func init() { @@ -60,7 +59,7 @@ type openshiftReference struct { func ParseReference(ref string) (types.ImageReference, error) { r, err := reference.ParseNormalizedNamed(ref) if err != nil { - return nil, perrors.Wrapf(err, "failed to parse image reference %q", ref) + return nil, fmt.Errorf("failed to parse image reference %q: %w", ref, err) } tagged, ok := r.(reference.NamedTagged) if !ok { diff --git a/ostree/ostree_dest.go b/ostree/ostree_dest.go index 98275da60..929523fa6 100644 --- a/ostree/ostree_dest.go +++ b/ostree/ostree_dest.go @@ -33,7 +33,6 @@ import ( "github.com/opencontainers/go-digest" selinux "github.com/opencontainers/selinux/go-selinux" "github.com/ostreedev/ostree-go/pkg/otbuiltin" - perrors "github.com/pkg/errors" "github.com/vbatts/tar-split/tar/asm" "github.com/vbatts/tar-split/tar/storage" ) @@ -203,7 +202,7 @@ func fixFiles(selinuxHnd *C.struct_selabel_handle, root string, dir string, user res, err := C.selabel_lookup_raw(selinuxHnd, &context, relPathC, C.int(info.Mode()&os.ModePerm)) if int(res) < 0 && err != syscall.ENOENT { - return perrors.Wrapf(err, "cannot selabel_lookup_raw %s", relPath) + return fmt.Errorf("cannot selabel_lookup_raw %s: %w", relPath, err) } if int(res) == 0 { defer C.freecon(context) @@ -211,7 +210,7 @@ func fixFiles(selinuxHnd *C.struct_selabel_handle, root string, dir string, user defer C.free(unsafe.Pointer(fullpathC)) res, err = C.lsetfilecon_raw(fullpathC, context) if int(res) < 0 { - return perrors.Wrapf(err, "cannot setfilecon_raw %s to %s", fullpath, C.GoString(context)) + return fmt.Errorf("cannot setfilecon_raw %s to %s: %w", fullpath, C.GoString(context), err) } } } @@ -446,7 +445,7 @@ func (d *ostreeImageDestination) Commit(context.Context, types.UnparsedImage) er if os.Getuid() == 0 && selinux.GetEnabled() { selinuxHnd, err = C.selabel_open(C.SELABEL_CTX_FILE, nil, 0) if selinuxHnd == nil { - return perrors.Wrapf(err, "cannot open the SELinux DB") + return fmt.Errorf("cannot open the SELinux DB: %w", err) } defer C.selabel_close(selinuxHnd) diff --git a/pkg/blobcache/blobcache.go b/pkg/blobcache/blobcache.go index 17a4a7c99..2bbf48848 100644 --- a/pkg/blobcache/blobcache.go +++ b/pkg/blobcache/blobcache.go @@ -11,7 +11,6 @@ import ( "github.com/containers/image/v5/transports" "github.com/containers/image/v5/types" digest "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" ) const ( @@ -102,7 +101,7 @@ func (b *BlobCache) findBlob(info types.BlobInfo) (string, int64, bool, error) { return path, fileInfo.Size(), isConfig, nil } if !os.IsNotExist(err) { - return "", -1, false, perrors.Wrap(err, "checking size") + return "", -1, false, fmt.Errorf("checking size: %w", err) } } @@ -133,12 +132,12 @@ func (b *BlobCache) ClearCache() error { defer f.Close() names, err := f.Readdirnames(-1) if err != nil { - return perrors.Wrapf(err, "error reading directory %q", b.directory) + return fmt.Errorf("error reading directory %q: %w", b.directory, err) } for _, name := range names { pathname := filepath.Join(b.directory, name) if err = os.RemoveAll(pathname); err != nil { - return perrors.Wrapf(err, "clearing cache for %q", transports.ImageName(b)) + return fmt.Errorf("clearing cache for %q: %w", transports.ImageName(b), err) } } return nil diff --git a/pkg/blobcache/dest.go b/pkg/blobcache/dest.go index 7ea7bbba2..c69eea6e3 100644 --- a/pkg/blobcache/dest.go +++ b/pkg/blobcache/dest.go @@ -3,6 +3,7 @@ package blobcache import ( "bytes" "context" + "fmt" "io" "os" "path/filepath" @@ -19,7 +20,6 @@ import ( "github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/ioutils" digest "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -33,7 +33,7 @@ type blobCacheDestination struct { func (b *BlobCache) NewImageDestination(ctx context.Context, sys *types.SystemContext) (types.ImageDestination, error) { dest, err := b.reference.NewImageDestination(ctx, sys) if err != nil { - return nil, perrors.Wrapf(err, "error creating new image destination %q", transports.ImageName(b.reference)) + return nil, fmt.Errorf("error creating new image destination %q: %w", transports.ImageName(b.reference), err) } logrus.Debugf("starting to write to image %q using blob cache in %q", transports.ImageName(b.reference), b.directory) d := &blobCacheDestination{reference: b, destination: imagedestination.FromPublic(dest)} @@ -155,7 +155,7 @@ func (d *blobCacheDestination) PutBlobWithOptions(ctx context.Context, stream io if err2 := os.Remove(tempfile.Name()); err2 != nil { logrus.Debugf("error cleaning up temporary file %q for blob %q: %v", tempfile.Name(), inputInfo.Digest.String(), err2) } - err = perrors.Wrapf(err, "error renaming new layer for blob %q into place at %q", inputInfo.Digest.String(), filename) + err = fmt.Errorf("error renaming new layer for blob %q into place at %q: %w", inputInfo.Digest.String(), filename, err) } } else { if err2 := os.Remove(tempfile.Name()); err2 != nil { @@ -207,7 +207,7 @@ func (d *blobCacheDestination) PutBlobWithOptions(ctx context.Context, stream io wg.Wait() } if err != nil { - return newBlobInfo, perrors.Wrapf(err, "error storing blob to image destination for cache %q", transports.ImageName(d.reference)) + return newBlobInfo, fmt.Errorf("error storing blob to image destination for cache %q: %w", transports.ImageName(d.reference), err) } if alternateDigest.Validate() == nil { logrus.Debugf("added blob %q (also %q) to the cache at %q", inputInfo.Digest.String(), alternateDigest.String(), d.reference.directory) diff --git a/pkg/blobcache/src.go b/pkg/blobcache/src.go index 74ad46666..60677470f 100644 --- a/pkg/blobcache/src.go +++ b/pkg/blobcache/src.go @@ -18,7 +18,6 @@ import ( "github.com/containers/image/v5/types" digest "github.com/opencontainers/go-digest" v1 "github.com/opencontainers/image-spec/specs-go/v1" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -38,7 +37,7 @@ type blobCacheSource struct { func (b *BlobCache) NewImageSource(ctx context.Context, sys *types.SystemContext) (types.ImageSource, error) { src, err := b.reference.NewImageSource(ctx, sys) if err != nil { - return nil, perrors.Wrapf(err, "error creating new image source %q", transports.ImageName(b.reference)) + return nil, fmt.Errorf("error creating new image source %q: %w", transports.ImageName(b.reference), err) } logrus.Debugf("starting to read from image %q using blob cache in %q (compression=%v)", transports.ImageName(b.reference), b.directory, b.compress) s := &blobCacheSource{reference: b, source: imagesource.FromPublic(src), sys: *sys} @@ -65,7 +64,7 @@ func (s *blobCacheSource) GetManifest(ctx context.Context, instanceDigest *diges } if !os.IsNotExist(err) { s.cacheErrors++ - return nil, "", perrors.Wrap(err, "checking for manifest file") + return nil, "", fmt.Errorf("checking for manifest file: %w", err) } } s.cacheMisses++ @@ -93,7 +92,7 @@ func (s *blobCacheSource) GetBlob(ctx context.Context, blobinfo types.BlobInfo, s.mu.Lock() s.cacheErrors++ s.mu.Unlock() - return nil, -1, perrors.Wrap(err, "checking for cache") + return nil, -1, fmt.Errorf("checking for cache: %w", err) } } s.mu.Lock() @@ -101,7 +100,7 @@ func (s *blobCacheSource) GetBlob(ctx context.Context, blobinfo types.BlobInfo, s.mu.Unlock() rc, size, err := s.source.GetBlob(ctx, blobinfo, cache) if err != nil { - return rc, size, perrors.Wrapf(err, "error reading blob from source image %q", transports.ImageName(s.reference)) + return rc, size, fmt.Errorf("error reading blob from source image %q: %w", transports.ImageName(s.reference), err) } return rc, size, nil } @@ -117,18 +116,18 @@ func (s *blobCacheSource) GetSignaturesWithFormat(ctx context.Context, instanceD func (s *blobCacheSource) LayerInfosForCopy(ctx context.Context, instanceDigest *digest.Digest) ([]types.BlobInfo, error) { signatures, err := s.source.GetSignaturesWithFormat(ctx, instanceDigest) if err != nil { - return nil, perrors.Wrapf(err, "error checking if image %q has signatures", transports.ImageName(s.reference)) + return nil, fmt.Errorf("error checking if image %q has signatures: %w", transports.ImageName(s.reference), err) } canReplaceBlobs := len(signatures) == 0 infos, err := s.source.LayerInfosForCopy(ctx, instanceDigest) if err != nil { - return nil, perrors.Wrapf(err, "error getting layer infos for copying image %q through cache", transports.ImageName(s.reference)) + return nil, fmt.Errorf("error getting layer infos for copying image %q through cache: %w", transports.ImageName(s.reference), err) } if infos == nil { img, err := image.FromUnparsedImage(ctx, &s.sys, image.UnparsedInstance(s.source, instanceDigest)) if err != nil { - return nil, perrors.Wrapf(err, "error opening image to get layer infos for copying image %q through cache", transports.ImageName(s.reference)) + return nil, fmt.Errorf("error opening image to get layer infos for copying image %q through cache: %w", transports.ImageName(s.reference), err) } infos = img.LayerInfos() } diff --git a/pkg/compression/compression.go b/pkg/compression/compression.go index a2191660a..ce688d117 100644 --- a/pkg/compression/compression.go +++ b/pkg/compression/compression.go @@ -10,7 +10,6 @@ import ( "github.com/containers/image/v5/pkg/compression/types" "github.com/containers/storage/pkg/chunked/compressor" "github.com/klauspost/pgzip" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/ulikunitz/xz" ) @@ -151,13 +150,13 @@ func DetectCompression(input io.Reader) (DecompressorFunc, io.Reader, error) { func AutoDecompress(stream io.Reader) (io.ReadCloser, bool, error) { decompressor, stream, err := DetectCompression(stream) if err != nil { - return nil, false, perrors.Wrapf(err, "detecting compression") + return nil, false, fmt.Errorf("detecting compression: %w", err) } var res io.ReadCloser if decompressor != nil { res, err = decompressor(stream) if err != nil { - return nil, false, perrors.Wrapf(err, "initializing decompression") + return nil, false, fmt.Errorf("initializing decompression: %w", err) } } else { res = io.NopCloser(stream) diff --git a/pkg/docker/config/config.go b/pkg/docker/config/config.go index 10d1b244a..9623546d8 100644 --- a/pkg/docker/config/config.go +++ b/pkg/docker/config/config.go @@ -19,7 +19,6 @@ import ( helperclient "github.com/docker/docker-credential-helpers/client" "github.com/docker/docker-credential-helpers/credentials" "github.com/hashicorp/go-multierror" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -150,7 +149,7 @@ func GetAllCredentials(sys *types.SystemContext) (map[string]types.DockerAuthCon // readJSONFile returns an empty map in case the path doesn't exist. auths, err := readJSONFile(path.path, path.legacyFormat) if err != nil { - return nil, perrors.Wrapf(err, "reading JSON file %q", path.path) + return nil, fmt.Errorf("reading JSON file %q: %w", path.path, err) } // Credential helpers in the auth file have a // direct mapping to a registry, so we can just @@ -357,7 +356,7 @@ func getAuthenticationWithHomeDir(sys *types.SystemContext, key, homeDir string) return "", "", err } if auth.IdentityToken != "" { - return "", "", perrors.Wrap(ErrNotSupported, "non-empty identity token found and this API doesn't support it") + return "", "", fmt.Errorf("non-empty identity token found and this API doesn't support it: %w", ErrNotSupported) } return auth.Username, auth.Password, nil } @@ -396,7 +395,7 @@ func RemoveAuthentication(sys *types.SystemContext, key string) error { return } } - multiErr = multierror.Append(multiErr, perrors.Wrapf(err, "removing credentials for %s from credential helper %s", key, helper)) + multiErr = multierror.Append(multiErr, fmt.Errorf("removing credentials for %s from credential helper %s: %w", key, helper, err)) } for _, helper := range helpers { @@ -529,7 +528,7 @@ func getPathToAuthWithOS(sys *types.SystemContext, goOS string) (string, bool, e // This means the user set the XDG_RUNTIME_DIR variable and either forgot to create the directory // or made a typo while setting the environment variable, // so return an error referring to $XDG_RUNTIME_DIR instead of xdgRuntimeDirPath inside. - return "", false, perrors.Wrapf(err, "%q directory set by $XDG_RUNTIME_DIR does not exist. Either create the directory or unset $XDG_RUNTIME_DIR.", runtimeDir) + return "", false, fmt.Errorf("%q directory set by $XDG_RUNTIME_DIR does not exist. Either create the directory or unset $XDG_RUNTIME_DIR.: %w", runtimeDir, err) } // else ignore err and let the caller fail accessing xdgRuntimeDirPath. return filepath.Join(runtimeDir, xdgRuntimeDirPath), false, nil } @@ -553,13 +552,13 @@ func readJSONFile(path string, legacyFormat bool) (dockerConfigFile, error) { if legacyFormat { if err = json.Unmarshal(raw, &auths.AuthConfigs); err != nil { - return dockerConfigFile{}, perrors.Wrapf(err, "unmarshaling JSON at %q", path) + return dockerConfigFile{}, fmt.Errorf("unmarshaling JSON at %q: %w", path, err) } return auths, nil } if err = json.Unmarshal(raw, &auths); err != nil { - return dockerConfigFile{}, perrors.Wrapf(err, "unmarshaling JSON at %q", path) + return dockerConfigFile{}, fmt.Errorf("unmarshaling JSON at %q: %w", path, err) } if auths.AuthConfigs == nil { @@ -591,21 +590,21 @@ func modifyJSON(sys *types.SystemContext, editor func(auths *dockerConfigFile) ( auths, err := readJSONFile(path, false) if err != nil { - return "", perrors.Wrapf(err, "reading JSON file %q", path) + return "", fmt.Errorf("reading JSON file %q: %w", path, err) } updated, err := editor(&auths) if err != nil { - return "", perrors.Wrapf(err, "updating %q", path) + return "", fmt.Errorf("updating %q: %w", path, err) } if updated { newData, err := json.MarshalIndent(auths, "", "\t") if err != nil { - return "", perrors.Wrapf(err, "marshaling JSON %q", path) + return "", fmt.Errorf("marshaling JSON %q: %w", path, err) } if err = ioutils.AtomicWriteFile(path, newData, 0600); err != nil { - return "", perrors.Wrapf(err, "writing to file %q", path) + return "", fmt.Errorf("writing to file %q: %w", path, err) } } @@ -659,7 +658,7 @@ func deleteAuthFromCredHelper(credHelper, registry string) error { func findCredentialsInFile(key, registry, path string, legacyFormat bool) (types.DockerAuthConfig, error) { auths, err := readJSONFile(path, legacyFormat) if err != nil { - return types.DockerAuthConfig{}, perrors.Wrapf(err, "reading JSON file %q", path) + return types.DockerAuthConfig{}, fmt.Errorf("reading JSON file %q: %w", path, err) } // First try cred helpers. They should always be normalized. diff --git a/pkg/shortnames/shortnames.go b/pkg/shortnames/shortnames.go index b23dd2fc6..3e16d8ca2 100644 --- a/pkg/shortnames/shortnames.go +++ b/pkg/shortnames/shortnames.go @@ -11,7 +11,6 @@ import ( "github.com/containers/image/v5/types" "github.com/manifoldco/promptui" "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" "golang.org/x/term" ) @@ -34,7 +33,7 @@ func IsShortName(input string) bool { func parseUnnormalizedShortName(input string) (bool, reference.Named, error) { ref, err := reference.Parse(input) if err != nil { - return false, nil, perrors.Wrapf(err, "cannot parse input: %q", input) + return false, nil, fmt.Errorf("cannot parse input: %q: %w", input, err) } named, ok := ref.(reference.Named) @@ -48,7 +47,7 @@ func parseUnnormalizedShortName(input string) (bool, reference.Named, error) { // normalized (e.g., docker.io/alpine to docker.io/library/alpine. named, err = reference.ParseNormalizedNamed(input) if err != nil { - return false, nil, perrors.Wrapf(err, "cannot normalize input: %q", input) + return false, nil, fmt.Errorf("cannot normalize input: %q: %w", input, err) } return false, named, nil } @@ -217,7 +216,7 @@ func (c *PullCandidate) Record() error { value := reference.TrimNamed(c.Value) if err := Add(c.resolved.systemContext, name.String(), value); err != nil { - return perrors.Wrapf(err, "recording short-name alias (%q=%q)", c.resolved.userInput, c.Value) + return fmt.Errorf("recording short-name alias (%q=%q): %w", c.resolved.userInput, c.Value, err) } return nil } @@ -280,7 +279,7 @@ func Resolve(ctx *types.SystemContext, name string) (*Resolved, error) { if ctx != nil && ctx.PodmanOnlyShortNamesIgnoreRegistriesConfAndForceDockerHub { named, err := reference.ParseNormalizedNamed(name) if err != nil { - return nil, perrors.Wrapf(err, "cannot normalize input: %q", name) + return nil, fmt.Errorf("cannot normalize input: %q: %w", name, err) } resolved.addCandidate(named) resolved.rationale = rationaleEnforcedDockerHub @@ -338,7 +337,7 @@ func Resolve(ctx *types.SystemContext, name string) (*Resolved, error) { for _, reg := range unqualifiedSearchRegistries { named, err := reference.ParseNormalizedNamed(fmt.Sprintf("%s/%s", reg, name)) if err != nil { - return nil, perrors.Wrapf(err, "creating reference with unqualified-search registry %q", reg) + return nil, fmt.Errorf("creating reference with unqualified-search registry %q: %w", reg, err) } resolved.addCandidate(named) } @@ -388,7 +387,7 @@ func Resolve(ctx *types.SystemContext, name string) (*Resolved, error) { named, err := reference.ParseNormalizedNamed(selection) if err != nil { - return nil, perrors.Wrapf(err, "selection %q is not a valid reference", selection) + return nil, fmt.Errorf("selection %q is not a valid reference: %w", selection, err) } resolved.PullCandidates = nil @@ -429,7 +428,7 @@ func ResolveLocally(ctx *types.SystemContext, name string) ([]reference.Named, e for _, reg := range registries { named, err := reference.ParseNormalizedNamed(fmt.Sprintf("%s/%s", reg, name)) if err != nil { - return nil, perrors.Wrapf(err, "creating reference with unqualified-search registry %q", reg) + return nil, fmt.Errorf("creating reference with unqualified-search registry %q: %w", reg, err) } named = reference.TagNameOnly(named) // Make sure to add ":latest" if needed candidates = append(candidates, named) diff --git a/pkg/sysregistriesv2/shortnames.go b/pkg/sysregistriesv2/shortnames.go index f0a8f5032..12939b24d 100644 --- a/pkg/sysregistriesv2/shortnames.go +++ b/pkg/sysregistriesv2/shortnames.go @@ -13,7 +13,6 @@ import ( "github.com/containers/image/v5/types" "github.com/containers/storage/pkg/homedir" "github.com/containers/storage/pkg/lockfile" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -211,7 +210,7 @@ func RemoveShortNameAlias(ctx *types.SystemContext, name string) error { func parseShortNameValue(alias string) (reference.Named, error) { ref, err := reference.Parse(alias) if err != nil { - return nil, perrors.Wrapf(err, "parsing alias %q", alias) + return nil, fmt.Errorf("parsing alias %q: %w", alias, err) } if _, ok := ref.(reference.Digested); ok { @@ -243,7 +242,7 @@ func parseShortNameValue(alias string) (reference.Named, error) { func validateShortName(name string) error { repo, err := reference.Parse(name) if err != nil { - return perrors.Wrapf(err, "cannot parse short name: %q", name) + return fmt.Errorf("cannot parse short name: %q: %w", name, err) } if _, ok := repo.(reference.Digested); ok { @@ -299,7 +298,7 @@ func newShortNameAliasCache(path string, conf *shortNameAliasConf) (*shortNameAl if len(errs) > 0 { err := errs[0] for i := 1; i < len(errs); i++ { - err = perrors.Wrapf(err, "%v\n", errs[i]) + err = fmt.Errorf("%v\n: %w", errs[i], err) } return nil, err } @@ -320,7 +319,7 @@ func loadShortNameAliasConf(confPath string) (*shortNameAliasConf, *shortNameAli meta, err := toml.DecodeFile(confPath, &conf) if err != nil && !os.IsNotExist(err) { // It's okay if the config doesn't exist. Other errors are not. - return nil, nil, perrors.Wrapf(err, "loading short-name aliases config file %q", confPath) + return nil, nil, fmt.Errorf("loading short-name aliases config file %q: %w", confPath, err) } if keys := meta.Undecoded(); len(keys) > 0 { logrus.Debugf("Failed to decode keys %q from %q", keys, confPath) @@ -330,7 +329,7 @@ func loadShortNameAliasConf(confPath string) (*shortNameAliasConf, *shortNameAli // file could still be corrupted by another process or user. cache, err := newShortNameAliasCache(confPath, &conf) if err != nil { - return nil, nil, perrors.Wrapf(err, "loading short-name aliases config file %q", confPath) + return nil, nil, fmt.Errorf("loading short-name aliases config file %q: %w", confPath, err) } return &conf, cache, nil diff --git a/pkg/sysregistriesv2/system_registries_v2.go b/pkg/sysregistriesv2/system_registries_v2.go index 442f3f043..41204dd9a 100644 --- a/pkg/sysregistriesv2/system_registries_v2.go +++ b/pkg/sysregistriesv2/system_registries_v2.go @@ -15,7 +15,6 @@ import ( "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/types" "github.com/containers/storage/pkg/homedir" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -103,7 +102,7 @@ func (e *Endpoint) rewriteReference(ref reference.Named, prefix string) (referen newNamedRef = e.Location + refString[prefixLen:] newParsedRef, err := reference.ParseNamed(newNamedRef) if err != nil { - return nil, perrors.Wrapf(err, "rewriting reference") + return nil, fmt.Errorf("rewriting reference: %w", err) } return newParsedRef, nil @@ -666,7 +665,7 @@ func dropInConfigs(wrapper configWrapper) ([]string, error) { if err != nil && !os.IsNotExist(err) { // Ignore IsNotExist errors: most systems won't have a registries.conf.d // directory. - return nil, perrors.Wrapf(err, "reading registries.conf.d") + return nil, fmt.Errorf("reading registries.conf.d: %w", err) } } @@ -708,7 +707,7 @@ func tryUpdatingCache(ctx *types.SystemContext, wrapper configWrapper) (*parsedC return nil, err // Should never happen } } else { - return nil, perrors.Wrapf(err, "loading registries configuration %q", wrapper.configPath) + return nil, fmt.Errorf("loading registries configuration %q: %w", wrapper.configPath, err) } } @@ -721,7 +720,7 @@ func tryUpdatingCache(ctx *types.SystemContext, wrapper configWrapper) (*parsedC // Enforce v2 format for drop-in-configs. dropIn, err := loadConfigFile(path, true) if err != nil { - return nil, perrors.Wrapf(err, "loading drop-in registries configuration %q", path) + return nil, fmt.Errorf("loading drop-in registries configuration %q: %w", path, err) } config.updateWithConfigurationFrom(dropIn) } @@ -975,7 +974,7 @@ func loadConfigFile(path string, forceV2 bool) (*parsedConfig, error) { // Parse and validate short-name aliases. cache, err := newShortNameAliasCache(path, &res.partialV2.shortNameAliasConf) if err != nil { - return nil, perrors.Wrap(err, "validating short-name aliases") + return nil, fmt.Errorf("validating short-name aliases: %w", err) } res.aliasCache = cache // Clear conf.partialV2.shortNameAliasConf to make it available for garbage collection and diff --git a/pkg/tlsclientconfig/tlsclientconfig.go b/pkg/tlsclientconfig/tlsclientconfig.go index c4586103e..9599aa3c9 100644 --- a/pkg/tlsclientconfig/tlsclientconfig.go +++ b/pkg/tlsclientconfig/tlsclientconfig.go @@ -12,7 +12,6 @@ import ( "github.com/docker/go-connections/sockets" "github.com/docker/go-connections/tlsconfig" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -50,7 +49,7 @@ func SetupCertificates(dir string, tlsc *tls.Config) error { if tlsc.RootCAs == nil { systemPool, err := tlsconfig.SystemCertPool() if err != nil { - return perrors.Wrap(err, "unable to get system cert pool") + return fmt.Errorf("unable to get system cert pool: %w", err) } tlsc.RootCAs = systemPool } diff --git a/signature/policy_config.go b/signature/policy_config.go index d3c07d03b..837154865 100644 --- a/signature/policy_config.go +++ b/signature/policy_config.go @@ -26,7 +26,6 @@ import ( "github.com/containers/image/v5/transports" "github.com/containers/image/v5/types" "github.com/containers/storage/pkg/homedir" - perrors "github.com/pkg/errors" ) // systemDefaultPolicyPath is the policy path used for DefaultPolicy(). @@ -83,7 +82,7 @@ func NewPolicyFromFile(fileName string) (*Policy, error) { } policy, err := NewPolicyFromBytes(contents) if err != nil { - return nil, perrors.Wrapf(err, "invalid policy in %q", fileName) + return nil, fmt.Errorf("invalid policy in %q: %w", fileName, err) } return policy, nil } diff --git a/signature/policy_config_test.go b/signature/policy_config_test.go index 5572869bb..01a5b1d46 100644 --- a/signature/policy_config_test.go +++ b/signature/policy_config_test.go @@ -9,7 +9,6 @@ import ( "github.com/containers/image/v5/directory" "github.com/containers/image/v5/docker" - perrors "github.com/pkg/errors" // this import is needed where we use the "atomic" transport in TestPolicyUnmarshalJSON _ "github.com/containers/image/v5/openshift" @@ -229,7 +228,8 @@ func TestNewPolicyFromFile(t *testing.T) { // A failure case; most are tested in the individual method unit tests. _, err = NewPolicyFromFile("/dev/null") require.Error(t, err) - assert.IsType(t, InvalidPolicyFormatError(""), perrors.Cause(err)) + var formatError InvalidPolicyFormatError + assert.ErrorAs(t, err, &formatError) } func TestNewPolicyFromBytes(t *testing.T) { diff --git a/storage/storage_dest.go b/storage/storage_dest.go index 4bc4cb5d5..ae3bfa8fa 100644 --- a/storage/storage_dest.go +++ b/storage/storage_dest.go @@ -33,7 +33,6 @@ import ( "github.com/containers/storage/pkg/ioutils" digest "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -90,7 +89,7 @@ type storageImageDestination struct { func newImageDestination(sys *types.SystemContext, imageRef storageReference) (*storageImageDestination, error) { directory, err := os.MkdirTemp(tmpdir.TemporaryDirectoryForBigFiles(sys), "storage") if err != nil { - return nil, perrors.Wrapf(err, "creating a temporary directory") + return nil, fmt.Errorf("creating a temporary directory: %w", err) } dest := &storageImageDestination{ PropertyMethodsInitialize: impl.PropertyMethods(impl.Properties{ @@ -189,7 +188,7 @@ func (s *storageImageDestination) putBlobToPendingFile(ctx context.Context, stre filename := s.computeNextBlobCacheFile() file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_EXCL, 0600) if err != nil { - return errorBlobInfo, perrors.Wrapf(err, "creating temporary file %q", filename) + return errorBlobInfo, fmt.Errorf("creating temporary file %q: %w", filename, err) } defer file.Close() counter := ioutils.NewWriteCounter(file) @@ -197,7 +196,7 @@ func (s *storageImageDestination) putBlobToPendingFile(ctx context.Context, stre digester, stream := putblobdigest.DigestIfUnknown(stream, blobinfo) decompressed, err := archive.DecompressStream(stream) if err != nil { - return errorBlobInfo, perrors.Wrap(err, "setting up to decompress blob") + return errorBlobInfo, fmt.Errorf("setting up to decompress blob: %w", err) } diffID := digest.Canonical.Digester() @@ -206,7 +205,7 @@ func (s *storageImageDestination) putBlobToPendingFile(ctx context.Context, stre _, err = io.Copy(diffID.Hash(), decompressed) decompressed.Close() if err != nil { - return errorBlobInfo, perrors.Wrapf(err, "storing blob to file %q", filename) + return errorBlobInfo, fmt.Errorf("storing blob to file %q: %w", filename, err) } // Determine blob properties, and fail if information that we were given about the blob @@ -320,7 +319,7 @@ func (s *storageImageDestination) tryReusingBlobAsPending(ctx context.Context, b // Check if we have the layer in the underlying additional layer store. aLayer, err := s.imageRef.transport.store.LookupAdditionalLayer(blobinfo.Digest, options.SrcRef.String()) if err != nil && !errors.Is(err, storage.ErrLayerUnknown) { - return false, types.BlobInfo{}, perrors.Wrapf(err, `looking for compressed layers with digest %q and labels`, blobinfo.Digest) + return false, types.BlobInfo{}, fmt.Errorf(`looking for compressed layers with digest %q and labels: %w`, blobinfo.Digest, err) } else if err == nil { // Record the uncompressed value so that we can use it to calculate layer IDs. s.blobDiffIDs[blobinfo.Digest] = aLayer.UncompressedDigest() @@ -337,7 +336,7 @@ func (s *storageImageDestination) tryReusingBlobAsPending(ctx context.Context, b return false, types.BlobInfo{}, errors.New(`Can not check for a blob with unknown digest`) } if err := blobinfo.Digest.Validate(); err != nil { - return false, types.BlobInfo{}, perrors.Wrapf(err, `Can not check for a blob with invalid digest`) + return false, types.BlobInfo{}, fmt.Errorf("Can not check for a blob with invalid digest: %w", err) } // Check if we've already cached it in a file. @@ -352,7 +351,7 @@ func (s *storageImageDestination) tryReusingBlobAsPending(ctx context.Context, b // Check if we have a wasn't-compressed layer in storage that's based on that blob. layers, err := s.imageRef.transport.store.LayersByUncompressedDigest(blobinfo.Digest) if err != nil && !errors.Is(err, storage.ErrLayerUnknown) { - return false, types.BlobInfo{}, perrors.Wrapf(err, `looking for layers with digest %q`, blobinfo.Digest) + return false, types.BlobInfo{}, fmt.Errorf(`looking for layers with digest %q: %w`, blobinfo.Digest, err) } if len(layers) > 0 { // Save this for completeness. @@ -367,7 +366,7 @@ func (s *storageImageDestination) tryReusingBlobAsPending(ctx context.Context, b // Check if we have a was-compressed layer in storage that's based on that blob. layers, err = s.imageRef.transport.store.LayersByCompressedDigest(blobinfo.Digest) if err != nil && !errors.Is(err, storage.ErrLayerUnknown) { - return false, types.BlobInfo{}, perrors.Wrapf(err, `looking for compressed layers with digest %q`, blobinfo.Digest) + return false, types.BlobInfo{}, fmt.Errorf(`looking for compressed layers with digest %q: %w`, blobinfo.Digest, err) } if len(layers) > 0 { // Record the uncompressed value so that we can use it to calculate layer IDs. @@ -386,7 +385,7 @@ func (s *storageImageDestination) tryReusingBlobAsPending(ctx context.Context, b if uncompressedDigest := options.Cache.UncompressedDigest(blobinfo.Digest); uncompressedDigest != "" && uncompressedDigest != blobinfo.Digest { layers, err := s.imageRef.transport.store.LayersByUncompressedDigest(uncompressedDigest) if err != nil && !errors.Is(err, storage.ErrLayerUnknown) { - return false, types.BlobInfo{}, perrors.Wrapf(err, `looking for layers with digest %q`, uncompressedDigest) + return false, types.BlobInfo{}, fmt.Errorf(`looking for layers with digest %q: %w`, uncompressedDigest, err) } if len(layers) > 0 { if blobinfo.Size != -1 { @@ -455,13 +454,13 @@ func (s *storageImageDestination) getConfigBlob(info types.BlobInfo) ([]byte, er return nil, errors.New(`no digest supplied when reading blob`) } if err := info.Digest.Validate(); err != nil { - return nil, perrors.Wrapf(err, `invalid digest supplied when reading blob`) + return nil, fmt.Errorf("invalid digest supplied when reading blob: %w", err) } // Assume it's a file, since we're only calling this from a place that expects to read files. if filename, ok := s.filenames[info.Digest]; ok { contents, err2 := os.ReadFile(filename) if err2 != nil { - return nil, perrors.Wrapf(err2, `reading blob from file %q`, filename) + return nil, fmt.Errorf(`reading blob from file %q: %w`, filename, err2) } return contents, nil } @@ -563,7 +562,7 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest // NOTE: use `TryReusingBlob` to prevent recursion. has, _, err := s.TryReusingBlob(ctx, blob.BlobInfo, none.NoCache, false) if err != nil { - return perrors.Wrapf(err, "checking for a layer based on blob %q", blob.Digest.String()) + return fmt.Errorf("checking for a layer based on blob %q: %w", blob.Digest.String(), err) } if !has { return fmt.Errorf("error determining uncompressed digest for blob %q", blob.Digest.String()) @@ -611,7 +610,7 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest if ok { layer, err := al.PutAs(id, lastLayer, nil) if err != nil && !errors.Is(err, storage.ErrDuplicateID) { - return perrors.Wrapf(err, "failed to put layer from digest and labels") + return fmt.Errorf("failed to put layer from digest and labels: %w", err) } lastLayer = layer.ID s.indexToStorageID[index] = &lastLayer @@ -636,7 +635,7 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest } } if layer == "" { - return perrors.Wrapf(err2, "locating layer for blob %q", blob.Digest) + return fmt.Errorf("locating layer for blob %q: %w", blob.Digest, err2) } // Read the layer's contents. noCompression := archive.Uncompressed @@ -645,7 +644,7 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest } diff, err2 := s.imageRef.transport.store.Diff("", layer, diffOptions) if err2 != nil { - return perrors.Wrapf(err2, "reading layer %q for blob %q", layer, blob.Digest) + return fmt.Errorf("reading layer %q for blob %q: %w", layer, blob.Digest, err2) } // Copy the layer diff to a file. Diff() takes a lock that it holds // until the ReadCloser that it returns is closed, and PutLayer() wants @@ -655,7 +654,7 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest file, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_EXCL, 0600) if err != nil { diff.Close() - return perrors.Wrapf(err, "creating temporary file %q", filename) + return fmt.Errorf("creating temporary file %q: %w", filename, err) } // Copy the data to the file. // TODO: This can take quite some time, and should ideally be cancellable using @@ -664,7 +663,7 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest diff.Close() file.Close() if err != nil { - return perrors.Wrapf(err, "storing blob to file %q", filename) + return fmt.Errorf("storing blob to file %q: %w", filename, err) } // Make sure that we can find this file later, should we need the layer's // contents again. @@ -675,7 +674,7 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest // Read the cached blob and use it as a diff. file, err := os.Open(filename) if err != nil { - return perrors.Wrapf(err, "opening file %q", filename) + return fmt.Errorf("opening file %q: %w", filename, err) } defer file.Close() // Build the new layer using the diff, regardless of where it came from. @@ -685,7 +684,7 @@ func (s *storageImageDestination) commitLayer(ctx context.Context, blob manifest UncompressedDigest: diffID, }, file) if err != nil && !errors.Is(err, storage.ErrDuplicateID) { - return perrors.Wrapf(err, "adding layer with blob %q", blob.Digest) + return fmt.Errorf("adding layer with blob %q: %w", blob.Digest, err) } s.indexToStorageID[index] = &layer.ID @@ -705,7 +704,7 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t } toplevelManifest, _, err := unparsedToplevel.Manifest(ctx) if err != nil { - return perrors.Wrapf(err, "retrieving top-level manifest") + return fmt.Errorf("retrieving top-level manifest: %w", err) } // If the name we're saving to includes a digest, then check that the // manifests that we're about to save all either match the one from the @@ -730,7 +729,7 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t // Find the list of layer blobs. man, err := manifest.FromBlob(s.manifest, manifest.GuessMIMEType(s.manifest)) if err != nil { - return perrors.Wrapf(err, "parsing manifest") + return fmt.Errorf("parsing manifest: %w", err) } layerBlobs := man.LayerInfos() @@ -766,15 +765,15 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t if err != nil { if !errors.Is(err, storage.ErrDuplicateID) { logrus.Debugf("error creating image: %q", err) - return perrors.Wrapf(err, "creating image %q", intendedID) + return fmt.Errorf("creating image %q: %w", intendedID, err) } img, err = s.imageRef.transport.store.Image(intendedID) if err != nil { - return perrors.Wrapf(err, "reading image %q", intendedID) + return fmt.Errorf("reading image %q: %w", intendedID, err) } if img.TopLayer != lastLayer { logrus.Debugf("error creating image: image with ID %q exists, but uses different layers", intendedID) - return perrors.Wrapf(storage.ErrDuplicateID, "image with ID %q already exists, but uses a different top layer", intendedID) + return fmt.Errorf("image with ID %q already exists, but uses a different top layer: %w", intendedID, storage.ErrDuplicateID) } logrus.Debugf("reusing image ID %q", img.ID) oldNames = append(oldNames, img.Names...) @@ -806,23 +805,23 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t for blob := range dataBlobs { v, err := os.ReadFile(s.filenames[blob]) if err != nil { - return perrors.Wrapf(err, "copying non-layer blob %q to image", blob) + return fmt.Errorf("copying non-layer blob %q to image: %w", blob, err) } if err := s.imageRef.transport.store.SetImageBigData(img.ID, blob.String(), v, manifest.Digest); err != nil { logrus.Debugf("error saving big data %q for image %q: %v", blob.String(), img.ID, err) - return perrors.Wrapf(err, "saving big data %q for image %q", blob.String(), img.ID) + return fmt.Errorf("saving big data %q for image %q: %w", blob.String(), img.ID, err) } } // Save the unparsedToplevel's manifest if it differs from the per-platform one, which is saved below. if len(toplevelManifest) != 0 && !bytes.Equal(toplevelManifest, s.manifest) { manifestDigest, err := manifest.Digest(toplevelManifest) if err != nil { - return perrors.Wrapf(err, "digesting top-level manifest") + return fmt.Errorf("digesting top-level manifest: %w", err) } key := manifestBigDataKey(manifestDigest) if err := s.imageRef.transport.store.SetImageBigData(img.ID, key, toplevelManifest, manifest.Digest); err != nil { logrus.Debugf("error saving top-level manifest for image %q: %v", img.ID, err) - return perrors.Wrapf(err, "saving top-level manifest for image %q", img.ID) + return fmt.Errorf("saving top-level manifest for image %q: %w", img.ID, err) } } // Save the image's manifest. Allow looking it up by digest by using the key convention defined by the Store. @@ -831,37 +830,37 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t key := manifestBigDataKey(s.manifestDigest) if err := s.imageRef.transport.store.SetImageBigData(img.ID, key, s.manifest, manifest.Digest); err != nil { logrus.Debugf("error saving manifest for image %q: %v", img.ID, err) - return perrors.Wrapf(err, "saving manifest for image %q", img.ID) + return fmt.Errorf("saving manifest for image %q: %w", img.ID, err) } key = storage.ImageDigestBigDataKey if err := s.imageRef.transport.store.SetImageBigData(img.ID, key, s.manifest, manifest.Digest); err != nil { logrus.Debugf("error saving manifest for image %q: %v", img.ID, err) - return perrors.Wrapf(err, "saving manifest for image %q", img.ID) + return fmt.Errorf("saving manifest for image %q: %w", img.ID, err) } // Save the signatures, if we have any. if len(s.signatures) > 0 { if err := s.imageRef.transport.store.SetImageBigData(img.ID, "signatures", s.signatures, manifest.Digest); err != nil { logrus.Debugf("error saving signatures for image %q: %v", img.ID, err) - return perrors.Wrapf(err, "saving signatures for image %q", img.ID) + return fmt.Errorf("saving signatures for image %q: %w", img.ID, err) } } for instanceDigest, signatures := range s.signatureses { key := signatureBigDataKey(instanceDigest) if err := s.imageRef.transport.store.SetImageBigData(img.ID, key, signatures, manifest.Digest); err != nil { logrus.Debugf("error saving signatures for image %q: %v", img.ID, err) - return perrors.Wrapf(err, "saving signatures for image %q", img.ID) + return fmt.Errorf("saving signatures for image %q: %w", img.ID, err) } } // Save our metadata. metadata, err := json.Marshal(s) if err != nil { logrus.Debugf("error encoding metadata for image %q: %v", img.ID, err) - return perrors.Wrapf(err, "encoding metadata for image %q", img.ID) + return fmt.Errorf("encoding metadata for image %q: %w", img.ID, err) } if len(metadata) != 0 { if err = s.imageRef.transport.store.SetMetadata(img.ID, string(metadata)); err != nil { logrus.Debugf("error saving metadata for image %q: %v", img.ID, err) - return perrors.Wrapf(err, "saving metadata for image %q", img.ID) + return fmt.Errorf("saving metadata for image %q: %w", img.ID, err) } logrus.Debugf("saved image metadata %q", string(metadata)) } @@ -869,7 +868,7 @@ func (s *storageImageDestination) Commit(ctx context.Context, unparsedToplevel t // values because AddNames() will deduplicate the list that we pass to it. if name := s.imageRef.DockerReference(); name != nil { if err := s.imageRef.transport.store.AddNames(img.ID, []string{name.String()}); err != nil { - return perrors.Wrapf(err, "adding names %v to image %q", name, img.ID) + return fmt.Errorf("adding names %v to image %q: %w", name, img.ID, err) } logrus.Debugf("added name %q to image %q", name, img.ID) } diff --git a/storage/storage_reference.go b/storage/storage_reference.go index 81340a9b3..dbb9804a6 100644 --- a/storage/storage_reference.go +++ b/storage/storage_reference.go @@ -5,6 +5,7 @@ package storage import ( "context" + "fmt" "strings" "github.com/containers/image/v5/docker/reference" @@ -12,7 +13,6 @@ import ( "github.com/containers/image/v5/types" "github.com/containers/storage" digest "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -31,11 +31,11 @@ func newReference(transport storageTransport, named reference.Named, id string) return nil, ErrInvalidReference } if named != nil && reference.IsNameOnly(named) { - return nil, perrors.Wrapf(ErrInvalidReference, "reference %s has neither a tag nor a digest", named.String()) + return nil, fmt.Errorf("reference %s has neither a tag nor a digest: %w", named.String(), ErrInvalidReference) } if id != "" { if err := validateImageID(id); err != nil { - return nil, perrors.Wrapf(ErrInvalidReference, "invalid ID value %q: %v", id, err) + return nil, fmt.Errorf("invalid ID value %q: %v: %w", id, err, ErrInvalidReference) } } // We take a copy of the transport, which contains a pointer to the @@ -145,12 +145,12 @@ func (s *storageReference) resolveImage(sys *types.SystemContext) (*storage.Imag } if s.id == "" { logrus.Debugf("reference %q does not resolve to an image ID", s.StringWithinTransport()) - return nil, perrors.Wrapf(ErrNoSuchImage, "reference %q does not resolve to an image ID", s.StringWithinTransport()) + return nil, fmt.Errorf("reference %q does not resolve to an image ID: %w", s.StringWithinTransport(), ErrNoSuchImage) } if loadedImage == nil { img, err := s.transport.store.Image(s.id) if err != nil { - return nil, perrors.Wrapf(err, "reading image %q", s.id) + return nil, fmt.Errorf("reading image %q: %w", s.id, err) } loadedImage = img } diff --git a/storage/storage_src.go b/storage/storage_src.go index cf255b34b..d4288dade 100644 --- a/storage/storage_src.go +++ b/storage/storage_src.go @@ -26,7 +26,6 @@ import ( "github.com/containers/storage/pkg/ioutils" digest "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -70,7 +69,7 @@ func newImageSource(ctx context.Context, sys *types.SystemContext, imageRef stor image.Compat = impl.AddCompat(image) if img.Metadata != "" { if err := json.Unmarshal([]byte(img.Metadata), image); err != nil { - return nil, perrors.Wrap(err, "decoding metadata for source image") + return nil, fmt.Errorf("decoding metadata for source image: %w", err) } } return image, nil @@ -183,7 +182,7 @@ func (s *storageImageSource) GetManifest(ctx context.Context, instanceDigest *di key := manifestBigDataKey(*instanceDigest) blob, err := s.imageRef.transport.store.ImageBigData(s.image.ID, key) if err != nil { - return nil, "", perrors.Wrapf(err, "reading manifest for image instance %q", *instanceDigest) + return nil, "", fmt.Errorf("reading manifest for image instance %q: %w", *instanceDigest, err) } return blob, manifest.GuessMIMEType(blob), err } @@ -220,14 +219,14 @@ func (s *storageImageSource) GetManifest(ctx context.Context, instanceDigest *di func (s *storageImageSource) LayerInfosForCopy(ctx context.Context, instanceDigest *digest.Digest) ([]types.BlobInfo, error) { manifestBlob, manifestType, err := s.GetManifest(ctx, instanceDigest) if err != nil { - return nil, perrors.Wrapf(err, "reading image manifest for %q", s.image.ID) + return nil, fmt.Errorf("reading image manifest for %q: %w", s.image.ID, err) } if manifest.MIMETypeIsMultiImage(manifestType) { return nil, errors.New("can't copy layers for a manifest list (shouldn't be attempted)") } man, err := manifest.FromBlob(manifestBlob, manifestType) if err != nil { - return nil, perrors.Wrapf(err, "parsing image manifest for %q", s.image.ID) + return nil, fmt.Errorf("parsing image manifest for %q: %w", s.image.ID, err) } uncompressedLayerType := "" @@ -243,7 +242,7 @@ func (s *storageImageSource) LayerInfosForCopy(ctx context.Context, instanceDige for layerID != "" { layer, err := s.imageRef.transport.store.Layer(layerID) if err != nil { - return nil, perrors.Wrapf(err, "reading layer %q in image %q", layerID, s.image.ID) + return nil, fmt.Errorf("reading layer %q in image %q: %w", layerID, s.image.ID, err) } if layer.UncompressedDigest == "" { return nil, fmt.Errorf("uncompressed digest for layer %q is unknown", layerID) @@ -262,7 +261,7 @@ func (s *storageImageSource) LayerInfosForCopy(ctx context.Context, instanceDige res, err := buildLayerInfosForCopy(man.LayerInfos(), physicalBlobInfos) if err != nil { - return nil, perrors.Wrapf(err, "creating LayerInfosForCopy of image %q", s.image.ID) + return nil, fmt.Errorf("creating LayerInfosForCopy of image %q: %w", s.image.ID, err) } return res, nil } @@ -313,7 +312,7 @@ func (s *storageImageSource) GetSignaturesWithFormat(ctx context.Context, instan if len(signatureSizes) > 0 { data, err := s.imageRef.transport.store.ImageBigData(s.image.ID, key) if err != nil { - return nil, perrors.Wrapf(err, "looking up signatures data for image %q (%s)", s.image.ID, instance) + return nil, fmt.Errorf("looking up signatures data for image %q (%s): %w", s.image.ID, instance, err) } signatureBlobs = data } @@ -342,12 +341,12 @@ func (s *storageImageSource) getSize() (int64, error) { // Size up the data blobs. dataNames, err := s.imageRef.transport.store.ListImageBigData(s.image.ID) if err != nil { - return -1, perrors.Wrapf(err, "reading image %q", s.image.ID) + return -1, fmt.Errorf("reading image %q: %w", s.image.ID, err) } for _, dataName := range dataNames { bigSize, err := s.imageRef.transport.store.ImageBigDataSize(s.image.ID, dataName) if err != nil { - return -1, perrors.Wrapf(err, "reading data blob size %q for %q", dataName, s.image.ID) + return -1, fmt.Errorf("reading data blob size %q for %q: %w", dataName, s.image.ID, err) } sum += bigSize } diff --git a/storage/storage_transport.go b/storage/storage_transport.go index 23aa6246c..104e9d8cc 100644 --- a/storage/storage_transport.go +++ b/storage/storage_transport.go @@ -15,7 +15,6 @@ import ( "github.com/containers/storage" "github.com/containers/storage/pkg/idtools" digest "github.com/opencontainers/go-digest" - perrors "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -118,13 +117,13 @@ func (s *storageTransport) DefaultGIDMap() []idtools.IDMap { // relative to the given store, and returns it in a reference object. func (s storageTransport) ParseStoreReference(store storage.Store, ref string) (*storageReference, error) { if ref == "" { - return nil, perrors.Wrapf(ErrInvalidReference, "%q is an empty reference", ref) + return nil, fmt.Errorf("%q is an empty reference: %w", ref, ErrInvalidReference) } if ref[0] == '[' { // Ignore the store specifier. closeIndex := strings.IndexRune(ref, ']') if closeIndex < 1 { - return nil, perrors.Wrapf(ErrInvalidReference, "store specifier in %q did not end", ref) + return nil, fmt.Errorf("store specifier in %q did not end: %w", ref, ErrInvalidReference) } ref = ref[closeIndex+1:] } @@ -136,7 +135,7 @@ func (s storageTransport) ParseStoreReference(store storage.Store, ref string) ( if split != -1 { possibleID := ref[split+1:] if possibleID == "" { - return nil, perrors.Wrapf(ErrInvalidReference, "empty trailing digest or ID in %q", ref) + return nil, fmt.Errorf("empty trailing digest or ID in %q: %w", ref, ErrInvalidReference) } // If it looks like a digest, leave it alone for now. if _, err := digest.Parse(possibleID); err != nil { @@ -148,7 +147,7 @@ func (s storageTransport) ParseStoreReference(store storage.Store, ref string) ( // so we might as well use the expanded value. id = img.ID } else { - return nil, perrors.Wrapf(ErrInvalidReference, "%q does not look like an image ID or digest", possibleID) + return nil, fmt.Errorf("%q does not look like an image ID or digest: %w", possibleID, ErrInvalidReference) } // We have recognized an image ID; peel it off. ref = ref[:split] @@ -174,7 +173,7 @@ func (s storageTransport) ParseStoreReference(store storage.Store, ref string) ( var err error named, err = reference.ParseNormalizedNamed(ref) if err != nil { - return nil, perrors.Wrapf(err, "parsing named reference %q", ref) + return nil, fmt.Errorf("parsing named reference %q: %w", ref, err) } named = reference.TagNameOnly(named) }