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

Method copyMultipleImages

copy/multiple.go:161–354  ·  view source on GitHub ↗

copyMultipleImages copies some or all of an image list's instances, using c.policyContext to validate source image admissibility.

(ctx context.Context)

Source from the content-addressed store, hash-verified

159// copyMultipleImages copies some or all of an image list's instances, using
160// c.policyContext to validate source image admissibility.
161func (c *copier) copyMultipleImages(ctx context.Context) (copiedManifest []byte, retErr error) {
162 // Parse the list and get a copy of the original value after it's re-encoded.
163 manifestList, manifestType, err := c.unparsedToplevel.Manifest(ctx)
164 if err != nil {
165 return nil, fmt.Errorf("reading manifest list: %w", err)
166 }
167 originalList, err := internalManifest.ListFromBlob(manifestList, manifestType)
168 if err != nil {
169 return nil, fmt.Errorf("parsing manifest list %q: %w", string(manifestList), err)
170 }
171 updatedList := originalList.CloneInternal()
172
173 sigs, err := c.sourceSignatures(ctx, c.unparsedToplevel,
174 "Getting image list signatures",
175 "Checking if image list destination supports signatures")
176 if err != nil {
177 return nil, err
178 }
179
180 // If the destination is a digested reference, make a note of that, determine what digest value we're
181 // expecting, and check that the source manifest matches it.
182 destIsDigestedReference := false
183 if named := c.dest.Reference().DockerReference(); named != nil {
184 if digested, ok := named.(reference.Digested); ok {
185 destIsDigestedReference = true
186 matches, err := manifest.MatchesDigest(manifestList, digested.Digest())
187 if err != nil {
188 return nil, fmt.Errorf("computing digest of source image's manifest: %w", err)
189 }
190 if !matches {
191 return nil, errors.New("Digest of source image's manifest would not match destination reference")
192 }
193 }
194 }
195
196 // Determine if we're allowed to modify the manifest list.
197 // If we can, set to the empty string. If we can't, set to the reason why.
198 // Compare, and perhaps keep in sync with, the version in copySingleImage.
199 cannotModifyManifestListReason := ""
200 if len(sigs) > 0 {
201 cannotModifyManifestListReason = "Would invalidate signatures"
202 }
203 if destIsDigestedReference {
204 cannotModifyManifestListReason = "Destination specifies a digest"
205 }
206 if c.options.PreserveDigests {
207 cannotModifyManifestListReason = "Instructed to preserve digests"
208 }
209
210 // Determine if we'll need to convert the manifest list to a different format.
211 forceListMIMEType := c.options.ForceManifestMIMEType
212 switch forceListMIMEType {
213 case manifest.DockerV2Schema1MediaType, manifest.DockerV2Schema1SignedMediaType, manifest.DockerV2Schema2MediaType:
214 forceListMIMEType = manifest.DockerV2ListMediaType
215 case imgspecv1.MediaTypeImageManifest:
216 forceListMIMEType = imgspecv1.MediaTypeImageIndex
217 }
218 selectedListType, otherManifestMIMETypeCandidates, err := c.determineListConversion(manifestType, c.dest.SupportedManifestMIMETypes(), forceListMIMEType)

Callers 1

ImageFunction · 0.95

Calls 15

sourceSignaturesMethod · 0.95
PrintfMethod · 0.95
copySingleImageMethod · 0.95
SerializeMethod · 0.95
createSignaturesMethod · 0.95
MatchesDigestFunction · 0.92
UnparsedInstanceFunction · 0.92
prepareInstanceCopiesFunction · 0.85
ManifestMethod · 0.65
CloneInternalMethod · 0.65
DockerReferenceMethod · 0.65

Tested by

no test coverage detected