Skip to content

nvx-rs slimming 3.1.6: a managed sandbox run, and one exec at a time #1111

Closed

Description

Parent: #1083, in #1076. Needs: #1110, #1117. Unblocks: #1112, #1118, #1123, #1128, #1131.

Goal. sandbox run boots a layered root through the new APIs and nvx-init: a cold boot, one exec over NVXC and a stop, with no state directory. One exec runs at a time per sandbox, across CLI processes (#819): sandbox exec waits for the sandbox's lock, and sandbox stop takes none.

Notes.

  • sandbox run becomes managed. Until SL3.4b, the old one-shot run still boots through the old layered init, which the shell /init selects by OpenVMM's lifecycle token; afterwards nvx-init boots every layered root that the CLI starts.

PRs, in order. Each PR has one goal, leaves dev green, and names in its description each old test of its area as kept, rewritten or retired, with each change that check_test_changes.py reports. Its tests follow the repository's test layout: a module's unit tests, and the code that only they use, sit in its tests.rs or tests/ and move with it. The estimates count core lines (code, not comments, docs or tests) and counted files; each PR records its measured values. Each PR does what its Scope says and no more: a case, input or layout that its Scope doesn't name, and whatever "Not in this PR" lists, is out of scope. Address every review comment within the scope, and ask before acting on one that asks for more. A PR whose measured core lines pass the stop that its Estimate names (twice the estimate, at most 600) stops and asks before continuing.

  1. SL3.4b: sandbox run boots a layered root through the new APIs: a cold boot, one exec and a stop.

    • Objective: sandbox run becomes a stateless managed layered launch: one cold boot, one NVXC exec and one stop. It uses the new VM interface and nvx-init while retaining the command's planned image, upper and exec behavior.
    • Contents: sandbox run takes provision's image and upper options and exec's options (--cwd, --environment, --environment-file, --inherit-default-environment). It creates and spawns the VM, runs one exec over NVXC, then stops the VM. It has no state directory, and checks the protected paths that apply (nvx-rs: GPT images, the RAM upper and protected paths in nvx-rs sandbox #818). Its outcome report stays readable under a restrictive umask, and the public sandbox scenarios, which now run by default, pass.
    • Scope:
      • nvx-rs/src/host/cli/sandbox/ gives sandbox run provision's EROFS and GPT image options and scratch or capped RAM uppers.
      • The command accepts exec's --cwd, --environment, --environment-file and --inherit-default-environment options for its single NVXC execution.
      • It creates and spawns the VM, executes once over NVXC, and stops gracefully; its command line holds nvx_sandbox=1 and no OpenVMM lifecycle option.
      • The launch creates no sandbox state directory, rejects shares whose canonical host path equals, contains or lies inside its root image, scratch image when present, or artifact directory, and leaves its outcome report readable under a restrictive umask.
    • Not in this PR:
      • More than one exec, a persistent state directory, restart or reattach behavior: use the provisioned sandbox lifecycle for those.
      • Keeping the old one-shot layered launch or its output compatibility: layered roots are managed and old CLI output need not be preserved.
      • New exec options, image kinds, upper kinds, commands or unrelated flags beyond those named in this PR.
      • An alias matrix for protected paths: the canonical-path checks from SL3.5c are sufficient.
    • Approach: Compose the VmConfig building already used by provision and start with the exec request already used by sandbox exec. Drive one host::vm launch and one NVXC execution in a straight-line cleanup path; do not add a temporary store, lifecycle abstraction or output-compatibility formatter.
    • Done when:
      • EROFS and GPT each run with scratch and capped RAM uppers, including the 50 percent default.
      • --cwd, explicit and file environments, and inherited default environment reach the single NVXC exec.
      • The VM stops gracefully, no state directory is created, and protected paths are refused.
      • The command line holds nvx_sandbox=1, contains no OpenVMM lifecycle option, and the public sandbox scenarios pass by default.
    • Needs: SL3.5c, in nvx-rs slimming 3.1.5: the sandbox lifecycle runs on the new interface and nvx-init #1110; SL7.8a, in nvx-rs slimming 3.3.3: nvx-init captures and restores, and boots the new launches' layered roots #1117.
    • Estimate: 300 core lines, 4 counted files. Past 600 core lines, stop and ask before continuing.
  2. SL3.9: One exec runs at a time per sandbox, across CLI processes.

    • Objective: Concurrent CLI processes cannot run two sandbox exec workloads in one sandbox. An exec waits for a bounded time and reports busy, while stop remains able to proceed.
    • Contents: exec_lock: sandbox exec takes a per-sandbox OS file lock, waits for it up to --wait (60 s by default), then fails with busy (nvx-rs: admit nvx-rs sandbox exec through a bounded queue across CLI processes #819). sandbox stop takes no lock.
    • Scope:
      • A new host::cli::exec_lock module owns one OS file lock per sandbox.
      • sandbox exec waits for the lock for --wait seconds, using 60 seconds when the option is omitted.
      • An exec that cannot acquire the lock before the deadline fails with busy.
      • sandbox stop does not acquire the exec lock and can proceed while an exec holds it.
    • Not in this PR:
      • An in-memory queue, daemon, ticket order or fairness guarantee: coordination is one OS file lock.
      • More than one concurrent exec per sandbox or a global lock across sandboxes.
      • Making stop wait for or acquire the exec lock.
      • New commands, unrelated flags or output redesigns beyond the required --wait and busy result.
    • Approach: Follow the existing per-sandbox lock-file pattern with a separate OS lock and a deadline derived from --wait. Poll with the existing short retry interval so tests use a small wait; do not add a scheduler, background service or persistent queue.
    • Done when:
      • A second sandbox exec waits up to its configured short test deadline, then fails with busy.
      • Omitting --wait selects the 60-second default without making the test sleep for 60 seconds.
      • sandbox stop proceeds while another process holds the exec lock.
      • Exec locks are per sandbox, so separate sandboxes do not block one another.
    • Needs: SL3.5b, in nvx-rs slimming 3.1.5: the sandbox lifecycle runs on the new interface and nvx-init #1110.
    • Estimate: 60 core lines, 3 counted files. Past 120 core lines, stop and ask before continuing.

Tests. sandbox run, with EROFS and GPT, each with a scratch and with a capped RAM upper: --cwd, explicit and file environments, the inherited default environment, one exec over NVXC, a graceful stop, no state directory, and the protected-path refusals; its command line holds nvx_sandbox=1 and no OpenVMM lifecycle token. A second sandbox exec waits for the lock up to --wait (60 s by default, tested without waiting 60 s), then fails with busy; sandbox stop proceeds while an exec holds the lock.

Done when: every PR above has merged, with dev green.

Activity

  1. esaurez commented on Nov 10, 2026

    @esaurez
    ContributorAuthor

    Workstream source/progress checkpoint - 2026-11-11 UTC

    Checked boxes below mean merged scope, not merely an implemented first iteration. Implementation branches are source checkpoints, not automatic qualification, Ready or merge approval. Some starting inputs are frozen/anonymous commits rather than standalone branches; their exact SHAs and known merged producer refs are recorded explicitly.

    The original technical scope remains authoritative, supplemented only by any portable technical clarification in this issue. No machine-specific execution policy is part of this checkpoint.

  2. ppenna commented on Nov 11, 2026

    @ppenna
    Contributor

    Both PRs of this group have merged into feature/nvx-refactor: SL3.4b (#1490) and SL3.9 (#1469).

    The feature branch's post-merge CI run at f834bcb967, which contains both, passed: https://github.com/microsoft/nvx/actions/runs/43114171980. Closing this group as complete; dev receives it when feature/nvx-refactor lands there.

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

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions