Repository navigation
NVX: Start MicroVMs from platform snapshot templates - #1693
Draft
Pedro Henrique Penna (ppenna) wants to merge 3 commits into
Draft
Pedro Henrique Penna (ppenna) wants to merge 3 commits into
Pedro Henrique Penna (ppenna) wants to merge 3 commits into
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Base automatically changed from
user/ppenna/nvx-persistent-state-root
to
main
November 10, 2026 01:46
Create-and-run requests, with captured or live output, open the agent with platform snapshots, so sandboxes start as clones of templates that the first request in the state directory captures. The templates fit sandboxes with the agent's default resources, one virtual processor and 256 MiB of memory. Dry runs never capture templates, since capturing boots VMs, and lifecycle operations keep cold booting their containers. A host that cannot capture the templates opens the agent without them and cold boots sandboxes. The diagnostic log records why, and each start's boot mode. Refs #1692 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
force-pushed
the
user/ppenna/nvx-platform-snapshots
branch
from
November 10, 2026 02:16
ae2a44e to
60d5913
Compare
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Template VMs and snapshots can be created before invalid requests are rejected, and first-time capture cancellation and cleanup remain untested.
2 open issues
What changed in this PR
Enables NVX create-and-run requests to reuse platform snapshot templates, building on the persistent state directory introduced in #1691. The reviewed changes use the existing agent crate without changing the pinned bundle or public APIs.
Changes:
- Enable snapshot cloning for captured and streaming execution, with cold-boot fallback; keep snapshots disabled for dry runs and lifecycle operations.
- Log boot metadata and document template storage, resource limits, and diagnostic behavior.
- Add snapshot scenarios to nightly validation and warm up templates before existing sandbox-interruption tests.
| File | Description |
|---|---|
src/mxc-sdk/tests/nvx_e2e.rs |
Adds clone, streaming, dry-run, and fallback coverage; warms interruption tests. |
src/mxc-sdk/src/backends/nvx/runner.rs |
Enables snapshots for execution and logs sandbox boot metadata. |
src/mxc-sdk/src/backends/nvx/crate_runtime.rs |
Configures templates, implements cold-boot fallback, and preserves start metadata. |
scripts/tests/microvm-validation.test.js |
Checks discovery and execution requirements for the snapshot scenario. |
scripts/ci/stage-nvx-validation-tests.ps1 |
Requires snapshot-test discovery in staged artifacts. |
scripts/ci/run_backend_validation_tests.ps1 |
Requires the snapshot scenario’s execution marker. |
docs/development/build-and-test/ci-validation-infrastructure.md |
Documents nightly snapshot coverage. |
docs/backends/nvx/nvx.md |
Documents snapshot behavior, storage costs, exclusions, and diagnostics. |
Review effort: Balanced
Opening the agent with platform snapshots captures the templates in an empty state directory, which boots VMs. Create-and-run requests therefore open the agent without them, finish capability and native validation, and only then reopen it with platform snapshots, reusing the bundle that the first open verified. A request that the agent rejects never boots a VM. The rejected-request scenario now covers captured requests too and checks that no request captured templates. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The console-interruption scenario adds a phase that interrupts a request in an empty state directory while the agent captures its templates. It checks that the executor exits through cancellation without provisioning a sandbox, that no OpenVMM process that the executor started survives, and that a later request succeeds with the same state directory. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
marked this pull request as ready for review
November 10, 2026 02:47
Pedro Henrique Penna (ppenna)
requested a review
from a team
as a code owner
November 10, 2026 02:48
Pedro Henrique Penna (ppenna)
marked this pull request as draft
November 10, 2026 19:55
3 of 11 tasks
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

