@@ -28,7 +28,6 @@ import (
2828 _ "github.com/docker/buildx/driver/docker" // required to get default driver registered
2929 "github.com/docker/buildx/util/buildflags"
3030 xprogress "github.com/docker/buildx/util/progress"
31- moby "github.com/docker/docker/api/types"
3231 bclient "github.com/moby/buildkit/client"
3332 "github.com/moby/buildkit/session"
3433 "github.com/moby/buildkit/session/auth/authprovider"
@@ -80,7 +79,7 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
8079 }
8180 }
8281
83- _ , err := s .doBuild (ctx , project , opts , Containers {}, options .Progress )
82+ _ , err := s .doBuild (ctx , project , opts , options .Progress )
8483 if err == nil {
8584 if len (imagesToBuild ) > 0 && ! options .Quiet {
8685 utils .DisplayScanSuggestMsg ()
@@ -90,7 +89,7 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
9089 return err
9190}
9291
93- func (s * composeService ) ensureImagesExists (ctx context.Context , project * types.Project , observedState Containers , quietPull bool ) error {
92+ func (s * composeService ) ensureImagesExists (ctx context.Context , project * types.Project , quietPull bool ) error {
9493 for _ , service := range project .Services {
9594 if service .Image == "" && service .Build == nil {
9695 return fmt .Errorf ("invalid service %q. Must specify either image or build" , service .Name )
@@ -111,37 +110,41 @@ func (s *composeService) ensureImagesExists(ctx context.Context, project *types.
111110 if quietPull {
112111 mode = xprogress .PrinterModeQuiet
113112 }
114- opts , imagesToBuild , err := s .getBuildOptions (project , images )
113+ opts , err := s .getBuildOptions (project , images )
115114 if err != nil {
116115 return err
117116 }
118- builtImages , err := s .doBuild (ctx , project , opts , observedState , mode )
117+ builtImages , err := s .doBuild (ctx , project , opts , mode )
119118 if err != nil {
120119 return err
121120 }
122121
123- if len (imagesToBuild ) > 0 {
122+ if len (builtImages ) > 0 {
124123 utils .DisplayScanSuggestMsg ()
125124 }
126125 for name , digest := range builtImages {
127126 images [name ] = digest
128127 }
129- // set digest as service.Image
128+ // set digest as com.docker.compose.image label so we can detect outdated containers
130129 for i , service := range project .Services {
131- digest , ok := images [getImageName (service , project .Name )]
130+ image := getImageName (service , project .Name )
131+ digest , ok := images [image ]
132132 if ok {
133- project .Services [i ].Image = digest
133+ if project .Services [i ].Labels == nil {
134+ project .Services [i ].Labels = types.Labels {}
135+ }
136+ project .Services [i ].Labels [api .ImageDigestLabel ] = digest
137+ project .Services [i ].Image = image
134138 }
135139 }
136140 return nil
137141}
138142
139- func (s * composeService ) getBuildOptions (project * types.Project , images map [string ]string ) (map [string ]build.Options , [] string , error ) {
143+ func (s * composeService ) getBuildOptions (project * types.Project , images map [string ]string ) (map [string ]build.Options , error ) {
140144 opts := map [string ]build.Options {}
141- imagesToBuild := []string {}
142145 for _ , service := range project .Services {
143146 if service .Image == "" && service .Build == nil {
144- return nil , nil , fmt .Errorf ("invalid service %q. Must specify either image or build" , service .Name )
147+ return nil , fmt .Errorf ("invalid service %q. Must specify either image or build" , service .Name )
145148 }
146149 imageName := getImageName (service , project .Name )
147150 _ , localImagePresent := images [imageName ]
@@ -150,16 +153,15 @@ func (s *composeService) getBuildOptions(project *types.Project, images map[stri
150153 if localImagePresent && service .PullPolicy != types .PullPolicyBuild {
151154 continue
152155 }
153- imagesToBuild = append (imagesToBuild , imageName )
154156 opt , err := s .toBuildOptions (project , service , imageName )
155157 if err != nil {
156- return nil , nil , err
158+ return nil , err
157159 }
158160 opts [imageName ] = opt
159161 continue
160162 }
161163 }
162- return opts , imagesToBuild , nil
164+ return opts , nil
163165
164166}
165167
@@ -182,7 +184,7 @@ func (s *composeService) getLocalImagesDigests(ctx context.Context, project *typ
182184 return images , nil
183185}
184186
185- func (s * composeService ) doBuild (ctx context.Context , project * types.Project , opts map [string ]build.Options , observedState Containers , mode string ) (map [string ]string , error ) {
187+ func (s * composeService ) doBuild (ctx context.Context , project * types.Project , opts map [string ]build.Options , mode string ) (map [string ]string , error ) {
186188 info , err := s .apiClient .Info (ctx )
187189 if err != nil {
188190 return nil , err
@@ -227,18 +229,6 @@ func (s *composeService) doBuild(ctx context.Context, project *types.Project, op
227229 return nil , WrapCategorisedComposeError (err , BuildFailure )
228230 }
229231
230- cw := progress .ContextWriter (ctx )
231- for _ , c := range observedState {
232- for imageName := range opts {
233- if c .Image == imageName {
234- err = s .removeContainers (ctx , cw , []moby.Container {c }, nil , false )
235- if err != nil {
236- return nil , err
237- }
238- }
239- }
240- }
241-
242232 imagesBuilt := map [string ]string {}
243233 for name , img := range response {
244234 if img == nil || len (img .ExporterResponse ) == 0 {
0 commit comments