Browse Source

only check if a dependency is required when something unexpected happens

Signed-off-by: Guillaume Lours <[email protected]>
Guillaume Lours 2 years ago
parent
commit
2d16a05afa
2 changed files with 27 additions and 5 deletions
  1. 25 3
      pkg/compose/convergence.go
  2. 2 2
      pkg/e2e/up_test.go

+ 25 - 3
pkg/compose/convergence.go

@@ -286,9 +286,18 @@ func containerEvents(containers Containers, eventFunc func(string) progress.Even
 	return events
 }
 
+func containerSkippedEvents(containers Containers, eventFunc func(string, string) progress.Event, reason string) []progress.Event {
+	events := []progress.Event{}
+	for _, container := range containers {
+		events = append(events, eventFunc(getContainerProgressName(container), reason))
+	}
+	return events
+}
+
 // ServiceConditionRunningOrHealthy is a service condition on status running or healthy
 const ServiceConditionRunningOrHealthy = "running_or_healthy"
 
+//nolint:gocyclo
 func (s *composeService) waitDependencies(ctx context.Context, project *types.Project, dependencies types.DependsOnConfig, containers Containers) error {
 	eg, _ := errgroup.WithContext(ctx)
 	w := progress.ContextWriter(ctx)
@@ -312,6 +321,11 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
 				case ServiceConditionRunningOrHealthy:
 					healthy, err := s.isServiceHealthy(ctx, waitingFor, true)
 					if err != nil {
+						if !config.Required {
+							w.Events(containerSkippedEvents(waitingFor, progress.SkippedEvent, fmt.Sprintf("optional dependency %q is not running or is unhealthy", dep)))
+							logrus.Warnf("optional dependency %q is not running or is unhealthy: %s", dep, err.Error())
+							return nil
+						}
 						return err
 					}
 					if healthy {
@@ -321,6 +335,11 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
 				case types.ServiceConditionHealthy:
 					healthy, err := s.isServiceHealthy(ctx, waitingFor, false)
 					if err != nil {
+						if !config.Required {
+							w.Events(containerSkippedEvents(waitingFor, progress.SkippedEvent, fmt.Sprintf("optional dependency %q failed to start", dep)))
+							logrus.Warnf("optional dependency %q failed to start: %s", dep, err.Error())
+							return nil
+						}
 						w.Events(containerEvents(waitingFor, progress.ErrorEvent))
 						return errors.Wrap(err, "dependency failed to start")
 					}
@@ -334,6 +353,12 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
 						return err
 					}
 					if exited {
+						logMessageSuffix := fmt.Sprintf("%q didn't complete successfully: exit %d", dep, code)
+						if !config.Required {
+							w.Events(containerSkippedEvents(waitingFor, progress.SkippedEvent, fmt.Sprintf("optional dependency %s", logMessageSuffix)))
+							logrus.Warnf("optional dependency %s", logMessageSuffix)
+							return nil
+						}
 						w.Events(containerEvents(waitingFor, progress.Exited))
 						if code != 0 {
 							return fmt.Errorf("service %q didn't complete successfully: exit %d", dep, code)
@@ -362,9 +387,6 @@ func shouldWaitForDependency(serviceName string, dependencyConfig types.ServiceD
 				return false, nil
 			}
 		}
-		if !dependencyConfig.Required {
-			return false, nil
-		}
 		return false, err
 	} else if service.Scale == 0 {
 		// don't wait for the dependency which configured to have 0 containers running

+ 2 - 2
pkg/e2e/up_test.go

@@ -162,7 +162,7 @@ func TestUpWithDependencyNotRequired(t *testing.T) {
 	})
 
 	res := c.RunDockerComposeCmd(t, "-f", "./fixtures/dependencies/deps-not-required.yaml", "--project-name", projectName,
-		"up", "-d")
+		"--profile", "not-required", "up", "-d")
 	assert.Assert(t, strings.Contains(res.Combined(), "foo"), res.Combined())
-	assert.Assert(t, !strings.Contains(res.Combined(), "bar"), res.Combined())
+	assert.Assert(t, strings.Contains(res.Combined(), " optional dependency \"bar\" failed to start"), res.Combined())
 }