copyUpdatedConfigAndManifest updates the image per ic.manifestUpdates, if necessary, stores the resulting config and manifest to the destination, and returns the stored manifest and its digest.
(ctx context.Context, instanceDigest *digest.Digest)
| 571 | // stores the resulting config and manifest to the destination, and returns the stored manifest |
| 572 | // and its digest. |
| 573 | func (ic *imageCopier) copyUpdatedConfigAndManifest(ctx context.Context, instanceDigest *digest.Digest) ([]byte, digest.Digest, error) { |
| 574 | var pendingImage types.Image = ic.src |
| 575 | if !ic.noPendingManifestUpdates() { |
| 576 | if ic.cannotModifyManifestReason != "" { |
| 577 | return nil, "", fmt.Errorf("Internal error: copy needs an updated manifest but that was known to be forbidden: %q", ic.cannotModifyManifestReason) |
| 578 | } |
| 579 | if !ic.diffIDsAreNeeded && ic.src.UpdatedImageNeedsLayerDiffIDs(*ic.manifestUpdates) { |
| 580 | // We have set ic.diffIDsAreNeeded based on the preferred MIME type returned by determineManifestConversion. |
| 581 | // So, this can only happen if we are trying to upload using one of the other MIME type candidates. |
| 582 | // Because UpdatedImageNeedsLayerDiffIDs is true only when converting from s1 to s2, this case should only arise |
| 583 | // when ic.c.dest.SupportedManifestMIMETypes() includes both s1 and s2, the upload using s1 failed, and we are now trying s2. |
| 584 | // Supposedly s2-only registries do not exist or are extremely rare, so failing with this error message is good enough for now. |
| 585 | // If handling such registries turns out to be necessary, we could compute ic.diffIDsAreNeeded based on the full list of manifest MIME type candidates. |
| 586 | return nil, "", fmt.Errorf("Can not convert image to %s, preparing DiffIDs for this case is not supported", ic.manifestUpdates.ManifestMIMEType) |
| 587 | } |
| 588 | pi, err := ic.src.UpdatedImage(ctx, *ic.manifestUpdates) |
| 589 | if err != nil { |
| 590 | return nil, "", fmt.Errorf("creating an updated image manifest: %w", err) |
| 591 | } |
| 592 | pendingImage = pi |
| 593 | } |
| 594 | man, _, err := pendingImage.Manifest(ctx) |
| 595 | if err != nil { |
| 596 | return nil, "", fmt.Errorf("reading manifest: %w", err) |
| 597 | } |
| 598 | |
| 599 | if err := ic.copyConfig(ctx, pendingImage); err != nil { |
| 600 | return nil, "", err |
| 601 | } |
| 602 | |
| 603 | ic.c.Printf("Writing manifest to image destination\n") |
| 604 | manifestDigest, err := manifest.Digest(man) |
| 605 | if err != nil { |
| 606 | return nil, "", err |
| 607 | } |
| 608 | if instanceDigest != nil { |
| 609 | instanceDigest = &manifestDigest |
| 610 | } |
| 611 | if err := ic.c.dest.PutManifest(ctx, man, instanceDigest); err != nil { |
| 612 | logrus.Debugf("Error %v while writing manifest %q", err, string(man)) |
| 613 | return nil, "", fmt.Errorf("writing manifest: %w", err) |
| 614 | } |
| 615 | return man, manifestDigest, nil |
| 616 | } |
| 617 | |
| 618 | // copyConfig copies config.json, if any, from src to dest. |
| 619 | func (ic *imageCopier) copyConfig(ctx context.Context, src types.Image) error { |
no test coverage detected