ImageCopy copies an image. This will retag an image in the same repository, only pushing and pulling the top level manifest. On the same registry, it will attempt to use cross-repository blob mounts to avoid pulling blobs. Blobs are only pulled when they don't exist on the target and a blob mount fa
(ctx context.Context, refSrc ref.Ref, refTgt ref.Ref, opts ...ImageOpts)
| 523 | // Blobs are only pulled when they don't exist on the target and a blob mount fails. |
| 524 | // Referrers are optionally copied recursively. |
| 525 | func (rc *RegClient) ImageCopy(ctx context.Context, refSrc ref.Ref, refTgt ref.Ref, opts ...ImageOpts) error { |
| 526 | opt := imageOpt{ |
| 527 | seen: map[string]*imageSeen{}, |
| 528 | finalFn: []func(context.Context) error{}, |
| 529 | } |
| 530 | for _, optFn := range opts { |
| 531 | optFn(&opt) |
| 532 | } |
| 533 | // dedup warnings |
| 534 | if w := warning.FromContext(ctx); w == nil { |
| 535 | ctx = warning.NewContext(ctx, &warning.Warning{Hook: warning.DefaultHook()}) |
| 536 | } |
| 537 | // block GC from running (in OCIDir) during the copy |
| 538 | schemeTgtAPI, err := rc.schemeGet(refTgt.Scheme) |
| 539 | if err != nil { |
| 540 | return err |
| 541 | } |
| 542 | if tgtGCLocker, isGCLocker := schemeTgtAPI.(scheme.GCLocker); isGCLocker { |
| 543 | tgtGCLocker.GCLock(refTgt) |
| 544 | defer tgtGCLocker.GCUnlock(refTgt) |
| 545 | } |
| 546 | // run the copy of manifests and blobs recursively |
| 547 | err = rc.imageCopyOpt(ctx, refSrc, refTgt, descriptor.Descriptor{}, opt.child, []digest.Digest{}, &opt) |
| 548 | if err != nil { |
| 549 | return err |
| 550 | } |
| 551 | // run any final functions, digest-tags and referrers that detected loops are retried here |
| 552 | for _, fn := range opt.finalFn { |
| 553 | err := fn(ctx) |
| 554 | if err != nil { |
| 555 | return err |
| 556 | } |
| 557 | } |
| 558 | return nil |
| 559 | } |
| 560 | |
| 561 | // imageCopyOpt is a thread safe copy of a manifest and nested content. |
| 562 | func (rc *RegClient) imageCopyOpt(ctx context.Context, refSrc ref.Ref, refTgt ref.Ref, d descriptor.Descriptor, child bool, parents []digest.Digest, opt *imageOpt) (err error) { |