MCPcopy Create free account
hub / github.com/containers/image / copyLayer

Method copyLayer

copy/single.go:696–892  ·  view source on GitHub ↗

copyLayer copies a layer with srcInfo (with known Digest and Annotations and possibly known Size) in src to dest, perhaps (de/re/)compressing it, and returns a complete blobInfo of the copied layer, and a value for LayerDiffIDs if diffIDIsNeeded srcRef can be used as an additional hint to the destin

(ctx context.Context, srcInfo types.BlobInfo, toEncrypt bool, pool *mpb.Progress, layerIndex int, srcRef reference.Named, emptyLayer bool)

Source from the content-addressed store, hash-verified

694// and returns a complete blobInfo of the copied layer, and a value for LayerDiffIDs if diffIDIsNeeded
695// srcRef can be used as an additional hint to the destination during checking whether a layer can be reused but srcRef can be nil.
696func (ic *imageCopier) copyLayer(ctx context.Context, srcInfo types.BlobInfo, toEncrypt bool, pool *mpb.Progress, layerIndex int, srcRef reference.Named, emptyLayer bool) (types.BlobInfo, digest.Digest, error) {
697 // If the srcInfo doesn't contain compression information, try to compute it from the
698 // MediaType, which was either read from a manifest by way of LayerInfos() or constructed
699 // by LayerInfosForCopy(), if it was supplied at all. If we succeed in copying the blob,
700 // the BlobInfo we return will be passed to UpdatedImage() and then to UpdateLayerInfos(),
701 // which uses the compression information to compute the updated MediaType values.
702 // (Sadly UpdatedImage() is documented to not update MediaTypes from
703 // ManifestUpdateOptions.LayerInfos[].MediaType, so we are doing it indirectly.)
704 if srcInfo.CompressionOperation == types.PreserveOriginal && srcInfo.CompressionAlgorithm == nil {
705 op, algo, err := compressionEditsFromBlobInfo(srcInfo)
706 if err != nil {
707 return types.BlobInfo{}, "", err
708 }
709 srcInfo.CompressionOperation = op
710 srcInfo.CompressionAlgorithm = algo
711 }
712
713 ic.c.printCopyInfo("blob", srcInfo)
714
715 diffIDIsNeeded := false
716 var cachedDiffID digest.Digest = ""
717 if ic.diffIDsAreNeeded {
718 cachedDiffID = ic.c.blobInfoCache.UncompressedDigest(srcInfo.Digest) // May be ""
719 diffIDIsNeeded = cachedDiffID == ""
720 }
721 // When encrypting to decrypting, only use the simple code path. We might be able to optimize more
722 // (e.g. if we know the DiffID of an encrypted compressed layer, it might not be necessary to pull, decrypt and decompress again),
723 // but it’s not trivially safe to do such things, so until someone takes the effort to make a comprehensive argument, let’s not.
724 encryptingOrDecrypting := toEncrypt || (isOciEncrypted(srcInfo.MediaType) && ic.c.options.OciDecryptConfig != nil)
725 canAvoidProcessingCompleteLayer := !diffIDIsNeeded && !encryptingOrDecrypting
726
727 // Don’t read the layer from the source if we already have the blob, and optimizations are acceptable.
728 if canAvoidProcessingCompleteLayer {
729 canChangeLayerCompression := ic.src.CanChangeLayerCompression(srcInfo.MediaType)
730 logrus.Debugf("Checking if we can reuse blob %s: general substitution = %v, compression for MIME type %q = %v",
731 srcInfo.Digest, ic.canSubstituteBlobs, srcInfo.MediaType, canChangeLayerCompression)
732 canSubstitute := ic.canSubstituteBlobs && canChangeLayerCompression
733
734 var requiredCompression *compressiontypes.Algorithm
735 if ic.requireCompressionFormatMatch {
736 requiredCompression = ic.compressionFormat
737 }
738
739 var tocDigest digest.Digest
740
741 // Check if we have a chunked layer in storage that's based on that blob. These layers are stored by their TOC digest.
742 d, err := chunkedToc.GetTOCDigest(srcInfo.Annotations)
743 if err != nil {
744 return types.BlobInfo{}, "", err
745 }
746 if d != nil {
747 tocDigest = *d
748 }
749
750 reused, reusedBlob, err := ic.c.dest.TryReusingBlobWithOptions(ctx, srcInfo, private.TryReusingBlobOptions{
751 Cache: ic.c.blobInfoCache,
752 CanSubstitute: canSubstitute,
753 EmptyLayer: emptyLayer,

Callers 1

copyLayersMethod · 0.95

Calls 15

copyLayerFromStreamMethod · 0.95
isOciEncryptedFunction · 0.85
updatedBlobInfoFromReuseFunction · 0.85
printCopyInfoMethod · 0.80
createProgressBarMethod · 0.80
UncompressedDigestMethod · 0.65
SupportsGetBlobAtMethod · 0.65

Tested by

no test coverage detected