Skip to content

Commit e980432

Browse files
committed
imagetools: fix concurrent map write from containerd issue
Workaround for containerd issue that can cause concurrent map write when WithMediaTypeKeyPrefix is called in parallel goroutines for context that originated from same base context. Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
1 parent 606e9d1 commit e980432

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

commands/imagetools/create.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,6 @@ func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, arg
168168
return errors.Wrapf(err, "failed to parse annotations")
169169
}
170170

171-
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.oci.empty.v1+json", "empty")
172-
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.dev.cosign.artifact.sig.v1+json", "cosign")
173-
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.dev.cosign.simplesigning.v1+json", "simplesigning")
174-
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.dev.sigstore.bundle.v0.3+json", "sigstore-bundle")
175-
176171
dt, desc, manifests, err := r.Combine(ctx, srcs, annotations, in.preferIndex, platforms)
177172
if err != nil {
178173
return err
@@ -208,16 +203,19 @@ func runCreate(ctx context.Context, dockerCli command.Cli, in createOptions, arg
208203
for _, t := range tags {
209204
eg.Go(func() error {
210205
return progress.Wrap(fmt.Sprintf("pushing %s", t.String()), pw.Write, func(sub progress.SubLogger) error {
206+
baseCtx := ctx
211207
eg2, _ := errgroup.WithContext(ctx)
212208
for _, desc := range manifests {
213209
eg2.Go(func() error {
210+
ctx = withMediaTypeKeyPrefix(baseCtx)
214211
sub.Log(1, fmt.Appendf(nil, "copying %s from %s to %s\n", desc.Digest.String(), desc.Source.Ref.String(), t.String()))
215212
return r.Copy(ctx, desc.Source, t)
216213
})
217214
}
218215
if err := eg2.Wait(); err != nil {
219216
return err
220217
}
218+
ctx = withMediaTypeKeyPrefix(ctx) // because of containerd bug this needs to be called separately for each ctx/goroutine pair to avoid concurrent map write
221219
sub.Log(1, fmt.Appendf(nil, "pushing %s to %s\n", desc.Digest.String(), t.String()))
222220
return r.Push(ctx, t, desc, dt)
223221
})
@@ -265,6 +263,14 @@ func parsePlatforms(in []string) ([]ocispecs.Platform, error) {
265263
return out, nil
266264
}
267265

266+
func withMediaTypeKeyPrefix(ctx context.Context) context.Context {
267+
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.oci.empty.v1+json", "empty")
268+
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.dev.cosign.artifact.sig.v1+json", "cosign")
269+
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.dev.cosign.simplesigning.v1+json", "simplesigning")
270+
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.dev.sigstore.bundle.v0.3+json", "sigstore-bundle")
271+
return ctx
272+
}
273+
268274
func parseRefs(in []string) ([]reference.Named, error) {
269275
refs := make([]reference.Named, len(in))
270276
for i, in := range in {

0 commit comments

Comments
 (0)