Skip to content

fix(exec): honour empty --detach-keys in remote exec#28405

Open
DeveshB-1 wants to merge 1 commit intocontainers:mainfrom
DeveshB-1:fix/remote-exec-detach-keys
Open

fix(exec): honour empty --detach-keys in remote exec#28405
DeveshB-1 wants to merge 1 commit intocontainers:mainfrom
DeveshB-1:fix/remote-exec-detach-keys

Conversation

@DeveshB-1
Copy link
Copy Markdown
Contributor

Fixes #28193

podman --remote exec --detach-keys "" was silently ignoring the empty value and falling back to the default ctrl-p,ctrl-q detach sequence.

Root cause

In pkg/api/handlers/compat/exec.go, the guard was:

if input.DetachKeys != "" {
    libpodConfig.DetachKeys = &input.DetachKeys
}

Go unmarshals both an absent field and "DetachKeys": "" to the same zero value, so an explicit empty string was indistinguishable from absent — and was ignored.

Fix

Read the raw JSON body alongside the typed decode to check whether DetachKeys was explicitly present. Apply the value whenever the key is present, even when empty. Mirrors the fix applied to podman run in v5.8.0.

cc @mheon @baude

@github-actions github-actions bot added the kind/api-change Change to remote API; merits scrutiny label Mar 29, 2026
@DeveshB-1 DeveshB-1 force-pushed the fix/remote-exec-detach-keys branch from bf350c3 to ffb5019 Compare March 29, 2026 18:46
@packit-as-a-service
Copy link
Copy Markdown

[NON-BLOCKING] Packit jobs failed. @containers/packit-build please check. Everyone else, feel free to ignore.

@mheon
Copy link
Copy Markdown
Member

mheon commented Mar 30, 2026

As I commented on the other - quite similar - PR we have open for this issue: this is greatly overcomplicated. Why not just change DetachKeys to a *string and let the JSON parser do the work for us?

@DeveshB-1
Copy link
Copy Markdown
Contributor Author

DeveshB-1 commented Mar 30, 2026

Good call - updated to shadow DetachKeys with a *string in ExecCreateConfig so the JSON decoder handles presence detection natively. nil = field absent, *"" = explicitly disabled. Also added an e2e test to test/e2e/exec_test.go covering --detach-keys="". Thanks for the direction!

Comment thread pkg/api/handlers/compat/exec.go Outdated

input := new(handlers.ExecCreateConfig)
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
if err := json.NewDecoder(r.Body).Decode(input); err != nil {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was the & dropped?

Copy link
Copy Markdown
Contributor Author

@DeveshB-1 DeveshB-1 Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch - accidentally dropped the & when rewriting the decode call. Restored.

Comment thread test/e2e/exec_test.go Outdated
execSession.WaitWithDefaultTimeout()
Expect(execSession).Should(ExitWithError(137, ""))

It("podman exec --detach-keys empty string disables detach", func() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test does nothing. I don't think we have any testing for detach keys because it's difficult to verify in an automated fashion.

Copy link
Copy Markdown
Contributor Author

@DeveshB-1 DeveshB-1 Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, that test was meaningless. Replaced it with a unit test in pkg/api/handlers/exec_create_config_test.go that directly verifies the JSON decoding of DetachKeys as a *string - covering absent field (nil), empty string (*""), and a real value. That's the actual behaviour the fix guarantees.

@DeveshB-1
Copy link
Copy Markdown
Contributor Author

Thanks for the review @mheon, really appreciate the guidance!

@DeveshB-1 DeveshB-1 force-pushed the fix/remote-exec-detach-keys branch 2 times, most recently from b44ddd7 to f0b995e Compare March 30, 2026 04:37
Copy link
Copy Markdown
Member

@Honny1 Honny1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code LGTM, I would like to see some extension of tests. Also would be great to add API tests.

// This is the regression test for the bug where DetachKeys:"" was silently
// ignored because the zero value of string is indistinguishable from absent.
func TestExecCreateConfigDetachKeys(t *testing.T) {
tests := []struct {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I miss the test scenario with an empty body.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok will add it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an empty body ({}) test case - committed in the latest push.

@DeveshB-1
Copy link
Copy Markdown
Contributor Author

Added API tests in test/apiv2/20-containers.at covering both the empty DetachKeys case (disable detach) and a non-empty value, with inspect verification via GET /exec/{id}/json. Also added the empty body {} unit test case as requested.

@DeveshB-1
Copy link
Copy Markdown
Contributor Author

@Honny1 do look into this

@mheon
Copy link
Copy Markdown
Member

mheon commented Mar 30, 2026

Please squash down to 1 commit

@DeveshB-1 DeveshB-1 force-pushed the fix/remote-exec-detach-keys branch from 08a2726 to 8ac0d8b Compare March 30, 2026 15:22
@DeveshB-1
Copy link
Copy Markdown
Contributor Author

Done - squashed to a single commit.

# Explicitly empty DetachKeys disables detach - exec create must accept it.
t POST containers/exec-detach-keys-test/exec \
Cmd='["true"]' \
DetachKeys='' \
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, the last thing I miss is a scenario without DetachKeys.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added - the test now also covers exec create without DetachKeys and verifies the default is non-empty via .DetachKeys~.+.

@DeveshB-1 DeveshB-1 force-pushed the fix/remote-exec-detach-keys branch from 0cd9721 to e218ce7 Compare March 30, 2026 15:35
@DeveshB-1
Copy link
Copy Markdown
Contributor Author

Done @Honny1 - added the no-DetachKeys scenario as well.

Copy link
Copy Markdown
Member

@mheon mheon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment thread test/apiv2/20-containers.at Outdated
201 \
.Id~[0-9a-f]\\{64\\}
eid=$(jq -r '.Id' <<<"$output")
t GET exec/$eid/json 200 .DetachKeys~.+
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  not ok 1195 [20-containers] GET exec/74000e0395b9fcfd953a21e3a0330c5abceafbcb996aa19aba4afb6392d2afc9/json : .DetachKeys
         #  expected: ~ .+
         #    actual: 

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — when DetachKeys is absent from the request, libpodConfig.DetachKeys was left as nil, and libpod's Inspect() returns "" for nil. Now we fall back to runtimeConfig.Engine.DetachKeys explicitly so the system default is stored and returned by inspect.

…efault

Use a *string field for DetachKeys in ExecCreateConfig so the JSON decoder
can distinguish an absent field (nil) from an explicitly-empty one ("").
Previously both mapped to the same empty string, causing DetachKeys:""
to be silently ignored.

When DetachKeys is absent from the request, store the system default from
runtimeConfig.Engine.DetachKeys so that exec inspect returns a meaningful
value rather than an empty string.

Adds unit tests for the JSON decoding and API tests covering all three
scenarios: no DetachKeys, empty DetachKeys, and a non-empty value.

Fixes: containers#28307
Signed-off-by: Devesh B <98201065+DeveshB-1@users.noreply.github.com>
@DeveshB-1 DeveshB-1 force-pushed the fix/remote-exec-detach-keys branch from 2393461 to 2147234 Compare March 30, 2026 16:56
@baude
Copy link
Copy Markdown
Member

baude commented Mar 30, 2026

looks like the api tests are failing still.

@DeveshB-1
Copy link
Copy Markdown
Contributor Author

looks like the api tests are failing still.

Got it will look into it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/api-change Change to remote API; merits scrutiny

Projects

None yet

Development

Successfully merging this pull request may close these issues.

podman --remote exec ignores empty detach keys

4 participants