Repository navigation
host: finish exited captures into snapshot entries - #1455
Merged
Pedro Henrique Penna (ppenna) merged 3 commits intoNov 11, 2026
Merged
Pedro Henrique Penna (ppenna) merged 3 commits into
Pedro Henrique Penna (ppenna) merged 3 commits into
Conversation
Contributor
This pull request changes existing testsIt modifies or removes 4 existing test asset(s), listed below. Review each with care: a change to a test can hide a regression that the test caught. See doc/contribute.md#changes-to-existing-tests. Test code
Test data
Relocated unchanged: 12; added: 34. Compared the merge base |
This was referenced Nov 10, 2026
Enrique Saurez (esaurez)
force-pushed
the
esaurez/issue1102-sl214-20261110-b718df7e
branch
from
November 10, 2026 22:04
d4d8927 to
1148a74
Compare
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues block the capture-finishing API changes.
No open issues 🎉
What changed in this PR
Adds post-exit capture finishing to NVX’s snapshot API for #1102, building on #1454’s capture preparation. The library validates capture output and writes snapshot metadata; callers retain responsibility for publication and storage.
Changes:
- Add
finish_captureandCapturedSnapshot, sharing existing validation and supporting retries after partial metadata writes. - Persist the complete capture-time contract in snapshot keys while preserving compatibility identities.
- Add capture-finishing and time-consistency tests, update encoding vectors, and document the public API.
| File | Description |
|---|---|
nvx-rs/tests/vectors/snapshot-key-v1.txt |
Append capture-time fields while preserving identity values. |
nvx-rs/tests/vectors/README.md |
Explain persisted time fields and compatibility hashing. |
nvx-rs/src/host/vm.rs |
Share the outcome filename with snapshot finishing. |
nvx-rs/src/host/template/store/tests.rs |
Import the shared snapshot artifact inventory. |
nvx-rs/src/host/template/store/capture/tests.rs |
Keep fixture filenames local and use shared constants. |
nvx-rs/src/host/template/store/capture.rs |
Reuse extracted outcome and artifact validation. |
nvx-rs/src/host/snapshot/tests.rs |
Test rejection of key/manifest capture-time mismatches. |
nvx-rs/src/host/snapshot/manifest.rs |
Clarify time-contract identity semantics in documentation. |
nvx-rs/src/host/snapshot/key/tests.rs |
Test full time round trips and unchanged compatibility identities. |
nvx-rs/src/host/snapshot/key.rs |
Derive keys from capture contexts and encode complete time contracts. |
nvx-rs/src/host/snapshot/capture/tests.rs |
Cover validation, privacy, retries, and caller-managed publication. |
nvx-rs/src/host/snapshot/capture.rs |
Implement capture finishing and shared validation helpers. |
nvx-rs/src/host/snapshot/canonical.rs |
Clarify which encoding bytes contribute to identities. |
nvx-rs/src/host/snapshot.rs |
Export finishing APIs and share strict artifact checks. |
nvx-rs/README.md |
Document finishing, publication responsibilities, and time semantics. |
nvx-rs/public-api/windows.txt |
Record the new Windows-visible public APIs. |
nvx-rs/public-api/linux.txt |
Record the new Linux-visible public APIs. |
Review effort: Balanced
Enrique Saurez (esaurez)
marked this pull request as ready for review
November 10, 2026 22:21
Enrique Saurez (esaurez)
marked this pull request as draft
November 10, 2026 22:22
Enrique Saurez (esaurez)
force-pushed
the
esaurez/sl2-13-capture-create-20261110-095bfb08
branch
from
November 10, 2026 22:27
8d6cbce to
e976e5c
Compare
Base automatically changed from
esaurez/sl2-13-capture-create-20261110-095bfb08
to
feature/nvx-refactor
November 10, 2026 23:27
Enrique Saurez (esaurez)
marked this pull request as ready for review
November 11, 2026 00:33
Validate the proved-exited capture outcome, strict OpenVMM artifacts and checked capture context. Write retryable private key and description files without moving or cleaning VM-directory entries. The Draft keeps SnapshotKey::time and its encoding/identity semantics pending the explicit user decision. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b718df7e-13ad-474d-b3c5-b0f93a7e18e6 Copilot-Session: bc910877-842b-4ceb-8b01-c50d4c0d7af9
Persist and strictly decode the complete per-snapshot time contract; hash only the unchanged compatibility prefix and reject key/manifest time mismatches. Keep the single Fresh encoding in place without a version bump or backward reader. Apply owner-only artifact validation at the snapshot boundary while preserving the legacy template validator and its existing callers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b718df7e-13ad-474d-b3c5-b0f93a7e18e6 Copilot-Session: bc910877-842b-4ceb-8b01-c50d4c0d7af9
Move the unchanged directory and endpoint contract into a private leaf, preserving the existing vm public paths and ownership. Keep capture and launch orchestration in their original modules and relocate directory tests with their owner. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: eecd1730-cf40-4c7f-8502-f74d24332b5c
Pedro Henrique Penna (ppenna)
force-pushed
the
esaurez/issue1102-sl214-20261110-b718df7e
branch
from
November 11, 2026 01:23
c6de1d8 to
aa319d6
Compare
Pedro Henrique Penna (ppenna)
merged commit Nov 11, 2026
9723f7a
into
feature/nvx-refactor
48 checks passed
Pedro Henrique Penna (ppenna)
deleted the
esaurez/issue1102-sl214-20261110-b718df7e
branch
November 11, 2026 01:39
This was referenced Nov 11, 2026
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.
Part of #1102, SL2.14, in #1076.
What and why
SL2.13 (#1454) prepares a capture launch; this pull request finishes the exited capture into the entries of a snapshot.
Capture finishing
host::snapshot::finish_capture(&VmDir, &CaptureContext, &Exited) -> Result<CapturedSnapshot>andCapturedSnapshot { pub key: SnapshotKey }.key.binand informationalsnapshot.jsonbesideopenvmm/. Leave logs, outcomes and unrelated VM entries untouched. Correctable validation failures and partial metadata writes can be retried; the caller alone publishes the three snapshot entries into its private immutable directory.SnapshotKey::time. PreserveKeyIdentity's unchanged compatibility prefix: different capture times have different persisted bytes but the same compatibility identity. Opening compares the complete key time against the strict manifest.No store, publication rename, journal, general transaction, version negotiation, backward decoder or manufactured exit proof. Rates contribute to compatibility; capture anchors, host/boot identities, lineage and cut-to-anchor interval are persisted but excluded from that identity. The Fresh encoding changes in place without a version bump.
VM directory ownership
Snapshot finishing needs the VM directory and its outcome file, but
host::vmimportshost::snapshot::{CaptureContext, Snapshot}, so importingvm::{OUTCOME, VmDir}fromsnapshot/capture.rsmadehost_modules::the_children_of_host_depend_on_one_another_without_cyclesfail. The last commit movesVmDir,VmOutputs, private-directory creation, the output and endpoint names, and their privacy and error helpers, unchanged, into privatehost::vm_directory, which depends only on host path and platform primitives.host::vmre-exportsVmDir,VmOutputsandcreate_private_dirat their existing public paths, so the public API gains only the snapshot items above, andTemplateKey::timethrough the existing alias. Launch, capture and process logic stay inhost::vm; its three accesses to the private path field use the existingpath()accessor.Rebase onto
feature/nvx-refactorThe branch is rebased onto
feature/nvx-refactorat 34d5c66 as three linear commits, replacing the previous head c6de1d8:The SL2.13 commits that the branch carried landed in the base as 8804b95 through e07a03b and are dropped, as are the two merge commits. Messages and authorship are unchanged. The final tree equals the three-way merge of c6de1d8 with 34d5c66, except in
nvx-rs/README.md's module table, which keeps both the base'snvx::host::vmrow and this pull request'snvx::host::snapshotrow. The other conflict, in the imports ofhost/vm.rs, keeps the base'shost::networkimport and this pull request's narrowedpaths::absolute. The net diff against the base is unchanged: 21 files, 1613 insertions and 745 deletions.As before the rebase, the first two commits compile but fail the host-module acyclicity test, 21 passed and 1 failed, until the third commit fixes it.
Size
The owned layer is seven production files, all under
nvx-rs/src/:host/mod.rs,host/snapshot.rs,host/snapshot/capture.rs,host/snapshot/key.rs,host/template/store/capture.rs,host/vm.rsand newhost/vm_directory.rs. As counted for c6de1d8, it adds or changes 439 and deletes 242 physical nonblank code lines, excluding comments, documentation and standalone test files and counting moved code as added: below 600. The rebase changes none of its hunks. Registering the shared owner, keeping its facade and removing the reverse dependency must be one compilable change, the narrow seven-file case that #1076 permits.Validation
At aa319d6, on a Windows x64 host without a hypervisor, with Rust 1.95.0 unless noted and
NVX_BUNDLE=skipas in CI (scripts/local_gates.pyis not on this base, so the commands come fromcheck-nvx-rsandcheck-quality):python scripts\nvx.py verifycargo fmt --all --checkcargo clippy --locked ... -- -D warnings, all fivecheck-nvx-rsconfigurationscargo test --locked --all-featurescargo test --lockedcargo build --locked --lib --no-default-featuresandcargo test --locked --lib --no-default-featurescargo doc --locked --no-deps --all-featureswithRUSTDOCFLAGS=-D warningspython scripts\public_api.py, Linux and Windows snapshotscargo +1.89 check --locked --all-targets --all-featurescargo check --locked --all-targets --all-features --target aarch64-apple-darwinhostconfigurations: format, Clippy, build, test, documentation and Rust 1.89cargo test --locked --all-features --test host_modulescargo check --locked --all-targets --all-featuresat 4de76db and f254457python scripts\check_test_layout.pyandpython scripts\check_markdown_links.pyCI: run 42938629920 on aa319d6 passed: 34 jobs succeeded, including Linux and Windows
check-nvx-rs, the NVX CLI on both, and the KVM, MSHV and WHP microVM, platform and package jobs, which were not run locally. The 9 skipped jobs publish the development release, package or publish the crate, record or persist performance results, handle merge groups, run the debug kernel on KVM and WHP, or check an OpenVMM pin that this pull request leaves unchanged.Changes to existing tests
python scripts\check_test_changes.py --base 34d5c669reports four changes, 12 relocated unchanged and 34 added, as before the rebase. No existing test is retired or weakened.host::template::store::testsobtain the shared artifact inventory fromhost::snapshot.keys_read_back_from_their_canonical_encodinghashes the specified compatibility prefix rather than the longer persisted bytes.keys_of_machines_that_no_manifest_describes_are_refusedstill corrupts the invariant ordering, locating it before the time suffix.snapshot-key-v1.txtappends time fields. Compatibility identities and CLASS vectors remain unchanged; truncation and trailing-byte cases retain their conditions. Its bytes were constructed independently of the Rust codec.The 12 relocations are these ten tests and their
is_fresh_pipeandvm_dirhelpers, which move unchanged, with their platform attributes and assertions, fromhost/vm/tests.rstohost/vm_directory/tests.rs. Only the test-onlyvm_dirhelper gains host-scoped visibility, for the launch tests that still use it.a_vm_directory_is_created_with_mode_700_for_the_current_user_whatever_the_umaskan_existing_directory_that_is_not_private_is_refused_and_left_unchangedtrailing_separators_and_current_directory_suffixes_do_not_hide_a_symbolic_linka_vm_directory_is_created_owner_only_and_protected_under_a_permissive_parentexisting_vm_directories_that_grant_others_or_inherit_are_refused_and_left_unchangeda_vm_directory_that_cannot_be_opened_or_created_fails_with_the_hosts_erroroutputs_name_the_vm_directorys_files_and_endpointsthe_endpoints_of_a_vm_directory_that_is_not_unicode_are_refuseda_restore_ready_endpoint_is_the_reserved_socket_or_a_fresh_pipecreating_and_opening_a_vm_directory_writes_no_capability_file_or_outputThe validation receipts of earlier heads, through c6de1d8, remain in this description's edit history.