Skip to content

fix(cli): backpressure sandbox uploads - #4448

Merged
johntmyers merged 6 commits into
NVIDIA:mainfrom
shiju-nv:fix/4430-upload-backpressure
Oct 13, 2026
Merged

johntmyers merged 6 commits into
NVIDIA:mainfrom
shiju-nv:fix/4430-upload-backpressure

Conversation

@shiju-nv

@shiju-nv shiju-nv commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Large sandbox upload transfers can outrun tar extraction and terminate with exit status 74 when queued stdin reaches 4 MiB. Stream built-in uploads with consumption credit so slow extraction makes the CLI wait while memory remains bounded.

This revision replaces the earlier framed protocol with SSH's own streams. It removes the frame codec, SHA-256 digests, the CLI sha2 dependency and the supervisor upload state machine, about 39% of the production code, while keeping the same credit window and failure behavior.

Related Issue

Closes #4430.

Changes

  • Add the versioned openshell-upload-v1 SSH subsystem. The CLI sends one JSON plan line, the raw tar stream and EOF. The supervisor's stdout carries only cumulative totals of bytes written to extraction stdin, and the CLI keeps at most 1 MiB beyond the last total outstanding. Extraction output arrives as stderr and the SSH exit status is the result; success requires exit status 0 and a final total equal to the bytes sent. No russh change is required.
  • Start extraction through the ordinary exec path, keeping the existing tar producer, destination checks, boundary execution and login-shell selection. Reject malformed plans, credit violations, extended data and EOF before the plan with exit status 74, and terminate the extractor on rejection, channel close or disconnect.
  • Keep cancellation active through setup, transfer and retry delays, and terminate cancelled destination probes. Stop SSH before closing stdin when the archive fails, so EOF never marks a truncated archive complete.
  • Keep each upload in the ssh process the CLI spawns. Sandbox ssh commands already disable connection sharing (fix(cli): disable ssh connection sharing for sandbox sessions #4157); uploads also override ForkAfterAuthentication, as forwards do, so the ssh exit status reports extraction. Like forwards, this needs OpenSSH 8.7 or later.
  • Require updated CLI and supervisor support before sending archive data. Older supervisors produce an upgrade error without an unpaced fallback. The general 4 MiB stdin guard, ordinary exec stdin and SFTP behavior remain unchanged.
  • Add credit-stall/resume, rejection, extractor-failure, output-isolation, compatibility and cancellation tests. Add the Podman E2E regression to its selected targets.
  • Document the upgrade requirement and partial-destination behavior. Interrupted extraction can leave partial files; uploads do not add atomic replacement or rollback.

Testing

  • Checks appropriate to the affected code and behavior pass.
  • Unit tests added/updated (if applicable).
  • E2E tests added/updated (if applicable).

Formatting, scoped Clippy with warnings denied, and the focused openshell-core, openshell-cli and openshell-supervisor-process library tests pass on the merged head (82 CLI, 2 core, 65 supervisor). Mutations that remove CLI credit gating, the supervisor credit check or the final total, route extractor stdout into the credit stream, or send EOF after a failed archive each fail a focused test.

Hosted CI passed on 3aeda041a, including the Podman upload_backpressure E2E (large_upload_preserves_content_and_metadata_outside_workdir). Later commits change only ssh arguments, compile-time checks, diagnostics and tests; CI for the current head covers them.

Not covered by tests: the caller-side order that kills ssh before stdin closes, a rejection after the result is reported, and the supervisor's 5 s drain timeout.

Checklist

  • Follows Conventional Commits.
  • Commits are signed off (DCO).
  • Architecture docs updated (if applicable).

Stream archive uploads over a bounded SSH subsystem whose credit follows extraction stdin progress. Preserve the existing input budget and tar destination semantics, validate completion, and clean up cancelled transfers. Add protocol, lifecycle, and large-upload regression coverage without changing russh.

Signed-off-by: Shiju <shiju@nvidia.com>
Keep cancellation active through upload setup and retry delays, and
terminate cancelled SSH probes. Preserve protocol failures through output
completion and report captured diagnostics on early extraction failure.
Remove redundant upload validation and extend the affected regressions.

Signed-off-by: Shiju <shiju@nvidia.com>
@johntmyers johntmyers added the test:e2e Requires end-to-end coverage label Oct 12, 2026
@github-actions

Copy link
Copy Markdown

Label test:e2e applied for 89fb703. Open the existing run and click Re-run all jobs to execute with the label set. The run will execute the standard E2E suite after building the required gateway, sandbox, and supervisor images once. The matching required CI gate status on this PR will flip green automatically once the run finishes.

@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

PR Review Status

The initial review found no blocking findings in the credited upload protocol, CLI cancellation and failure handling, supervisor integration, or regression coverage. The published upload docs explain the upgrade requirement and partial destinations after interruption.

@shiju-nv, I checked your reproduction and application-layer credit explanation on #4430 against the patch: the upload window follows boundary stdin consumption while the existing input guard remains in place.

Blocking findings: None.
Carried findings: None.
Non-blocking suggestions: None.

Gator metadata
  • Validation: Implements accepted issue bug: sandbox upload fails with exit status 74 since 0.1.3 (4 MiB pending-stdin bound terminates tar extract) #4430; concentrated upload fix by a verified repository maintainer.
  • Docs: Fern sandbox overview and public CLI skill updated; existing navigation is sufficient.
  • Checks: DCO, Helm Lint, and Trivy Changes pass; Branch Checks remain pending on this head.
  • E2E: test:e2e applied; E2E Label Help requires rerunning Branch E2E Checks run 38314119207.
  • Head SHA: 89fb703fb86a23d0501f642da206ae36b3c6b863
  • Base SHA: 3495c8e92af8947046f4f938f929bfb7057eb455
  • Merge base SHA: 749d09e34459d86d402057f1c9564247ef3cc74e
  • Patch ID: 753593770561a5da1bc66f81d1169e29fbf2fd85
  • Gator payload: 12
  • Review mode: initial
  • Previous reviewed SHA: none
  • Review budget exhausted: no
  • Maintainer decision required: no
  • Test dispatch: Authorized rerun accepted and confirmed queued for the current head after the narrow sandbox policy allowance was approved and loaded.
  • Next state: gator:watch-pipeline

@johntmyers johntmyers added gator:watch-pipeline Gator is monitoring PR CI/CD status gator:approval-needed Gator completed review; maintainer approval needed and removed gator:watch-pipeline Gator is monitoring PR CI/CD status labels Oct 12, 2026
Replace the framed upload protocol with SSH's own streams. The client
sends one JSON plan line, the raw archive and EOF. The supervisor's
stdout carries only cumulative totals of bytes written to extraction
stdin, extraction output goes to stderr, and the exit status reports
the result. Extraction starts inline through the ordinary exec path.

This removes the frame codec, SHA-256 digests, the CLI sha2 dependency
and the supervisor upload state machine while keeping the 1 MiB credit
window, the 4 MiB input guard, cancellation and error reporting. A
failed archive now stops SSH before closing stdin, so EOF never marks a
truncated archive complete.

Signed-off-by: Shiju <shiju@nvidia.com>
@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

PR Review Status

The follow-up review found no blocking regressions in the change from custom upload frames to credited SSH streams. I checked bounded plan parsing, consumption-based credit, extraction output isolation, final byte totals and exit status, cancellation, and the updated regression coverage.

Blocking findings: None.
Carried findings: None.

Required Branch Checks, Helm Lint, Trivy Changes, and DCO pass on this head. The required E2E suite is running; Gator will inspect its results next cycle.

Gator metadata
  • Validation: Continues the accepted upload-backpressure fix for bug: sandbox upload fails with exit status 74 since 0.1.3 (4 MiB pending-stdin bound terminates tar extract) #4430 within the existing CLI and supervisor subsystems.
  • Docs: Published sandbox overview and CLI skill remain consistent with the upgrade requirement and partial-destination behavior; crate README explains the simplified protocol.
  • Checks: Current-head Branch Checks, Helm Lint, Trivy Changes, and DCO are green; E2E is pending.
  • E2E: test:e2e remains applied; current-head Branch E2E Checks run 38318089210 is in progress with runtime suites started. No additional dispatch is needed.
  • Head SHA: 3aeda041ac67d077364a909c4f28bfa8f3084246
  • Base SHA: 3495c8e92af8947046f4f938f929bfb7057eb455
  • Merge base SHA: 749d09e34459d86d402057f1c9564247ef3cc74e
  • Patch ID: 150d9acdc9003aba65c701d70350a69e85119bc4
  • Gator payload: 12
  • Review mode: follow_up
  • Previous reviewed SHA: 89fb703fb86a23d0501f642da206ae36b3c6b863
  • Review budget exhausted: no
  • Maintainer decision required: no
  • Next state: gator:watch-pipeline

@johntmyers johntmyers added gator:watch-pipeline Gator is monitoring PR CI/CD status gator:approval-needed Gator completed review; maintainer approval needed and removed gator:approval-needed Gator completed review; maintainer approval needed gator:watch-pipeline Gator is monitoring PR CI/CD status labels Oct 12, 2026
- Apply the forward multiplexing overrides to the upload ssh command, so
  a user ControlMaster cannot carry an upload over another session's
  master connection.
- Kill ssh before closing its stdin when a transfer fails locally, and
  include ssh stderr in transport errors.
- Share ACK_INTERVAL_BYTES from core. Assert at compile time that CLI
  chunks fit the credit left after an ack and that the window stays
  below the supervisor's pending-input guard.
- Log the real reason when the supervisor rejects an upload.
- Test that a single-packet upload reports its final total.

Signed-off-by: Shiju <shiju@nvidia.com>
@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

Blocked

The latest head has merge conflicts with main, so Gator cannot continue the follow-up review. Protobuf Compatibility also failed; its annotation reports exit code 1, but the sandbox could not access the log host to determine the cause. Other Branch Checks are still running, and current-head E2E is queued.

Action required: @shiju-nv, resolve the merge conflicts and push an updated head. Please also inspect the Protobuf Compatibility job and address any PR-caused failure.

Gator metadata
  • Head SHA: be78f0883249708d72459522c117bd1899f8beea
  • Base SHA: 3495c8e92af8947046f4f938f929bfb7057eb455
  • Merge base SHA: 749d09e34459d86d402057f1c9564247ef3cc74e
  • Patch ID: 0e42549e256eb0de59886a535bbf3216b93a8aa4
  • Gator payload: 12
  • Review mode: follow_up; deferred for merge conflicts, no code-review conclusion for this head.
  • Previous reviewed SHA: 3aeda041ac67d077364a909c4f28bfa8f3084246
  • Carried findings: None.
  • E2E: test:e2e applied; current-head Branch E2E Checks run 38361740834 is queued. No additional dispatch needed.
  • Next state: gator:blocked
  • Blocked reason: merge_conflicts

…kpressure

Signed-off-by: Shiju <shiju@nvidia.com>

# Conflicts:
#	crates/openshell-cli/src/ssh.rs
@johntmyers johntmyers added gator:blocked Gator is blocked by process or repository gates and removed gator:approval-needed Gator completed review; maintainer approval needed labels Oct 13, 2026
@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

PR Review Status

The follow-up review found no blocking regressions in the upload SSH connection ownership, cancellation cleanup, shared credit cadence, or merge integration. The added test checks that uploads open the subsystem without a TTY.

@shiju-nv, I checked the updated head: the merge conflicts are resolved and Protobuf Compatibility now passes. Branch Checks, Helm Lint, Trivy Changes, and DCO also pass; the required E2E suite is running.

Blocking findings: None.
Carried findings: None.

Gator metadata
  • Validation: Continues accepted issue bug: sandbox upload fails with exit status 74 since 0.1.3 (4 MiB pending-stdin bound terminates tar extract) #4430 within the existing CLI and supervisor upload paths.
  • Docs: Published sandbox overview and public CLI skill document bounded uploads, the CLI/supervisor upgrade requirement, and partial destinations.
  • Checks: Current-head Branch Checks, Helm Lint, Trivy Changes, and DCO pass.
  • E2E: test:e2e remains applied; current-head Branch E2E Checks run 38363547156 is in progress with runtime suites executing. No additional dispatch is needed.
  • Head SHA: d5bbc71fd83175473dddcbd207a838455b74a6d2
  • Base SHA: 5e414eadde83644d7a8a27554313b74a8bd61639
  • Merge base SHA: 5e414eadde83644d7a8a27554313b74a8bd61639
  • Patch ID: 9e997e67e4ac011033a62ca20a3a0fe1ed04b2d1
  • Gator payload: 12
  • Review mode: follow_up
  • Previous reviewed SHA: 3aeda041ac67d077364a909c4f28bfa8f3084246
  • Review budget exhausted: no
  • Maintainer decision required: no
  • Next state: gator:watch-pipeline

@johntmyers johntmyers added gator:watch-pipeline Gator is monitoring PR CI/CD status gator:blocked Gator is blocked by process or repository gates and removed gator:blocked Gator is blocked by process or repository gates gator:watch-pipeline Gator is monitoring PR CI/CD status labels Oct 13, 2026
@johntmyers johntmyers added the gator:approval-needed Gator completed review; maintainer approval needed label Oct 13, 2026
@johntmyers
johntmyers added this pull request to the merge queue Oct 13, 2026
@johntmyers johntmyers added gator:merge-ready and removed gator:approval-needed Gator completed review; maintainer approval needed labels Oct 13, 2026
Merged via the queue into NVIDIA:main with commit 6a6401b Oct 13, 2026
185 of 191 checks passed
@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

Monitoring Complete

Monitoring is complete because this PR has merged. The final Gator state was merge-ready, and the latest review reported no blocking findings.

I removed the active gator:* label because there is nothing left for gator to monitor on this PR.

Gator metadata
  • Head SHA: d5bbc71fd83175473dddcbd207a838455b74a6d2
  • Gator payload: 12

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

Labels

test:e2e Requires end-to-end coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: sandbox upload fails with exit status 74 since 0.1.3 (4 MiB pending-stdin bound terminates tar extract)

2 participants