From ff65973eae8d7ab5767cb9bfd2932457c1cbcc47 Mon Sep 17 00:00:00 2001 From: Cyber Eclipse <143217084+CyberEclipses@users.noreply.github.com> Date: Thu, 6 Aug 2026 22:07:05 +0000 Subject: [PATCH] fix: allow detach during compose up startup wait Signed-off-by: Cyber Eclipse <143217084+CyberEclipses@users.noreply.github.com> --- pkg/compose/up.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/pkg/compose/up.go b/pkg/compose/up.go index b2bcb3f7dbb..1018968ebe0 100644 --- a/pkg/compose/up.go +++ b/pkg/compose/up.go @@ -111,8 +111,20 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options globalCtx, cancel := context.WithCancel(ctx) defer cancel() + // startCtx keeps service startup isolated from parent cancellation, + // while still allowing the interactive detach action to interrupt + // startup/wait and return control to the user. + startCtx, cancelStart := context.WithCancel(context.WithoutCancel(ctx)) + defer cancelStart() + + var isDetached atomic.Bool + if navigationMenu != nil { - navigationMenu.EnableDetach(cancel) + navigationMenu.EnableDetach(func() { + isDetached.Store(true) + cancelStart() + cancel() + }) } var ( @@ -283,8 +295,12 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options }) // We use the parent context without cancellation as we manage sigterm to stop the stack - err = s.start(context.WithoutCancel(ctx), project.Name, options.Start, printer.HandleEvent) + err = s.start(startCtx, project.Name, options.Start, printer.HandleEvent) if err != nil && !isTerminated.Load() { // Ignore error if the process is terminated + if isDetached.Load() && errors.Is(err, context.Canceled) { + return nil + } + cancel() _ = eg.Wait() return err