diff --git a/build/build.go b/build/build.go index 3fd2e581..42ec32a1 100644 --- a/build/build.go +++ b/build/build.go @@ -608,7 +608,7 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s } } - dt, desc, err := itpull.Combine(ctx, srcs, nil) + dt, desc, err := itpull.Combine(ctx, srcs, nil, false) if err != nil { return err } diff --git a/commands/imagetools/create.go b/commands/imagetools/create.go index f05571b0..5239bd0f 100644 --- a/commands/imagetools/create.go +++ b/commands/imagetools/create.go @@ -29,6 +29,7 @@ type createOptions struct { dryrun bool actionAppend bool progress string + preferIndex bool } func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, args []string) error { @@ -153,7 +154,7 @@ func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, arg } } - dt, desc, err := r.Combine(ctx, srcs, in.annotations) + dt, desc, err := r.Combine(ctx, srcs, in.annotations, in.preferIndex) if err != nil { return err } @@ -283,6 +284,7 @@ func createCmd(dockerCli command.Cli, opts RootOptions) *cobra.Command { flags.BoolVar(&options.actionAppend, "append", false, "Append to existing manifest") flags.StringVar(&options.progress, "progress", "auto", `Set type of progress output ("auto", "plain", "tty"). Use plain to show container output`) flags.StringArrayVarP(&options.annotations, "annotation", "", []string{}, "Add annotation to the image") + flags.BoolVar(&options.preferIndex, "prefer-index", true, "When only a single source is specified, prefer outputting an image index or manifest list instead of performing a carbon copy") return cmd } diff --git a/util/imagetools/create.go b/util/imagetools/create.go index a8c3241d..fa168b1a 100644 --- a/util/imagetools/create.go +++ b/util/imagetools/create.go @@ -29,7 +29,7 @@ type Source struct { Ref reference.Named } -func (r *Resolver) Combine(ctx context.Context, srcs []*Source, ann []string) ([]byte, ocispec.Descriptor, error) { +func (r *Resolver) Combine(ctx context.Context, srcs []*Source, ann []string, preferIndex bool) ([]byte, ocispec.Descriptor, error) { eg, ctx := errgroup.WithContext(ctx) dts := make([][]byte, len(srcs)) @@ -79,7 +79,12 @@ func (r *Resolver) Combine(ctx context.Context, srcs []*Source, ann []string) ([ // on single source, return original bytes if len(srcs) == 1 && len(ann) == 0 { - if mt := srcs[0].Desc.MediaType; mt == images.MediaTypeDockerSchema2ManifestList || mt == images.MediaTypeDockerSchema2Manifest || mt == ocispec.MediaTypeImageIndex { + switch srcs[0].Desc.MediaType { + case images.MediaTypeDockerSchema2Manifest: + if !preferIndex { + return dts[0], srcs[0].Desc, nil + } + case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: return dts[0], srcs[0].Desc, nil } }