Skip to content

Commit

Permalink
add support for service_completed_successfully
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
  • Loading branch information
ndeloof committed Apr 7, 2021
1 parent 80c8241 commit 15a21a4
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
35 changes: 33 additions & 2 deletions local/compose/convergence.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/compose-spec/compose-go/types"
"github.com/containerd/containerd/platforms"
moby "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/network"
specs "github.com/opencontainers/image-spec/specs-go/v1"
Expand Down Expand Up @@ -162,6 +163,14 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
}
}
})
case "service_completed_successfully":
exit, err := s.waitCompleted(ctx, project, dep)
if err != nil {
return err
}
if exit != 0 {
return fmt.Errorf("service %q didn't completed successfully: exit %d", dep, exit)
}
}
}
return eg.Wait()
Expand Down Expand Up @@ -330,8 +339,8 @@ func (s *composeService) connectContainerToNetwork(ctx context.Context, id strin
func (s *composeService) isServiceHealthy(ctx context.Context, project *types.Project, service string) (bool, error) {
containers, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
Filters: filters.NewArgs(
filters.Arg("label", fmt.Sprintf("%s=%s", projectLabel, project.Name)),
filters.Arg("label", fmt.Sprintf("%s=%s", serviceLabel, service)),
projectFilter(project.Name),
serviceFilter(service),
),
})
if err != nil {
Expand All @@ -356,6 +365,28 @@ func (s *composeService) isServiceHealthy(ctx context.Context, project *types.Pr
return true, nil
}

func (s *composeService) waitCompleted(ctx context.Context, project *types.Project, dep string) (int64, error) {
containers, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
Filters: filters.NewArgs(
projectFilter(project.Name),
serviceFilter(dep),
),
})
if err != nil {
return 0, err
}
for _, c := range containers {
wait, errors := s.apiClient.ContainerWait(ctx, c.ID, container.WaitConditionNextExit)
select {
case w := <-wait:
return w.StatusCode, nil
case err := <-errors:
return 0, err
}
}
return 0, nil
}

func (s *composeService) startService(ctx context.Context, project *types.Project, service types.ServiceConfig) error {
err := s.waitDependencies(ctx, project, service)
if err != nil {
Expand Down
10 changes: 10 additions & 0 deletions local/e2e/compose/compose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,13 @@ func TestAttachRestart(t *testing.T) {
execRegex := regexp.MustCompile(`another_1 \| world`)
assert.Equal(t, len(execRegex.FindAllStringIndex(output, -1)), 3, res.Combined())
}

func TestInitContainer(t *testing.T) {
c := NewParallelE2eCLI(t, binDir)

res := c.RunDockerOrExitError("compose", "--ansi=never", "--project-directory", "./fixtures/init-container", "up")
defer c.RunDockerCmd("compose", "-p", "init-container", "down")
output := res.Stdout()

assert.Assert(t, strings.Contains(output, "foo_1 | hello\nbar_1 | world"), res.Combined())
}
11 changes: 11 additions & 0 deletions local/e2e/compose/fixtures/init-container/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
services:
foo:
image: alpine
command: "echo hello"

bar:
image: alpine
command: "echo world"
depends_on:
foo:
condition: "service_completed_successfully"

0 comments on commit 15a21a4

Please sign in to comment.