From ce27dba52e7ab5e877372d25a223b642cee7569b Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Mon, 23 Sep 2024 16:05:53 +0200 Subject: [PATCH 1/3] wait for dependent service up to delay set by --wait-timeout Signed-off-by: Nicolas De Loof --- pkg/compose/convergence.go | 17 +++++++++++++---- pkg/compose/convergence_test.go | 4 ++-- pkg/compose/run.go | 2 +- pkg/compose/start.go | 4 ++-- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/pkg/compose/convergence.go b/pkg/compose/convergence.go index 5ad3c94b1f1..4f90cda99de 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/convergence.go @@ -364,7 +364,12 @@ func containerReasonEvents(containers Containers, eventFunc func(string, string) const ServiceConditionRunningOrHealthy = "running_or_healthy" //nolint:gocyclo -func (s *composeService) waitDependencies(ctx context.Context, project *types.Project, dependant string, dependencies types.DependsOnConfig, containers Containers) error { +func (s *composeService) waitDependencies(ctx context.Context, project *types.Project, dependant string, dependencies types.DependsOnConfig, containers Containers, timeout time.Duration) error { + if timeout > 0 { + withTimeout, cancelFunc := context.WithTimeout(ctx, timeout) + defer cancelFunc() + ctx = withTimeout + } eg, _ := errgroup.WithContext(ctx) w := progress.ContextWriter(ctx) for dep, config := range dependencies { @@ -454,7 +459,11 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr } }) } - return eg.Wait() + err := eg.Wait() + if errors.Is(err, context.DeadlineExceeded) { + return fmt.Errorf("timeout waiting for dependencies") + } + return err } func shouldWaitForDependency(serviceName string, dependencyConfig types.ServiceDependency, project *types.Project) (bool, error) { @@ -760,12 +769,12 @@ func (s *composeService) isServiceCompleted(ctx context.Context, containers Cont return false, 0, nil } -func (s *composeService) startService(ctx context.Context, project *types.Project, service types.ServiceConfig, containers Containers) error { +func (s *composeService) startService(ctx context.Context, project *types.Project, service types.ServiceConfig, containers Containers, timeout time.Duration) error { if service.Deploy != nil && service.Deploy.Replicas != nil && *service.Deploy.Replicas == 0 { return nil } - err := s.waitDependencies(ctx, project, service.Name, service.DependsOn, containers) + err := s.waitDependencies(ctx, project, service.Name, service.DependsOn, containers, timeout) if err != nil { return err } diff --git a/pkg/compose/convergence_test.go b/pkg/compose/convergence_test.go index e25ccd9f64e..dc981fdaffb 100644 --- a/pkg/compose/convergence_test.go +++ b/pkg/compose/convergence_test.go @@ -239,7 +239,7 @@ func TestWaitDependencies(t *testing.T) { "db": {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, 0)) }) t.Run("should skip dependencies with condition service_started", func(t *testing.T) { dbService := types.ServiceConfig{Name: "db", Scale: intPtr(1)} @@ -252,7 +252,7 @@ func TestWaitDependencies(t *testing.T) { "db": {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, 0)) }) } diff --git a/pkg/compose/run.go b/pkg/compose/run.go index cdafb4b8aff..1bd769dbb61 100644 --- a/pkg/compose/run.go +++ b/pkg/compose/run.go @@ -93,7 +93,7 @@ func (s *composeService) prepareRun(ctx context.Context, project *types.Project, } if !opts.NoDeps { - if err := s.waitDependencies(ctx, project, service.Name, service.DependsOn, observedState); err != nil { + if err := s.waitDependencies(ctx, project, service.Name, service.DependsOn, observedState, 0); err != nil { return "", err } } diff --git a/pkg/compose/start.go b/pkg/compose/start.go index 7caeb305775..b5fcceebfda 100644 --- a/pkg/compose/start.go +++ b/pkg/compose/start.go @@ -129,7 +129,7 @@ func (s *composeService) start(ctx context.Context, projectName string, options return err } - return s.startService(ctx, project, service, containers) + return s.startService(ctx, project, service, containers, options.WaitTimeout) }) if err != nil { return err @@ -149,7 +149,7 @@ func (s *composeService) start(ctx context.Context, projectName string, options defer cancel() } - err = s.waitDependencies(ctx, project, project.Name, depends, containers) + err = s.waitDependencies(ctx, project, project.Name, depends, containers, 0) if err != nil { if errors.Is(ctx.Err(), context.DeadlineExceeded) { return fmt.Errorf("application not healthy after %s", options.WaitTimeout) From 34b18194f7e9efa1ac8c0e67c554c46b61bf5690 Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Mon, 23 Sep 2024 09:48:07 +0200 Subject: [PATCH 2/3] check secret source exists, as bind mount would create target as a folder otherwise Signed-off-by: Nicolas De Loof --- pkg/compose/create.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/compose/create.go b/pkg/compose/create.go index c4d1734fa5f..f4178d6af7b 100644 --- a/pkg/compose/create.go +++ b/pkg/compose/create.go @@ -1003,11 +1003,18 @@ func buildContainerSecretMounts(p types.Project, s types.ServiceConfig) ([]mount continue } + if _, err := os.Stat(definedSecret.File); os.IsNotExist(err) { + logrus.Warnf("secret file %s does not exist", definedSecret.Name) + } + mnt, err := buildMount(p, types.ServiceVolumeConfig{ Type: types.VolumeTypeBind, Source: definedSecret.File, Target: target, ReadOnly: true, + Bind: &types.ServiceVolumeBind{ + CreateHostPath: false, + }, }) if err != nil { return nil, err From 8b9fe89842701c290cbbeddf1b4e9d538ffe9f85 Mon Sep 17 00:00:00 2001 From: Joana Hrotko Date: Tue, 24 Sep 2024 12:17:15 +0100 Subject: [PATCH 3/3] After container restart register printer consumer Signed-off-by: Joana Hrotko --- pkg/compose/printer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/compose/printer.go b/pkg/compose/printer.go index fba8801a152..9f382f87db6 100644 --- a/pkg/compose/printer.go +++ b/pkg/compose/printer.go @@ -98,7 +98,7 @@ func (p *printer) Run(cascade api.Cascade, exitCodeFrom string, stopFn func() er case api.UserCancel: aborting = true case api.ContainerEventAttach: - if _, ok := containers[id]; ok { + if attached, ok := containers[id]; ok && attached { continue } containers[id] = true