Skip to content

fix(rumprun): keep argument boundaries in the guest config - #1174

Open
rahul05ranjan wants to merge 1 commit into
urunc-dev:mainfrom
rahul05ranjan:fix/rumprun-argv-boundaries-in-rc
Open

rahul05ranjan wants to merge 1 commit into
urunc-dev:mainfrom
rahul05ranjan:fix/rumprun-argv-boundaries-in-rc

Conversation

@rahul05ranjan

Copy link
Copy Markdown

Description

urunc hands the container's arguments to a rumprun guest by joining all of argv into one cmdline string (strings.Join(data.CmdLine, " ") in Rumprun.Init). The guest cannot get that back intact: rumprun's config parser splits cmdline on whitespace (lib/librumprun_base/config.c: makeargv → rumprun_parseargs), so an argument that contains a space arrives as two arguments and an empty argument vanishes entirely. redis-server --requirepass 'a b' dies with >>> 'requirepass "a" "b"' / Bad directive or wrong number of arguments, and --logfile '' degrades into a bare --logfile, exactly as reported in #1158.

The rumprun configuration format has a second form made for this: rc takes a bin and an argv array, and the guest copies every array element as its own string with no whitespace processing (config.c: addbin → rre_argv[i] = token2cstr(...), verified in the rumprun sources; doc/config.md specifies both forms). This change emits the command as a one-entry rc list — argv[0] as bin, the rest as the argv array — so argument boundaries survive:

{"rc":[{"bin":"redis-server","argv":["--requirepass","a b","--logfile",""]}],"env":…}

Two notes on the shape:

  • The serialization uses an encoder with HTML escaping off, because the guest's jsmn-based parser keeps string bytes exactly as written and does not decode \uXXXX escapes, so &, < and > must stay raw. This overlaps the open fix(rumprun): do not escape &, < and > in guest config #1101 (its marshalNoEscape); this PR does not depend on it but will conflict textually — happy to rebase once one of the two lands.
  • With rc, the guest no longer sets RUMPRUN_EXEC_CMDLINE, which only affects multibaked multi-program images (it asks the guest to run every remaining baked program after the command; rc entries list exactly the programs to run). urunc runs one container process per guest, so the container images this affects behave identically.
  • An empty CmdLine (not reachable from an OCI spec, which requires at least argv[0]) keeps the old empty cmdline, which is what lets the guest run its first baked program without arguments.

Related issues

How was this tested?

  • Guest-semantics mirror of both sides (Python, stdlib): the intended argv, the strings.Join+whitespace-split result (HEAD: ['redis-server', '--requirepass', 'a', 'b'] and a dropped empty) and the rc-array result (FIX: byte-exact) for all three cases in the issue plus multiple empties.
  • New pkg/unikontainers/unikernels/rumprun_test.go (the package had no rumprun tests): four tests asserting the exact rc serialization, argument-boundary preservation (spaced and empty values round-trip through the JSON), no \u003c-style HTML escaping, the empty-cmdline fallback and that Init keeps CmdLine unjoined.
  • The upstream parser claims were checked against the rumprun sources directly (config.c addbin/token2cstr/handle_cmdline, app-tools/rumprun which still emits cmdline — this change is urunc-side fidelity the host tool does not have).
  • Not run locally: no Go toolchain on this machine, so make lint and the unit suite are left to CI; the runtime check is the repro in Rumprun arguments with a space are split, empty ones are dropped #1158 (redis with --requirepass 'a b' over nerdctl).

LLM usage

GLM (Z.ai, model glm-5.3, via OpenRouter) assisted in analyzing the issue, reading the rumprun parser sources and preparing this change; the diff and the claims above were reviewed against the upstream rumprun code before opening.

Checklist

  • I have read the contribution guide.
  • The linter passes locally (make lint). — no Go toolchain on this machine; the change follows gofmt layout.
  • The e2e tests of at least one tool pass locally (make test_ctr, make test_nerdctl, make test_docker, make test_crictl). — needs a rumprun/solo5 VMM and image, not available here; CI will run the suite once labeled.

The rumprun configuration carried the application command as a single
'cmdline' string, which the guest splits on whitespace (config.c:
makeargv/rumprun_parseargs). An argument that contains a space therefore
reached the application as two arguments and an empty argument vanished,
so 'redis-server --requirepass "a b"' failed with a bare 'a b' split
into 'a' and 'b', and '--logfile ""' lost its value entirely.

The rumprun configuration format has a second form for exactly this:
'rc' takes bin plus an argv array, and the guest copies every array
element as its own string (config.c: addbin), with no whitespace
processing. Emit the command in the rc form, keeping argv[0] as bin and
the rest as the argv array.

The JSON encoder keeps HTML escaping off, because the guest's jsmn
parser keeps string bytes as written and does not decode \uXXXX
escapes; the same helper shape as the open urunc-dev#1101, which this change
does not depend on but will textually overlap - happy to rebase once
one lands.

Fixes urunc-dev#1158

Co-authored-by: rahul05ranjan <11793455+rahul05ranjan@users.noreply.github.com>
Signed-off-by: rahul05ranjan <11793455+rahul05ranjan@users.noreply.github.com>
@netlify

netlify Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for urunc canceled.

Name Link
🔨 Latest commit 54a292a
🔍 Latest deploy log https://app.netlify.com/projects/urunc/deploys/6ae17e1f9edb630df864602a

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rumprun arguments with a space are split, empty ones are dropped

1 participant