@@ -25,6 +25,7 @@ import (
25
25
"github.com/compose-spec/compose-go/types"
26
26
"github.com/containerd/containerd/platforms"
27
27
moby "github.com/docker/docker/api/types"
28
+ "github.com/docker/docker/api/types/container"
28
29
"github.com/docker/docker/api/types/filters"
29
30
"github.com/docker/docker/api/types/network"
30
31
specs "github.com/opencontainers/image-spec/specs-go/v1"
@@ -162,6 +163,14 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
162
163
}
163
164
}
164
165
})
166
+ case "service_completed_successfully" :
167
+ exit , err := s .waitCompleted (ctx , project , dep )
168
+ if err != nil {
169
+ return err
170
+ }
171
+ if exit != 0 {
172
+ return fmt .Errorf ("service %q didn't completed successfully: exit %d" , dep , exit )
173
+ }
165
174
}
166
175
}
167
176
return eg .Wait ()
@@ -330,8 +339,8 @@ func (s *composeService) connectContainerToNetwork(ctx context.Context, id strin
330
339
func (s * composeService ) isServiceHealthy (ctx context.Context , project * types.Project , service string ) (bool , error ) {
331
340
containers , err := s .apiClient .ContainerList (ctx , moby.ContainerListOptions {
332
341
Filters : filters .NewArgs (
333
- filters . Arg ( "label" , fmt . Sprintf ( "%s=%s" , projectLabel , project .Name ) ),
334
- filters . Arg ( "label" , fmt . Sprintf ( "%s=%s" , serviceLabel , service ) ),
342
+ projectFilter ( project .Name ),
343
+ serviceFilter ( service ),
335
344
),
336
345
})
337
346
if err != nil {
@@ -356,6 +365,28 @@ func (s *composeService) isServiceHealthy(ctx context.Context, project *types.Pr
356
365
return true , nil
357
366
}
358
367
368
+ func (s * composeService ) waitCompleted (ctx context.Context , project * types.Project , dep string ) (int64 , error ) {
369
+ containers , err := s .apiClient .ContainerList (ctx , moby.ContainerListOptions {
370
+ Filters : filters .NewArgs (
371
+ projectFilter (project .Name ),
372
+ serviceFilter (dep ),
373
+ ),
374
+ })
375
+ if err != nil {
376
+ return 0 , err
377
+ }
378
+ for _ , c := range containers {
379
+ wait , errors := s .apiClient .ContainerWait (ctx , c .ID , container .WaitConditionNextExit )
380
+ select {
381
+ case w := <- wait :
382
+ return w .StatusCode , nil
383
+ case err := <- errors :
384
+ return 0 , err
385
+ }
386
+ }
387
+ return 0 , nil
388
+ }
389
+
359
390
func (s * composeService ) startService (ctx context.Context , project * types.Project , service types.ServiceConfig ) error {
360
391
err := s .waitDependencies (ctx , project , service )
361
392
if err != nil {
0 commit comments