Skip to content

Commit b8bbdcd

Browse files
committed
detect dependency failed to start
Signed-off-by: Nicolas De Loof <[email protected]>
1 parent 9d12eec commit b8bbdcd

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

pkg/compose/convergence.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/docker/docker/api/types/filters"
3232
"github.com/docker/docker/api/types/network"
3333
specs "github.com/opencontainers/image-spec/specs-go/v1"
34+
"github.com/pkg/errors"
3435
"github.com/sirupsen/logrus"
3536
"golang.org/x/sync/errgroup"
3637

@@ -277,7 +278,7 @@ func containerEvents(containers Containers, eventFunc func(string) progress.Even
277278
return events
278279
}
279280

280-
// ServiceConditionRunningOrHealthy is a service condition on statys running or healthy
281+
// ServiceConditionRunningOrHealthy is a service condition on status running or healthy
281282
const ServiceConditionRunningOrHealthy = "running_or_healthy"
282283

283284
func (s *composeService) waitDependencies(ctx context.Context, project *types.Project, dependencies types.DependsOnConfig) error {
@@ -315,7 +316,8 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
315316
case types.ServiceConditionHealthy:
316317
healthy, err := s.isServiceHealthy(ctx, project, dep, false)
317318
if err != nil {
318-
return err
319+
w.Events(containerEvents(containers, progress.ErrorEvent))
320+
return errors.Wrap(err, "dependency failed to start")
319321
}
320322
if healthy {
321323
w.Events(containerEvents(containers, progress.Healthy))
@@ -644,7 +646,7 @@ func (s *composeService) connectContainerToNetwork(ctx context.Context, id strin
644646
}
645647

646648
func (s *composeService) isServiceHealthy(ctx context.Context, project *types.Project, service string, fallbackRunning bool) (bool, error) {
647-
containers, err := s.getContainers(ctx, project.Name, oneOffExclude, false, service)
649+
containers, err := s.getContainers(ctx, project.Name, oneOffExclude, true, service)
648650
if err != nil {
649651
return false, err
650652
}
@@ -662,6 +664,10 @@ func (s *composeService) isServiceHealthy(ctx context.Context, project *types.Pr
662664
return container.State != nil && container.State.Status == "running", nil
663665
}
664666

667+
if container.State.Status == "exited" {
668+
return false, fmt.Errorf("container for service %q exited (%d)", service, container.State.ExitCode)
669+
}
670+
665671
if container.State == nil || container.State.Health == nil {
666672
return false, fmt.Errorf("container for service %q has no healthcheck configured", service)
667673
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
services:
2+
web:
3+
image: nginx:alpine
4+
depends_on:
5+
db:
6+
condition: service_healthy
7+
db:
8+
image: alpine
9+
command: sh -c "exit 1"
10+

pkg/e2e/up_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,18 @@ func TestUpWithBuildDependencies(t *testing.T) {
123123
res.Assert(t, icmd.Success)
124124
})
125125
}
126+
127+
func TestUpWithDependencyExit(t *testing.T) {
128+
c := NewParallelCLI(t)
129+
130+
t.Run("up with dependency to exit before being healthy", func(t *testing.T) {
131+
res := c.RunDockerComposeCmdNoCheck(t, "--project-directory", "fixtures/dependencies",
132+
"-f", "fixtures/dependencies/dependency-exit.yaml", "up", "-d")
133+
134+
t.Cleanup(func() {
135+
c.RunDockerComposeCmd(t, "--project-name", "dependencies", "down")
136+
})
137+
138+
res.Assert(t, icmd.Expected{ExitCode: 1, Err: "dependency failed to start: container for service \"db\" exited (1)"})
139+
})
140+
}

0 commit comments

Comments
 (0)