فهرست منبع

detect dependency failed to start

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 3 سال پیش
والد
کامیت
b8bbdcd872
3فایلهای تغییر یافته به همراه34 افزوده شده و 3 حذف شده
  1. 9 3
      pkg/compose/convergence.go
  2. 10 0
      pkg/e2e/fixtures/dependencies/dependency-exit.yaml
  3. 15 0
      pkg/e2e/up_test.go

+ 9 - 3
pkg/compose/convergence.go

@@ -31,6 +31,7 @@ import (
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/network"
 	specs "github.com/opencontainers/image-spec/specs-go/v1"
+	"github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
 	"golang.org/x/sync/errgroup"
 
@@ -277,7 +278,7 @@ func containerEvents(containers Containers, eventFunc func(string) progress.Even
 	return events
 }
 
-// ServiceConditionRunningOrHealthy is a service condition on statys running or healthy
+// ServiceConditionRunningOrHealthy is a service condition on status running or healthy
 const ServiceConditionRunningOrHealthy = "running_or_healthy"
 
 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
 				case types.ServiceConditionHealthy:
 					healthy, err := s.isServiceHealthy(ctx, project, dep, false)
 					if err != nil {
-						return err
+						w.Events(containerEvents(containers, progress.ErrorEvent))
+						return errors.Wrap(err, "dependency failed to start")
 					}
 					if healthy {
 						w.Events(containerEvents(containers, progress.Healthy))
@@ -644,7 +646,7 @@ func (s *composeService) connectContainerToNetwork(ctx context.Context, id strin
 }
 
 func (s *composeService) isServiceHealthy(ctx context.Context, project *types.Project, service string, fallbackRunning bool) (bool, error) {
-	containers, err := s.getContainers(ctx, project.Name, oneOffExclude, false, service)
+	containers, err := s.getContainers(ctx, project.Name, oneOffExclude, true, service)
 	if err != nil {
 		return false, err
 	}
@@ -662,6 +664,10 @@ func (s *composeService) isServiceHealthy(ctx context.Context, project *types.Pr
 			return container.State != nil && container.State.Status == "running", nil
 		}
 
+		if container.State.Status == "exited" {
+			return false, fmt.Errorf("container for service %q exited (%d)", service, container.State.ExitCode)
+		}
+
 		if container.State == nil || container.State.Health == nil {
 			return false, fmt.Errorf("container for service %q has no healthcheck configured", service)
 		}

+ 10 - 0
pkg/e2e/fixtures/dependencies/dependency-exit.yaml

@@ -0,0 +1,10 @@
+services:
+  web:
+    image: nginx:alpine
+    depends_on:
+      db:
+        condition: service_healthy
+  db:
+    image: alpine
+    command: sh -c "exit 1"
+

+ 15 - 0
pkg/e2e/up_test.go

@@ -123,3 +123,18 @@ func TestUpWithBuildDependencies(t *testing.T) {
 		res.Assert(t, icmd.Success)
 	})
 }
+
+func TestUpWithDependencyExit(t *testing.T) {
+	c := NewParallelCLI(t)
+
+	t.Run("up with dependency to exit before being healthy", func(t *testing.T) {
+		res := c.RunDockerComposeCmdNoCheck(t, "--project-directory", "fixtures/dependencies",
+			"-f", "fixtures/dependencies/dependency-exit.yaml", "up", "-d")
+
+		t.Cleanup(func() {
+			c.RunDockerComposeCmd(t, "--project-name", "dependencies", "down")
+		})
+
+		res.Assert(t, icmd.Expected{ExitCode: 1, Err: "dependency failed to start: container for service \"db\" exited (1)"})
+	})
+}