Skip to content

fix(cli): start sandbox exec without waiting for piped stdin EOF - #4006

Merged
johntmyers merged 1 commit into
NVIDIA:mainfrom
fede-kamel:fix/cli-exec-stdin-nonblocking
Oct 1, 2026
Merged

johntmyers merged 1 commit into
NVIDIA:mainfrom
fede-kamel:fix/cli-exec-stdin-nonblocking

Conversation

@fede-kamel

Copy link
Copy Markdown
Contributor

Summary

openshell sandbox exec read piped stdin to EOF before it sent the exec request. Under any parent that keeps stdin open (CI runners, supervisors, agent harnesses) the CLI hung forever without the gateway ever seeing the request, and a slow producer delayed the command until EOF. The CLI now waits at most 200 ms for piped stdin to end; small pipes keep the single-request path, and an open pipe starts the command through the streaming RPC with stdin forwarded as it arrives.

Related Issue

Closes #3993.

Changes

  • crates/openshell-cli/src/run.rs: spawn_piped_stdin_reader reads stdin on a detached OS thread and hands chunks over a channel; collect_piped_stdin gathers them until EOF or EXEC_STDIN_UNARY_GRACE (200 ms). Complete input goes into the unary request as before. Open input routes to sandbox_exec_streaming_grpc, which gains a stdin_rest receiver and forwards the collected prefix plus the remainder, closing remote stdin at EOF. The 4 MiB cap applies to prefix plus remainder; the error text is unchanged. The terminal path is untouched.
  • docs/how-it-works/sandboxes/overview.mdx: document the grace period and the </dev/null idiom for commands that need no input.

Testing

  • Unit tests (run::tests::piped_stdin_*): a pipe that closes immediately is sent in one request; a pipe that stays open returns after the grace period with the prefix collected so far and keeps delivering later bytes until EOF; input over the limit is rejected with the sandbox upload hint.
  • cargo test -p openshell-cli (all suites), cargo clippy -p openshell-cli --all-targets -D warnings, cargo fmt --all --check.
  • Manual, before the fix, on a 0.1.2 gateway with the Docker driver: sleep 300 | openshell sandbox exec -n sb -- true hung until killed and produced no ExecSandbox RPC in the gateway log; </dev/null returned in 0.1 s; a pipe closing after 5 s started the command 5 s late. These are the reproduction steps in sandbox exec reads piped stdin to EOF before starting the command; hangs forever when stdin is an open pipe #3993.
  • E2E tests added: not in this PR; the behaviour is covered by the unit tests above and the existing exec e2e coverage.

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • Architecture docs updated (if applicable): not applicable, user-facing docs updated instead.

With a non-terminal stdin, sandbox exec read stdin to EOF before it sent
the exec request. A pipe that never closes (CI runners, supervisors, agent
harnesses) blocked the CLI forever in read(2) without the gateway ever
seeing the request, and a slow producer delayed the command until EOF.

Collect piped stdin on a detached reader thread for at most 200 ms. Input
that reaches EOF within that window still travels in the single request
that older gateways need. If the pipe is still open, start the command
through the streaming RPC and forward the collected prefix plus the rest of
stdin as it arrives, closing remote stdin at EOF. The 4 MiB cap covers the
prefix and the streamed remainder together.

Closes NVIDIA#3993

Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
@copy-pr-bot

copy-pr-bot Bot commented Sep 30, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@fede-kamel

Copy link
Copy Markdown
Contributor Author

I have read the DCO document and I hereby sign the DCO.

@johntmyers johntmyers self-assigned this Oct 1, 2026
@johntmyers johntmyers added the test:e2e Requires end-to-end coverage label Oct 1, 2026
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

Label test:e2e applied, but pull-request/4006 does not exist yet. A maintainer needs to comment /ok to test d250bca506c906e0bca9c32e29ca27d255bebf33 to mirror this PR. Once the mirror exists, re-apply the label or re-run Branch E2E Checks from the Actions tab.

@johntmyers

Copy link
Copy Markdown
Collaborator

/ok to test d250bca

@johntmyers johntmyers left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

gator-agent

PR Review Status

This focused fix is project-valid against #3993, the user-facing documentation is updated, and the independent initial review found no blocking issues.

Blocking findings:

  • No blocking findings remain

Carried findings:

  • None

Non-blocking suggestions:

  • None
Gator metadata
  • Validation: Fixes the reproducible linked CLI hang in a concentrated subsystem.
  • Docs: Fern sandbox execution behavior is updated; navigation is unchanged because no page was added or moved.
  • Checks: Current-head required checks are awaiting the copy-pr mirror and workflow dispatch.
  • E2E: test:e2e applied; authorized /ok to test posted for the current head; Branch E2E is not yet confirmed queued.
  • Head SHA: d250bca506c906e0bca9c32e29ca27d255bebf33
  • Base SHA: 912a077bd641272016fb8b2fd58209f6c7c6f194
  • Merge base SHA: 912a077bd641272016fb8b2fd58209f6c7c6f194
  • Patch ID: e962ee5e74ba782674e05bccde01348171cfa49a
  • Gator payload: 9
  • Review mode: initial
  • Previous reviewed SHA: none
  • Review budget exhausted: no
  • Maintainer decision required: no
  • Next state: gator:in-review

@johntmyers johntmyers added gator:in-review Gator is reviewing or awaiting PR review feedback gator:watch-pipeline Gator is monitoring PR CI/CD status gator:approval-needed Gator completed review; maintainer approval needed and removed gator:in-review Gator is reviewing or awaiting PR review feedback gator:watch-pipeline Gator is monitoring PR CI/CD status labels Oct 1, 2026
@BOT9315

BOT9315 commented Oct 1, 2026

Copy link
Copy Markdown

Note: when running the split flow on 0.1.2, use openshell sandbox exec -n "$NAME" -- </dev/null. Without the redirect, exec can hang when stdin is an open pipe (see #3993, fix in #4006).

@BOT9315

BOT9315 commented Oct 1, 2026

Copy link
Copy Markdown

run the worker command inside the running sandbox

</dev/null avoids the stdin-EOF hang (#3993) on 0.1.2

openshell sandbox exec -n "$NAME" -- </dev/null

@johntmyers
johntmyers added this pull request to the merge queue Oct 1, 2026
@johntmyers johntmyers added gator:merge-ready and removed gator:approval-needed Gator completed review; maintainer approval needed labels Oct 1, 2026
Merged via the queue into NVIDIA:main with commit ffcbe62 Oct 1, 2026
119 of 122 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gator:merge-ready test:e2e Requires end-to-end coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sandbox exec reads piped stdin to EOF before starting the command; hangs forever when stdin is an open pipe

3 participants