📖 Description
Every MicroVM create-and-run request cold boots its guest kernel. This PR starts those sandboxes as clones of the signed agent's platform snapshot templates instead.
This PR is rebased onto
mainafter #1691 merged and #1672 replaced MXC's native DLL bindings with theaci_edge_sandboxescrate. The pinned crate,0.1.1, already stages the sandbox ABI 3 bundle from releasev0.1.0-build188642429, and #1691 already registers image references before provisioning. This PR therefore no longer changes the bundle or the ABI bindings. It enables platform snapshots through the crate'sSetupConfig::with_platform_snapshots.run_jsonand the executor) or live output (spawn_json), open the agent, finish capability and native validation, and then reopen it withplatformSnapshots(maxVcpus: 1,maxMemoryMib: 256). These capacities fit sandboxes with the agent's default resources. The reopen reuses the bundle that the first open verified. The first request in a state directory captures two templates, one with a NIC and one without. Later requests in any process clone them, and concurrent first requests capture them once.--dry-runvalidation never enables them either. Lifecycle operations open the agent without them, so the containers they provision cold boot. Otherwise, whichever lifecycle call first opened the lifecycle state directory, such asstop, would boot VMs to capture templates. A create-and-run request that setsmicrovm.provision.memoryMibto anything other than 256 cold boots, and its start records thecoldReason.bootMode,templateorcoldReason,bootMilliseconds, andphases.These measurements were taken before the rebase, with the same agent bundle driven through MXC's former DLL bindings. They come from a Windows 11 x64 WHP host (i9-12900H), using release builds, a warm image cache, and
echo helloonpublic.ecr.aws/docker/library/alpine:3, with the variants interleaved:The agent reported a median boot of 243 ms for clones and 283 ms for cold boots (n=15 each). The edge guest already cold boots quickly on this host, so clones save about 40 ms of boot, which is within the end-to-end noise.
Costs and limitations:
aci_edge_agent: template store …: captured generation N of the … template in … msto the process's standard error. In the executor, that stream also carries the workload's standard error, and MXC cannot redirect it.This changes the default boot behavior, but no request schema, policy field, public API, or pinned runtime, so I don't believe it needs a spec. I'm happy to write one if maintainers prefer. Given the measurements above, maintainers may also prefer to leave platform snapshots off until they pay off on more hosts.
🔗 References
Closes #1692
Builds on #1691 and #1672
🔍 Validation
On a Windows 11 x64 WHP host (build 26300), from
src, at b2f3f7a (rebased ontomainat 03efb61, plus the review follow-ups):cargo fmt --all -- --check: passed.cargo clippy --locked -p mxc-sdk --features microvm --target x86_64-pc-windows-msvc --all-targets -- -D warnings: passed.cargo test --locked -p mxc-sdk --features microvm --target x86_64-pc-windows-msvc --lib: 2668 passed, 0 failed, 1 ignored.cargo test --locked -p mxc-sdk --features microvm --target x86_64-pc-windows-msvc --no-fail-fast --test nvx_e2e --test nvx_bundle_integrity -- --include-ignored --nocapture --test-threads=1, withLOCALAPPDATAset to an empty temporary directory:nvx_bundle_integrity: 9 passed, 0 failed.nvx_e2e: 24 passed, 0 failed, 0 ignored, and all twelve nightlyVM_EXECUTEDscenario markers printed.With this host's own
LOCALAPPDATA, twonvx_bundle_integritytests fail before they reach this change. An earlier build left%LOCALAPPDATA%\Microsoft\MXC\nvxwith an inherited DACL, which MXC's state-root check rejects.node --test scripts\tests\microvm-validation.test.js(from the repository root): 53 passed, 0 failed.node scripts\ci\resolve-validation-test-matrix.mjs --plan nightly(from the repository root): passed.The intermediate commit 3b11170 builds, and its 58 NVX unit tests pass.
New and changed coverage:
signed_bundle_executor_starts_sandboxes_from_platform_snapshotsruns nightly. It is listed in the staging and validation scripts and their script tests.noNicclone on the host CPU profile.nicclone witheth0.spawn_jsonrequest in another empty state directory also captures the templates. Temporarily makingspawn_streamingopen the agent without platform snapshots fails this check.native_validation_rejects_requests_without_booting_a_vm, previouslystreaming_and_lifecycle_validation_reach_the_crate_without_a_vm, sends a proxy that native validation rejects throughrun_jsonandspawn_json. It then checks that no agent state directory has a template store. It fails if platform snapshots are enabled before validation.signed_bundle_executor_console_interruptinterrupts three phases:capture: the first request's template capture, in an empty state directory.startupandexecution: these phases make a warm-up request first, so their interruptions reach the sandbox rather than a template capture.Each phase checks that every OpenVMM process the executor started has terminated, and that a later request succeeds with the same state directory.
Unit tests cover:
✅ Checklist
feature-acceptedCargo.lock, thedependency-feed-checkcheck passes (see pull request builds)📋 Issue Type