Skip to content

feat(mxc): support sandbox exec and restart on Windows - #5427

Closed
getrou wants to merge 3 commits into
NVIDIA:windowsfrom
getrou:user/getrou/mxc-windows-exec
Closed

getrou wants to merge 3 commits into
NVIDIA:windowsfrom
getrou:user/getrou/mxc-windows-exec

Conversation

@getrou

@getrou getrou commented Nov 9, 2026

Copy link
Copy Markdown

Draft: opening for early feedback on the Windows exec approach. Linux verification and a linked accepted issue are pending.

Summary

Adds sandbox exec and sandbox restart to the MXC driver on Windows, so the standard OpenShell CLI flows (create, exec, stop, start, delete) work on both the process_container and isolation_session backends. Commands now run on Windows as written, without POSIX shell assumptions.

Related Issue

Closes #NNN

Changes

  • Exec on Windows: the supervisor's SSH server is reached through an in-process duplex stream on Windows (no Unix socket). The in-boundary agent translates the gateway's POSIX-quoted exec string back into argv, and runs anything else through cmd.exe /d /s /c.
  • Spawn-failure fallback: if a shell request fails to spawn directly, the agent retries through cmd.exe, so the gateway always gets an exit status instead of waiting on a failed channel.
  • Commands run as written: the cmd /c tail is passed verbatim (cmd does not use CRT quoting) for both exec and the main process. create -- <command> works without driver config and defaults the working directory to %TEMP%\openshell-mxc\<sandboxId>.
  • Windows-safe ProxyCommand quoting in openshell-core and the CLI, plus split_sandbox_path for Windows paths.
  • Restart: start_sandbox re-runs the MXC lifecycle with fresh launch authentication after a full stop. The workspace persists across restarts.
  • Tests: Windows forwarding/quoting unit tests; POSIX-only proxy-command tests gated to non-Windows; POSIX command parser tests; driver start_sandbox tests.

Release Notes

openshell sandbox exec and openshell sandbox start (restart) now work for MXC sandboxes on Windows.

Testing

  • Checks appropriate to the affected code and behavior pass: each commit builds on Windows (x86_64-pc-windows-msvc); cargo test passes for the affected crates on Windows
  • Unit tests added/updated (if applicable)
  • E2E tests added/updated (if applicable)

Manual verification on a Windows VM with MXC, on both process_container and isolation_session:

  • sandbox exec with plain argv, cd X && / K=v prefixes, and cmd syntax (&, if exist, redirection)
  • create, then stop, start, exec: the workspace persists and exec works after restart
  • The pre-restructure conformance scenarios, with Windows fixtures that are not part of this PR: 7 of 10 pass on both backends. The remaining 3 are file transfer, which runs POSIX commands (mkdir -p, tar, realpath) inside the sandbox.

Checklist

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

`sandbox exec`, `connect`, and file transfer reach the sandbox through the
supervisor's SSH server. On Windows that server was never started and the
relay rejected SSH targets, so exec failed on both MXC backends.

Supervisor: the relay and the SSH server run in the same process, so on
Windows each relay is handed to the server as one half of an in-memory
duplex stream, registered under the configured socket path. No socket or
pipe is created, so nothing outside the supervisor can reach the server.
The Unix socket path is unchanged.

MXC driver: pass OPENSHELL_SSH_SOCKET_PATH so the supervisor starts its
SSH server.

MXC boundary: accept shell exec intent. The gateway sends a POSIX command
string built by shell_escape; when it is that plain form, recover argv,
environment, and working directory and spawn the program directly. Other
shell syntax runs through cmd.exe /d /s /c. When a program cannot be
started directly, retry through cmd.exe, as a POSIX shell would report
"command not found" itself; this also resolves cmd built-ins. Without the
retry the SSH client waits for an exit status that never arrives.

PTY (ConPTY) remains unsupported, so `sandbox connect` is not enabled.

Signed-off-by: Geoffrey Trousdale (they/them) <getrou@microsoft.com>
- MXC boundary: pass the tail after `cmd.exe /c` verbatim (with /s and outer
  quotes) for both exec and the main process, because cmd.exe does not use
  CRT argument quoting.
- MXC driver: honor a generic `create -- <command>` and default the working
  directory to a per-sandbox temp directory when the template sets none.
- CLI/core: escape the SSH ProxyCommand for Windows and split Windows sandbox
  paths correctly.

Signed-off-by: Geoffrey Trousdale (they/them) <getrou@microsoft.com>
StartSandbox returned Unimplemented. Stop already tears the runtime down
completely (for an isolation session it also deprovisions the agent user), so
start reruns the sandbox lifecycle from the stored spec with the fresh launch
credentials the gateway supplies. Each start gets its own runtime generation
and state directories; the previous generation's directories are removed.
Host paths named by the policy, such as the workspace, persist across the
restart. A start of a sandbox that is already starting or running succeeds
without relaunching.

The isolation-session agent user is not preserved across a restart: a new
agent user is provisioned for each start.

Also fix the Windows restart counter fixture: cmd includes the space before
`&` in echoed text, so the counter read "2 " instead of "2".

Signed-off-by: Geoffrey Trousdale (they/them) <getrou@microsoft.com>
@copy-pr-bot

copy-pr-bot Bot commented Nov 9, 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.

@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown

Thank you for your interest in contributing to OpenShell, @getrou.

This project uses a vouch system for first-time contributors. Before submitting a pull request, you need to be vouched by a maintainer.

To get vouched:

  1. Open a Vouch Request discussion.
  2. Describe what you want to change and why.
  3. Write in your own words — do not have an AI generate the request.
  4. A maintainer will comment /vouch if approved.
  5. Once vouched, open a new PR (preferred) or reopen this one after a few minutes.

See CONTRIBUTING.md for details.

@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown

Thank you for your submission! We ask that you sign our Developer Certificate of Origin before we can accept your contribution. You can sign the DCO by adding a comment below using this text:


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


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the DCO Assistant Lite bot.

@github-actions github-actions Bot closed this Nov 9, 2026
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.

1 participant