From b702188b65e8971eb2612907b89c2d097928a25f Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Tue, 16 May 2023 11:46:48 +0200 Subject: [PATCH] imagetools(create): set correct media type when combining manifests When using imagetools create and combining multiple sources we should check the media type of each manifest and set the right media type for the manifest list. If there is a mismatch we set OCI index as best effort. Signed-off-by: CrazyMax --- util/imagetools/create.go | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/util/imagetools/create.go b/util/imagetools/create.go index 953ac9a4..3b1057bc 100644 --- a/util/imagetools/create.go +++ b/util/imagetools/create.go @@ -122,24 +122,29 @@ func (r *Resolver) Combine(ctx context.Context, srcs []*Source) ([]byte, ocispec } } - mt := images.MediaTypeDockerSchema2ManifestList //ocispec.MediaTypeImageIndex - idx := struct { - // MediaType is reserved in the OCI spec but - // excluded from go types. - MediaType string `json:"mediaType,omitempty"` - - ocispec.Index - }{ - MediaType: mt, - Index: ocispec.Index{ - Versioned: specs.Versioned{ - SchemaVersion: 2, - }, - Manifests: newDescs, - }, + dockerMfsts := 0 + for _, desc := range newDescs { + if strings.HasPrefix(desc.MediaType, "application/vnd.docker.") { + dockerMfsts++ + } } - idxBytes, err := json.MarshalIndent(idx, "", " ") + var mt string + if dockerMfsts == len(newDescs) { + // all manifests are Docker types, use Docker manifest list + mt = images.MediaTypeDockerSchema2ManifestList + } else { + // otherwise, use OCI index + mt = ocispec.MediaTypeImageIndex + } + + idxBytes, err := json.MarshalIndent(ocispec.Index{ + MediaType: mt, + Versioned: specs.Versioned{ + SchemaVersion: 2, + }, + Manifests: newDescs, + }, "", " ") if err != nil { return nil, ocispec.Descriptor{}, errors.Wrap(err, "failed to marshal index") }