diff --git a/commands/imagetools/create.go b/commands/imagetools/create.go index 95c59f0d8304..c02fc2ce686d 100644 --- a/commands/imagetools/create.go +++ b/commands/imagetools/create.go @@ -200,24 +200,39 @@ func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, arg eg, _ := errgroup.WithContext(ctx) pw := progress.WithPrefix(printer, "internal", true) + tagsByRepo := map[string][]reference.Named{} for _, t := range tags { + repo := t.Name() + tagsByRepo[repo] = append(tagsByRepo[repo], t) + } + + for repo, repoTags := range tagsByRepo { eg.Go(func() error { - return progress.Wrap(fmt.Sprintf("pushing %s", t.String()), pw.Write, func(sub progress.SubLogger) error { + seed := repoTags[0] + return progress.Wrap(fmt.Sprintf("pushing %s", repo), pw.Write, func(sub progress.SubLogger) error { baseCtx := ctx eg2, _ := errgroup.WithContext(ctx) for _, desc := range manifests { eg2.Go(func() error { ctx = withMediaTypeKeyPrefix(baseCtx) - sub.Log(1, fmt.Appendf(nil, "copying %s from %s to %s\n", desc.Digest.String(), desc.Source.Ref.String(), t.String())) - return r.Copy(ctx, desc.Source, t) + sub.Log(1, fmt.Appendf(nil, "copying %s from %s to %s\n", desc.Digest.String(), desc.Source.Ref.String(), repo)) + return r.Copy(ctx, &imagetools.Source{ + Ref: desc.Source.Ref, + Desc: desc.Descriptor, + }, seed) }) } if err := eg2.Wait(); err != nil { return err } ctx = withMediaTypeKeyPrefix(ctx) // because of containerd bug this needs to be called separately for each ctx/goroutine pair to avoid concurrent map write - sub.Log(1, fmt.Appendf(nil, "pushing %s to %s\n", desc.Digest.String(), t.String())) - return r.Push(ctx, t, desc, dt) + for _, t := range repoTags { + sub.Log(1, fmt.Appendf(nil, "pushing %s to %s\n", desc.Digest.String(), t.String())) + if err := r.Push(ctx, t, desc, dt); err != nil { + return err + } + } + return nil }) }) } diff --git a/util/imagetools/create.go b/util/imagetools/create.go index 60db747a47fd..979b3f7793b4 100644 --- a/util/imagetools/create.go +++ b/util/imagetools/create.go @@ -429,6 +429,9 @@ func (r *Resolver) filterPlatforms(ctx context.Context, dt []byte, desc ocispecs // try to pull in attestation manifest via referrer if one exists addedRef := false for d := range matchedManifests { + if _, ok := references[d]; ok { // manifest itself is already attestation + continue + } hasRef := false for _, subject := range references { if subject.Digest == d {