@@ -28,7 +28,6 @@ import (
28
28
_ "github.com/docker/buildx/driver/docker" // required to get default driver registered
29
29
"github.com/docker/buildx/util/buildflags"
30
30
xprogress "github.com/docker/buildx/util/progress"
31
- moby "github.com/docker/docker/api/types"
32
31
bclient "github.com/moby/buildkit/client"
33
32
"github.com/moby/buildkit/session"
34
33
"github.com/moby/buildkit/session/auth/authprovider"
@@ -80,7 +79,7 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
80
79
}
81
80
}
82
81
83
- _ , err := s .doBuild (ctx , project , opts , Containers {}, options .Progress )
82
+ _ , err := s .doBuild (ctx , project , opts , options .Progress )
84
83
if err == nil {
85
84
if len (imagesToBuild ) > 0 && ! options .Quiet {
86
85
utils .DisplayScanSuggestMsg ()
@@ -90,7 +89,7 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
90
89
return err
91
90
}
92
91
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 {
94
93
for _ , service := range project .Services {
95
94
if service .Image == "" && service .Build == nil {
96
95
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.
111
110
if quietPull {
112
111
mode = xprogress .PrinterModeQuiet
113
112
}
114
- opts , imagesToBuild , err := s .getBuildOptions (project , images )
113
+ opts , err := s .getBuildOptions (project , images )
115
114
if err != nil {
116
115
return err
117
116
}
118
- builtImages , err := s .doBuild (ctx , project , opts , observedState , mode )
117
+ builtImages , err := s .doBuild (ctx , project , opts , mode )
119
118
if err != nil {
120
119
return err
121
120
}
122
121
123
- if len (imagesToBuild ) > 0 {
122
+ if len (builtImages ) > 0 {
124
123
utils .DisplayScanSuggestMsg ()
125
124
}
126
125
for name , digest := range builtImages {
127
126
images [name ] = digest
128
127
}
129
- // set digest as service.Image
128
+ // set digest as com.docker.compose.image label so we can detect outdated containers
130
129
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 ]
132
132
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
134
138
}
135
139
}
136
140
return nil
137
141
}
138
142
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 ) {
140
144
opts := map [string ]build.Options {}
141
- imagesToBuild := []string {}
142
145
for _ , service := range project .Services {
143
146
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 )
145
148
}
146
149
imageName := getImageName (service , project .Name )
147
150
_ , localImagePresent := images [imageName ]
@@ -150,16 +153,15 @@ func (s *composeService) getBuildOptions(project *types.Project, images map[stri
150
153
if localImagePresent && service .PullPolicy != types .PullPolicyBuild {
151
154
continue
152
155
}
153
- imagesToBuild = append (imagesToBuild , imageName )
154
156
opt , err := s .toBuildOptions (project , service , imageName )
155
157
if err != nil {
156
- return nil , nil , err
158
+ return nil , err
157
159
}
158
160
opts [imageName ] = opt
159
161
continue
160
162
}
161
163
}
162
- return opts , imagesToBuild , nil
164
+ return opts , nil
163
165
164
166
}
165
167
@@ -182,7 +184,7 @@ func (s *composeService) getLocalImagesDigests(ctx context.Context, project *typ
182
184
return images , nil
183
185
}
184
186
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 ) {
186
188
info , err := s .apiClient .Info (ctx )
187
189
if err != nil {
188
190
return nil , err
@@ -227,18 +229,6 @@ func (s *composeService) doBuild(ctx context.Context, project *types.Project, op
227
229
return nil , WrapCategorisedComposeError (err , BuildFailure )
228
230
}
229
231
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
-
242
232
imagesBuilt := map [string ]string {}
243
233
for name , img := range response {
244
234
if img == nil || len (img .ExporterResponse ) == 0 {
0 commit comments