From 92394aab048d43411d9c0d970380500e80e7c4c8 Mon Sep 17 00:00:00 2001 From: Guillaume Da Silva Date: Fri, 29 May 2026 07:35:29 -0400 Subject: [PATCH 1/5] feat(shell): add --ephemeral flag to spawn a debug pod from service image When --ephemeral is passed, qovery shell creates a new temporary pod using the service's image and env vars instead of connecting to an existing pod. The pod is automatically deleted when the session ends. Depends on: rust-backend feat/ephemeral-shell (new /shell/ephemeral endpoint) --- cmd/shell.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cmd/shell.go b/cmd/shell.go index 16037921..3604fa23 100644 --- a/cmd/shell.go +++ b/cmd/shell.go @@ -52,7 +52,11 @@ var shellCmd = &cobra.Command{ return } - pkg.ExecShell(shellRequest, "/shell/exec") + endpoint := "/shell/exec" + if ephemeral { + endpoint = "/shell/ephemeral" + } + pkg.ExecShell(shellRequest, endpoint) }, } @@ -60,6 +64,7 @@ var ( command []string podName string podContainerName string + ephemeral bool ) func shellRequestWithContextFlags() (*pkg.ShellRequest, error) { @@ -348,10 +353,12 @@ func init() { shellCmd.Flags().StringVarP(&serviceName, "service", "", "", "Service Name") shellCmd.Flags().StringVarP(&podName, "pod", "p", "", "pod name where to exec into") shellCmd.Flags().StringVar(&podContainerName, "container", "", "container name inside the pod") + shellCmd.Flags().BoolVar(&ephemeral, "ephemeral", false, "spawn a new ephemeral pod using the service image and env vars instead of connecting to an existing pod") shellCmd.Example = "qovery shell\n" + "qovery shell \n" + "qovery shell --organization --project --environment --service \n" + - "qovery shell --organization --project --environment --service --pod --container --command " + "qovery shell --organization --project --environment --service --pod --container --command \n" + + "qovery shell --ephemeral --organization --project --environment --service " rootCmd.AddCommand(shellCmd) } From b0fe471bf474b934fdf87d2b29be36469f940d4f Mon Sep 17 00:00:00 2001 From: Guillaume Da Silva Date: Fri, 29 May 2026 08:54:57 -0400 Subject: [PATCH 2/5] feat(shell): add --mode flag to --ephemeral (clone or debug) --- cmd/shell.go | 13 ++++++++++--- pkg/shell.go | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/cmd/shell.go b/cmd/shell.go index 3604fa23..92d51c2f 100644 --- a/cmd/shell.go +++ b/cmd/shell.go @@ -54,6 +54,11 @@ var shellCmd = &cobra.Command{ endpoint := "/shell/exec" if ephemeral { + if ephemeralMode != "clone" && ephemeralMode != "debug" { + utils.PrintlnError(errors.New("--mode must be 'clone' or 'debug'")) + return + } + shellRequest.EphemeralMode = ephemeralMode endpoint = "/shell/ephemeral" } pkg.ExecShell(shellRequest, endpoint) @@ -65,6 +70,7 @@ var ( podName string podContainerName string ephemeral bool + ephemeralMode string ) func shellRequestWithContextFlags() (*pkg.ShellRequest, error) { @@ -353,12 +359,13 @@ func init() { shellCmd.Flags().StringVarP(&serviceName, "service", "", "", "Service Name") shellCmd.Flags().StringVarP(&podName, "pod", "p", "", "pod name where to exec into") shellCmd.Flags().StringVar(&podContainerName, "container", "", "container name inside the pod") - shellCmd.Flags().BoolVar(&ephemeral, "ephemeral", false, "spawn a new ephemeral pod using the service image and env vars instead of connecting to an existing pod") + shellCmd.Flags().BoolVar(&ephemeral, "ephemeral", false, "spawn an ephemeral shell instead of connecting to an existing pod") + shellCmd.Flags().StringVar(&ephemeralMode, "mode", "clone", "ephemeral mode: 'clone' (new isolated pod, Heroku-style) or 'debug' (ephemeral container injected into existing pod, kubectl-debug style)") shellCmd.Example = "qovery shell\n" + "qovery shell \n" + "qovery shell --organization --project --environment --service \n" + - "qovery shell --organization --project --environment --service --pod --container --command \n" + - "qovery shell --ephemeral --organization --project --environment --service " + "qovery shell --ephemeral --mode clone --organization --project --environment --service \n" + + "qovery shell --ephemeral --mode debug --organization --project --environment --service " rootCmd.AddCommand(shellCmd) } diff --git a/pkg/shell.go b/pkg/shell.go index 239938bf..c09f456c 100644 --- a/pkg/shell.go +++ b/pkg/shell.go @@ -46,6 +46,7 @@ type ShellRequest struct { Command []string `url:"command"` TtyWidth uint16 `url:"tty_width"` TtyHeight uint16 `url:"tty_height"` + EphemeralMode string `url:"mode,omitempty"` } func (s *ShellRequest) SetTtySize(width uint16, height uint16) { From 7ea3aa2f4574988db2b4f498aa8716fbe428beb3 Mon Sep 17 00:00:00 2001 From: Guillaume Da Silva Date: Fri, 29 May 2026 09:12:23 -0400 Subject: [PATCH 3/5] feat(shell): warn when --mode is set without --ephemeral --- cmd/shell.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/shell.go b/cmd/shell.go index 92d51c2f..87bea919 100644 --- a/cmd/shell.go +++ b/cmd/shell.go @@ -60,6 +60,8 @@ var shellCmd = &cobra.Command{ } shellRequest.EphemeralMode = ephemeralMode endpoint = "/shell/ephemeral" + } else if cmd.Flags().Changed("mode") { + utils.PrintlnInfo("--mode has no effect without --ephemeral; ignoring it.") } pkg.ExecShell(shellRequest, endpoint) }, From 517ac4ef5087000b740eb95681f9d7d2407ab108 Mon Sep 17 00:00:00 2001 From: Guillaume Da Silva Date: Tue, 2 Jun 2026 11:53:12 +0200 Subject: [PATCH 4/5] feat(shell): add --cpu/--memory resource overrides for ephemeral clone pods --- cmd/shell.go | 7 +++++++ pkg/shell.go | 2 ++ 2 files changed, 9 insertions(+) diff --git a/cmd/shell.go b/cmd/shell.go index 87bea919..aa55ca20 100644 --- a/cmd/shell.go +++ b/cmd/shell.go @@ -59,6 +59,8 @@ var shellCmd = &cobra.Command{ return } shellRequest.EphemeralMode = ephemeralMode + shellRequest.CpuOverride = cpuOverride + shellRequest.MemoryOverride = memoryOverride endpoint = "/shell/ephemeral" } else if cmd.Flags().Changed("mode") { utils.PrintlnInfo("--mode has no effect without --ephemeral; ignoring it.") @@ -73,6 +75,8 @@ var ( podContainerName string ephemeral bool ephemeralMode string + cpuOverride string + memoryOverride string ) func shellRequestWithContextFlags() (*pkg.ShellRequest, error) { @@ -363,10 +367,13 @@ func init() { shellCmd.Flags().StringVar(&podContainerName, "container", "", "container name inside the pod") shellCmd.Flags().BoolVar(&ephemeral, "ephemeral", false, "spawn an ephemeral shell instead of connecting to an existing pod") shellCmd.Flags().StringVar(&ephemeralMode, "mode", "clone", "ephemeral mode: 'clone' (new isolated pod, Heroku-style) or 'debug' (ephemeral container injected into existing pod, kubectl-debug style)") + shellCmd.Flags().StringVar(&cpuOverride, "cpu", "", "override CPU request+limit for the ephemeral pod (e.g. '500m', '2')") + shellCmd.Flags().StringVar(&memoryOverride, "memory", "", "override memory request+limit for the ephemeral pod (e.g. '512Mi', '2Gi')") shellCmd.Example = "qovery shell\n" + "qovery shell \n" + "qovery shell --organization --project --environment --service \n" + "qovery shell --ephemeral --mode clone --organization --project --environment --service \n" + + "qovery shell --ephemeral --mode clone --memory 2Gi --organization --project --environment --service \n" + "qovery shell --ephemeral --mode debug --organization --project --environment --service " rootCmd.AddCommand(shellCmd) diff --git a/pkg/shell.go b/pkg/shell.go index c09f456c..63f3af39 100644 --- a/pkg/shell.go +++ b/pkg/shell.go @@ -47,6 +47,8 @@ type ShellRequest struct { TtyWidth uint16 `url:"tty_width"` TtyHeight uint16 `url:"tty_height"` EphemeralMode string `url:"mode,omitempty"` + CpuOverride string `url:"cpu_override,omitempty"` + MemoryOverride string `url:"memory_override,omitempty"` } func (s *ShellRequest) SetTtySize(width uint16, height uint16) { From 6b6163dd93777df244bd1647c8038a1e8745bce2 Mon Sep 17 00:00:00 2001 From: Guillaume Da Silva Date: Wed, 3 Jun 2026 14:01:03 +0200 Subject: [PATCH 5/5] fix(shell): warn when --cpu/--memory are passed in ephemeral debug mode Resource overrides only apply to clone mode; debug injects a container into an existing pod and ignores them. Warn instead of silently dropping. --- cmd/shell.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/shell.go b/cmd/shell.go index aa55ca20..d5cbc9a1 100644 --- a/cmd/shell.go +++ b/cmd/shell.go @@ -58,6 +58,9 @@ var shellCmd = &cobra.Command{ utils.PrintlnError(errors.New("--mode must be 'clone' or 'debug'")) return } + if ephemeralMode == "debug" && (cpuOverride != "" || memoryOverride != "") { + utils.PrintlnInfo("--cpu/--memory only apply to --mode clone; ignoring them in debug mode.") + } shellRequest.EphemeralMode = ephemeralMode shellRequest.CpuOverride = cpuOverride shellRequest.MemoryOverride = memoryOverride