Skip to content

Commit

Permalink
wait on service containers as dependencies to be deterministic
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas De Loof <[email protected]>
  • Loading branch information
ndeloof committed Jan 26, 2023
1 parent 79361a5 commit 0834430
Showing 1 changed file with 13 additions and 12 deletions.
25 changes: 13 additions & 12 deletions pkg/compose/convergence.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
<-ticker.C
switch config.Condition {
case ServiceConditionRunningOrHealthy:
healthy, err := s.isServiceHealthy(ctx, containers, dep, true)
healthy, err := s.isServiceHealthy(ctx, containers, true)
if err != nil {
return err
}
Expand All @@ -310,7 +310,7 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
return nil
}
case types.ServiceConditionHealthy:
healthy, err := s.isServiceHealthy(ctx, containers, dep, false)
healthy, err := s.isServiceHealthy(ctx, containers, false)
if err != nil {
w.Events(containerEvents(containers, progress.ErrorEvent))
return errors.Wrap(err, "dependency failed to start")
Expand All @@ -320,7 +320,7 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
return nil
}
case types.ServiceConditionCompletedSuccessfully:
exited, code, err := s.isServiceCompleted(ctx, containers, dep)
exited, code, err := s.isServiceCompleted(ctx, containers)
if err != nil {
return err
}
Expand Down Expand Up @@ -641,7 +641,7 @@ func (s *composeService) connectContainerToNetwork(ctx context.Context, id strin
return nil
}

func (s *composeService) isServiceHealthy(ctx context.Context, containers Containers, service string, fallbackRunning bool) (bool, error) {
func (s *composeService) isServiceHealthy(ctx context.Context, containers Containers, fallbackRunning bool) (bool, error) {
if len(containers) == 0 {
return false, nil
}
Expand All @@ -650,33 +650,34 @@ func (s *composeService) isServiceHealthy(ctx context.Context, containers Contai
if err != nil {
return false, err
}

if container.State.Status == "exited" {
return false, fmt.Errorf("container %s exited (%d)", container.Name, container.State.ExitCode)
}

if container.Config.Healthcheck == nil && fallbackRunning {
// Container does not define a health check, but we can fall back to "running" state
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)
return false, fmt.Errorf("container %s has no healthcheck configured", container.Name)
}
switch container.State.Health.Status {
case moby.Healthy:
// Continue by checking the next container.
case moby.Unhealthy:
return false, fmt.Errorf("container for service %q is unhealthy", service)
return false, fmt.Errorf("container %s is unhealthy", container.Name)
case moby.Starting:
return false, nil
default:
return false, fmt.Errorf("container for service %q had unexpected health status %q", service, container.State.Health.Status)
return false, fmt.Errorf("container %s had unexpected health status %q", container.Name, container.State.Health.Status)
}
}
return true, nil
}

func (s *composeService) isServiceCompleted(ctx context.Context, containers Containers, dep string) (bool, int, error) {
func (s *composeService) isServiceCompleted(ctx context.Context, containers Containers) (bool, int, error) {
for _, c := range containers {
container, err := s.apiClient().ContainerInspect(ctx, c.ID)
if err != nil {
Expand Down

0 comments on commit 0834430

Please sign in to comment.