fail start if depependency is missing

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2023-10-19 09:29:32 +02:00
parent fd8ab2f7ac
commit 1ffa194e12
No known key found for this signature in database
GPG Key ID: 9858809D6F8F6E7E
4 changed files with 13 additions and 6 deletions

View File

@ -306,7 +306,7 @@ func containerReasonEvents(containers Containers, eventFunc func(string, string)
const ServiceConditionRunningOrHealthy = "running_or_healthy" const ServiceConditionRunningOrHealthy = "running_or_healthy"
//nolint:gocyclo //nolint:gocyclo
func (s *composeService) waitDependencies(ctx context.Context, project *types.Project, dependencies types.DependsOnConfig, containers Containers) error { func (s *composeService) waitDependencies(ctx context.Context, project *types.Project, dependant string, dependencies types.DependsOnConfig, containers Containers) error {
eg, _ := errgroup.WithContext(ctx) eg, _ := errgroup.WithContext(ctx)
w := progress.ContextWriter(ctx) w := progress.ContextWriter(ctx)
for dep, config := range dependencies { for dep, config := range dependencies {
@ -318,6 +318,13 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
waitingFor := containers.filter(isService(dep)) waitingFor := containers.filter(isService(dep))
w.Events(containerEvents(waitingFor, progress.Waiting)) w.Events(containerEvents(waitingFor, progress.Waiting))
if len(waitingFor) == 0 {
if config.Required {
return fmt.Errorf("%s is missing dependency %s", dependant, dep)
}
logrus.Warnf("%s is missing dependency %s", dependant, dep)
continue
}
dep, config := dep, config dep, config := dep, config
eg.Go(func() error { eg.Go(func() error {
@ -717,7 +724,7 @@ func (s *composeService) startService(ctx context.Context, project *types.Projec
return nil return nil
} }
err := s.waitDependencies(ctx, project, service.DependsOn, containers) err := s.waitDependencies(ctx, project, service.Name, service.DependsOn, containers)
if err != nil { if err != nil {
return err return err
} }

View File

@ -229,7 +229,7 @@ func TestWaitDependencies(t *testing.T) {
"db": {Condition: ServiceConditionRunningOrHealthy}, "db": {Condition: ServiceConditionRunningOrHealthy},
"redis": {Condition: ServiceConditionRunningOrHealthy}, "redis": {Condition: ServiceConditionRunningOrHealthy},
} }
assert.NilError(t, tested.waitDependencies(context.Background(), &project, dependencies, nil)) assert.NilError(t, tested.waitDependencies(context.Background(), &project, "", dependencies, nil))
}) })
t.Run("should skip dependencies with condition service_started", func(t *testing.T) { t.Run("should skip dependencies with condition service_started", func(t *testing.T) {
dbService := types.ServiceConfig{Name: "db", Scale: 1} dbService := types.ServiceConfig{Name: "db", Scale: 1}
@ -239,6 +239,6 @@ func TestWaitDependencies(t *testing.T) {
"db": {Condition: types.ServiceConditionStarted, Required: true}, "db": {Condition: types.ServiceConditionStarted, Required: true},
"redis": {Condition: types.ServiceConditionStarted, Required: true}, "redis": {Condition: types.ServiceConditionStarted, Required: true},
} }
assert.NilError(t, tested.waitDependencies(context.Background(), &project, dependencies, nil)) assert.NilError(t, tested.waitDependencies(context.Background(), &project, "", dependencies, nil))
}) })
} }

View File

@ -96,7 +96,7 @@ func (s *composeService) prepareRun(ctx context.Context, project *types.Project,
updateServices(&service, observedState) updateServices(&service, observedState)
if !opts.NoDeps { if !opts.NoDeps {
if err := s.waitDependencies(ctx, project, service.DependsOn, observedState); err != nil { if err := s.waitDependencies(ctx, project, service.Name, service.DependsOn, observedState); err != nil {
return "", err return "", err
} }
} }

View File

@ -117,7 +117,7 @@ func (s *composeService) start(ctx context.Context, projectName string, options
defer cancel() defer cancel()
} }
err = s.waitDependencies(ctx, project, depends, containers) err = s.waitDependencies(ctx, project, project.Name, depends, containers)
if err != nil { if err != nil {
if ctx.Err() == context.DeadlineExceeded { if ctx.Err() == context.DeadlineExceeded {
return fmt.Errorf("application not healthy after %s", options.WaitTimeout) return fmt.Errorf("application not healthy after %s", options.WaitTimeout)