From 72e2a6adb0e7ef9db31aaabcc7fadf33b44382b1 Mon Sep 17 00:00:00 2001 From: Helio Machado <0x2b3bfa0+git@googlemail.com> Date: Sat, 17 May 2025 15:21:41 +0200 Subject: [PATCH 1/4] Fix concurrent map writes in pullRequiredImages function Fix concurrent map writes error in `pullRequiredImages` function in `pkg/compose/pull.go`. * Add a `sync.Mutex` to protect concurrent access to the map `images`. * Lock the `sync.Mutex` before writing to the map `images`. * Unlock the `sync.Mutex` after writing to the map `images`. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/docker/compose?shareId=XXXX-XXXX-XXXX-XXXX). --- pkg/compose/pull.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/compose/pull.go b/pkg/compose/pull.go index 0e70c189213..144196f6b6d 100644 --- a/pkg/compose/pull.go +++ b/pkg/compose/pull.go @@ -298,7 +298,7 @@ func (s *composeService) pullRequiredImages(ctx context.Context, project *types. return err } if pull { - needPull[name] = service + needPull[name] = service } for i, vol := range service.Volumes { if vol.Type == types.VolumeTypeImage { @@ -343,9 +343,11 @@ func (s *composeService) pullRequiredImages(ctx context.Context, project *types. } err := eg.Wait() for i, service := range needPull { + mutex.Lock() if pulledImages[i].ID != "" { images[service.Image] = pulledImages[i] } + mutex.Unlock() } return err }, s.stdinfo()) From b1f1fb532338f10a028745e89f7069ab5bcb6b7d Mon Sep 17 00:00:00 2001 From: Helio Machado <0x2b3bfa0+git@googlemail.com> Date: Sat, 17 May 2025 15:22:21 +0200 Subject: [PATCH 2/4] Update pull.go Signed-off-by: Helio Machado <0x2b3bfa0+git@googlemail.com> --- pkg/compose/pull.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/compose/pull.go b/pkg/compose/pull.go index 144196f6b6d..848f7a9a91f 100644 --- a/pkg/compose/pull.go +++ b/pkg/compose/pull.go @@ -298,7 +298,7 @@ func (s *composeService) pullRequiredImages(ctx context.Context, project *types. return err } if pull { - needPull[name] = service + needPull[name] = service } for i, vol := range service.Volumes { if vol.Type == types.VolumeTypeImage { From 70eaaf4c6843e58e003fb8f4ea914d0c55447a3a Mon Sep 17 00:00:00 2001 From: Helio Machado <0x2b3bfa0+git@googlemail.com> Date: Sat, 17 May 2025 15:27:36 +0200 Subject: [PATCH 3/4] Add mutexes to protect concurrent access to maps in `pullRequiredImages` function * Add `imagesMutex` to protect concurrent access to the `images` map * Add `pulledImagesMutex` to protect concurrent access to the `pulledImages` map * Lock and unlock `pulledImagesMutex` before and after writing to the `pulledImages` map * Lock and unlock `imagesMutex` before and after reading from the `images` map --- pkg/compose/pull.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pkg/compose/pull.go b/pkg/compose/pull.go index 848f7a9a91f..2dcce400ad7 100644 --- a/pkg/compose/pull.go +++ b/pkg/compose/pull.go @@ -298,7 +298,7 @@ func (s *composeService) pullRequiredImages(ctx context.Context, project *types. return err } if pull { - needPull[name] = service + needPull[name] = service } for i, vol := range service.Volumes { if vol.Type == types.VolumeTypeImage { @@ -323,12 +323,13 @@ func (s *composeService) pullRequiredImages(ctx context.Context, project *types. eg, ctx := errgroup.WithContext(ctx) eg.SetLimit(s.maxConcurrency) pulledImages := map[string]api.ImageSummary{} - var mutex sync.Mutex + var imagesMutex sync.Mutex + var pulledImagesMutex sync.Mutex for name, service := range needPull { eg.Go(func() error { id, err := s.pullServiceImage(ctx, service, s.configFile(), w, quietPull, project.Environment["DOCKER_DEFAULT_PLATFORM"]) - mutex.Lock() - defer mutex.Unlock() + pulledImagesMutex.Lock() + defer pulledImagesMutex.Unlock() pulledImages[name] = api.ImageSummary{ ID: id, Repository: service.Image, @@ -343,11 +344,11 @@ func (s *composeService) pullRequiredImages(ctx context.Context, project *types. } err := eg.Wait() for i, service := range needPull { - mutex.Lock() + imagesMutex.Lock() if pulledImages[i].ID != "" { images[service.Image] = pulledImages[i] } - mutex.Unlock() + imagesMutex.Unlock() } return err }, s.stdinfo()) From 4c555ce88cb92ff20e717ca9f7da18bbe60aaf34 Mon Sep 17 00:00:00 2001 From: Helio Machado <0x2b3bfa0+git@googlemail.com> Date: Sat, 17 May 2025 15:28:10 +0200 Subject: [PATCH 4/4] Update pull.go Signed-off-by: Helio Machado <0x2b3bfa0+git@googlemail.com> --- pkg/compose/pull.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/compose/pull.go b/pkg/compose/pull.go index 2dcce400ad7..946792d74e0 100644 --- a/pkg/compose/pull.go +++ b/pkg/compose/pull.go @@ -298,7 +298,7 @@ func (s *composeService) pullRequiredImages(ctx context.Context, project *types. return err } if pull { - needPull[name] = service + needPull[name] = service } for i, vol := range service.Volumes { if vol.Type == types.VolumeTypeImage {