@@ -20,6 +20,8 @@ import (
2020 "context"
2121 "fmt"
2222 "os"
23+ "strings"
24+ "sync"
2325
2426 "github.com/compose-spec/compose-go/types"
2527 "github.com/containerd/containerd/platforms"
@@ -29,10 +31,12 @@ import (
2931 "github.com/docker/buildx/util/buildflags"
3032 xprogress "github.com/docker/buildx/util/progress"
3133 moby "github.com/docker/docker/api/types"
34+ "github.com/docker/docker/registry"
3235 bclient "github.com/moby/buildkit/client"
3336 "github.com/moby/buildkit/session"
3437 "github.com/moby/buildkit/session/auth/authprovider"
3538 specs "github.com/opencontainers/image-spec/specs-go/v1"
39+ "golang.org/x/sync/errgroup"
3640
3741 "github.com/docker/compose-cli/pkg/api"
3842 "github.com/docker/compose-cli/pkg/progress"
@@ -97,7 +101,7 @@ func (s *composeService) ensureImagesExists(ctx context.Context, project *types.
97101 }
98102 }
99103
100- images , err := s .getLocalImagesDigests (ctx , project )
104+ images , err := s .getLocalImagesIDs (ctx , project )
101105 if err != nil {
102106 return err
103107 }
@@ -163,7 +167,19 @@ func (s *composeService) getBuildOptions(project *types.Project, images map[stri
163167
164168}
165169
166- func (s * composeService ) getLocalImagesDigests (ctx context.Context , project * types.Project ) (map [string ]string , error ) {
170+ func (s * composeService ) getLocalImagesIDs (ctx context.Context , project * types.Project ) (map [string ]string , error ) {
171+ imgs , err := s .getLocalImageSummaries (ctx , project )
172+ if err != nil {
173+ return nil , err
174+ }
175+ images := map [string ]string {}
176+ for name , info := range imgs {
177+ images [name ] = info .ID
178+ }
179+ return images , nil
180+ }
181+
182+ func (s * composeService ) getLocalImageSummaries (ctx context.Context , project * types.Project ) (map [string ]api.ImageSummary , error ) {
167183 imageNames := []string {}
168184 for _ , s := range project .Services {
169185 imgName := getImageName (s , project .Name )
@@ -175,13 +191,64 @@ func (s *composeService) getLocalImagesDigests(ctx context.Context, project *typ
175191 if err != nil {
176192 return nil , err
177193 }
178- images := map [string ]string {}
179- for name , info := range imgs {
180- images [name ] = info .ID
194+ return imgs , nil
195+ }
196+
197+ func (s * composeService ) getLocalImagesDigests (ctx context.Context , project * types.Project ) (map [string ][]string , error ) {
198+ imgs , err := s .getLocalImageSummaries (ctx , project )
199+ if err != nil {
200+ return nil , err
201+ }
202+ images := map [string ][]string {}
203+ for name , summary := range imgs {
204+ for _ , d := range summary .Digests {
205+ s := strings .Split (d , "@" )
206+ images [name ] = append (images [name ], s [len (s )- 1 ])
207+ }
181208 }
182209 return images , nil
183210}
184211
212+ func (s * composeService ) getDistributionImagesDigests (ctx context.Context , project * types.Project ) (map [string ]string , error ) {
213+ images := map [string ]string {}
214+
215+ for _ , service := range project .Services {
216+ if service .Image == "" {
217+ continue
218+ }
219+ images [service .Image ] = ""
220+ }
221+
222+ info , err := s .apiClient .Info (ctx )
223+ if err != nil {
224+ return nil , err
225+ }
226+
227+ if info .IndexServerAddress == "" {
228+ info .IndexServerAddress = registry .IndexServer
229+ }
230+
231+ l := sync.Mutex {}
232+ eg , ctx := errgroup .WithContext (ctx )
233+ for img := range images {
234+ img := img
235+ eg .Go (func () error {
236+ registryAuth , err := getEncodedRegistryAuth (img , info , s .configFile )
237+ if err != nil {
238+ return err
239+ }
240+ inspect , _ := s .apiClient .DistributionInspect (ctx , img , registryAuth )
241+ // Ignore error here.
242+ // If you catch error here, all inspect requests will fail.
243+ l .Lock ()
244+ images [img ] = inspect .Descriptor .Digest .String ()
245+ l .Unlock ()
246+ return nil
247+ })
248+ }
249+ return images , eg .Wait ()
250+ }
251+
185252func (s * composeService ) doBuild (ctx context.Context , project * types.Project , opts map [string ]build.Options , observedState Containers , mode string ) (map [string ]string , error ) {
186253 info , err := s .apiClient .Info (ctx )
187254 if err != nil {
0 commit comments