From 1bfd4cb95bcfdc210cfc0b1a01fc4a93ace4f29a Mon Sep 17 00:00:00 2001 From: Mayowa Fajobi <127399119+MayorFaj@users.noreply.github.com> Date: Tue, 3 Feb 2026 11:49:28 +0000 Subject: [PATCH] Fix healthcheck argument with spaces split in Docker API (#27818) Fixes: #26519 Signed-off-by: MayorFaj --- pkg/api/handlers/compat/containers_create.go | 13 +++++----- pkg/specgenutil/specgen.go | 5 +++- test/apiv2/20-containers.at | 25 ++++++++++++++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go index 4855b56b66..b6ad88104c 100644 --- a/pkg/api/handlers/compat/containers_create.go +++ b/pkg/api/handlers/compat/containers_create.go @@ -604,14 +604,13 @@ func cliOpts(cc handlers.CreateContainerConfig, rtc *config.Config) (*entities.C cliOpts.OOMKillDisable = *cc.HostConfig.OomKillDisable } if cc.Config.Healthcheck != nil { - finCmd := "" - for _, str := range cc.Config.Healthcheck.Test { - finCmd = finCmd + str + " " + // Encode healthcheck test as JSON to preserve arguments with spaces. + // MakeHealthCheckFromCli will unmarshal this back to the original array. + cmdJSON, err := json.Marshal(cc.Config.Healthcheck.Test) + if err != nil { + return nil, nil, err } - if len(finCmd) > 1 { - finCmd = finCmd[:len(finCmd)-1] - } - cliOpts.HealthCmd = finCmd + cliOpts.HealthCmd = string(cmdJSON) if cc.Config.Healthcheck.Interval > 0 { cliOpts.HealthInterval = cc.Config.Healthcheck.Interval.String() } diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go index 2456a9555e..30973f9105 100644 --- a/pkg/specgenutil/specgen.go +++ b/pkg/specgenutil/specgen.go @@ -985,7 +985,10 @@ func MakeHealthCheckFromCli(inCmd, interval string, retries uint, timeout, start var concat string if strings.ToUpper(cmdArr[0]) == define.HealthConfigTestCmd || strings.ToUpper(cmdArr[0]) == define.HealthConfigTestNone { // this is for compat, we are already split properly for most compat cases - cmdArr = strings.Fields(inCmd) + // Only re-split if the input was not already a JSON array (isArr == false); otherwise preserve the unmarshaled array structure + if !isArr { + cmdArr = strings.Fields(inCmd) + } } else if strings.ToUpper(cmdArr[0]) != define.HealthConfigTestCmdShell { // this is for podman side of things, won't contain the keywords if isArr && len(cmdArr) > 1 { // an array of consecutive commands cmdArr = append([]string{define.HealthConfigTestCmd}, cmdArr...) diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at index c9a0ea5a10..80743a1349 100644 --- a/test/apiv2/20-containers.at +++ b/test/apiv2/20-containers.at @@ -594,6 +594,31 @@ t GET containers/$cid/json 200 \ .Config.Healthcheck.Timeout=30000000000 \ .Config.Healthcheck.Retries=3 +t DELETE containers/$cid?v=true 204 + +# Test Compat Create with healthcheck preserving arguments with spaces +HEALTHCHECK_TMPD=$(mktemp -d podman-apiv2-test.healthcheck.XXXXXXXX) +cat >$HEALTHCHECK_TMPD/create.json <