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

Method copyLayers

copy/single.go:436–561  ·  view source on GitHub ↗

copyLayers copies layers from ic.src/ic.c.rawSource to dest, using and updating ic.manifestUpdates if necessary and ic.cannotModifyManifestReason == "".

(ctx context.Context)

Source from the content-addressed store, hash-verified

434
435// copyLayers copies layers from ic.src/ic.c.rawSource to dest, using and updating ic.manifestUpdates if necessary and ic.cannotModifyManifestReason == "".
436func (ic *imageCopier) copyLayers(ctx context.Context) ([]compressiontypes.Algorithm, error) {
437 srcInfos := ic.src.LayerInfos()
438 updatedSrcInfos, err := ic.src.LayerInfosForCopy(ctx)
439 if err != nil {
440 return nil, err
441 }
442 srcInfosUpdated := false
443 if updatedSrcInfos != nil && !reflect.DeepEqual(srcInfos, updatedSrcInfos) {
444 if ic.cannotModifyManifestReason != "" {
445 return nil, fmt.Errorf("Copying this image would require changing layer representation, which we cannot do: %q", ic.cannotModifyManifestReason)
446 }
447 srcInfos = updatedSrcInfos
448 srcInfosUpdated = true
449 }
450
451 type copyLayerData struct {
452 destInfo types.BlobInfo
453 diffID digest.Digest
454 err error
455 }
456
457 // The manifest is used to extract the information whether a given
458 // layer is empty.
459 man, err := manifest.FromBlob(ic.src.ManifestBlob, ic.src.ManifestMIMEType)
460 if err != nil {
461 return nil, err
462 }
463 manifestLayerInfos := man.LayerInfos()
464
465 // copyGroup is used to determine if all layers are copied
466 copyGroup := sync.WaitGroup{}
467
468 data := make([]copyLayerData, len(srcInfos))
469 copyLayerHelper := func(index int, srcLayer types.BlobInfo, toEncrypt bool, pool *mpb.Progress, srcRef reference.Named) {
470 defer ic.c.concurrentBlobCopiesSemaphore.Release(1)
471 defer copyGroup.Done()
472 cld := copyLayerData{}
473 if !ic.c.options.DownloadForeignLayers && ic.c.dest.AcceptsForeignLayerURLs() && len(srcLayer.URLs) != 0 {
474 // DiffIDs are, currently, needed only when converting from schema1.
475 // In which case src.LayerInfos will not have URLs because schema1
476 // does not support them.
477 if ic.diffIDsAreNeeded {
478 cld.err = errors.New("getting DiffID for foreign layers is unimplemented")
479 } else {
480 cld.destInfo = srcLayer
481 logrus.Debugf("Skipping foreign layer %q copy to %s", cld.destInfo.Digest, ic.c.dest.Reference().Transport().Name())
482 }
483 } else {
484 cld.destInfo, cld.diffID, cld.err = ic.copyLayer(ctx, srcLayer, toEncrypt, pool, index, srcRef, manifestLayerInfos[index].EmptyLayer)
485 }
486 data[index] = cld
487 }
488
489 // Decide which layers to encrypt
490 layersToEncrypt := set.New[int]()
491 if ic.c.options.OciEncryptLayers != nil {
492 totalLayers := len(srcInfos)
493 for _, l := range *ic.c.options.OciEncryptLayers {

Callers 1

copySingleImageMethod · 0.95

Calls 15

copyLayerMethod · 0.95
FromBlobFunction · 0.92
layerDigestsDifferFunction · 0.85
algorithmsByNamesFunction · 0.85
newProgressPoolMethod · 0.80
ContainsMethod · 0.80
AllMethod · 0.80
LayerInfosMethod · 0.65
LayerInfosForCopyMethod · 0.65
NameMethod · 0.65
TransportMethod · 0.65

Tested by

no test coverage detected