Repository navigation
host: make image staging and artifact discovery private to the CLI (SL6.4) - #1533
Conversation
This pull request changes existing testsIt modifies or removes 140 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
... and 90 more, which the job's summary lists. Relocated unchanged: 0; added: 6. Compared the merge base |
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues were identified for the changes narrowing the public API around CLI-owned image staging and artifact discovery.
No open issues 🎉
What changed in this PR
Implements SL6.4 of #1124, narrowing nvx’s public API so image staging and artifact discovery remain CLI-owned implementation details. This builds on #1532’s removal of unused helpers while preserving discovery, image checks, serialized bindings, and launch behavior.
Changes:
- Makes artifact, seal, distro, scratch, and layer APIs crate-private, with feature gates that retain shared library functionality.
- Moves private-API tests to their owning modules and adapts integration tests to exercise the CLI or inspect recorded data.
- Updates documentation, the external-launch example, coverage references, and both platform API snapshots.
| File | Description |
|---|---|
nvx-rs/tests/security_checklist.rs |
Moves image checks out; uses test-local file identity helpers. |
nvx-rs/tests/cli/lifecycle.rs |
Checks recorded bindings without importing private types. |
nvx-rs/tests/cli/artifacts.rs |
Asserts guest names through CLI output. |
nvx-rs/tests/cli.rs |
Exercises scratch claims through the CLI and specifies guest defaults. |
nvx-rs/src/lib.rs |
Removes artifact layouts from the public host description. |
nvx-rs/src/host/seal/windows.rs |
Gates guarded-open functionality behind cli. |
nvx-rs/src/host/seal.rs |
Privatizes seal types and gates functionality by its users. |
nvx-rs/src/host/sandbox/tests/specification.rs |
Gates layer grammar tests behind cli. |
nvx-rs/src/host/sandbox/scratch/tests.rs |
Receives the scratch-claim security checklist test. |
nvx-rs/src/host/sandbox/scratch.rs |
Makes scratch bindings and checked files crate-private. |
nvx-rs/src/host/sandbox/options/tests.rs |
Gates distro-dependent tests and adjusts imports. |
nvx-rs/src/host/sandbox/mod.rs |
Privatizes image modules and removes layer re-exports. |
nvx-rs/src/host/sandbox/layer.rs |
Makes layer types and parsing APIs crate-private. |
nvx-rs/src/host/sandbox/distro/tests.rs |
Receives the staged-image replacement checklist test. |
nvx-rs/src/host/sandbox/distro.rs |
Makes distro bindings, policy values, and checks crate-private. |
nvx-rs/src/host/mod.rs |
Privatizes artifact and seal modules; updates documentation. |
nvx-rs/src/host/cli/sandbox/tests.rs |
Checks exact provisioned bindings for scratch and RAM uppers. |
nvx-rs/src/host/cli/sandbox/options.rs |
Imports SandboxLayer from its owning module. |
nvx-rs/src/host/artifacts/require.rs |
Gates CLI-only artifact checks while retaining shared validation. |
nvx-rs/src/host/artifacts/mod.rs |
Privatizes and gates discovery helpers, constants, and tests. |
nvx-rs/src/host/artifacts/guest.rs |
Makes the guest inventory crate-private. |
nvx-rs/src/host/artifacts/dir.rs |
Makes artifact layouts, paths, and directory APIs crate-private. |
nvx-rs/README.md |
Documents CLI ownership and revised test locations. |
nvx-rs/public-api/windows.txt |
Removes privatized APIs from the Windows snapshot. |
nvx-rs/public-api/linux.txt |
Removes privatized APIs from the Linux snapshot. |
nvx-rs/examples/external-launch.rs |
Uses std::path::absolute instead of the private wrapper. |
doc/acceptance-case-matrix.md |
Points coverage references to the relocated tests. |
Review effort: Balanced
008035d to
7e7ef6e
Compare
SL6.4 (#1124) makes host::seal, host::sandbox's distro, scratch and layer modules and host::artifacts private to the CLI. Integration tests reached them through their public paths, which they cannot once those are private, so each case moves beside its owner or drives the nvx-rs binary, with the same assertions: - The security checklist's checks of a staged image and of a scratch image's claim, which only the CLI makes, a_staged_image_that_was_replaced_fails_its_check and a_scratch_image_is_claimed_by_one_launch_and_checked_again_after_a_release, move unchanged to the unit tests of host::sandbox::distro and host::sandbox::scratch, where they stage their images in a private directory as the checklist did. - The checklist's a_launch_takes_a_new_private_log_and_keeps_every_entry_that_it_did_not_create compares the identities of the created log and of the file at its path with a test-local file_id, the device and inode on Linux and the FILE_ID_INFO on Windows, as the seal holds them, in place of FileSeal. - lifecycle.rs compared the bindings that provision recorded with DistroBinding::verify and ScratchBinding::bind. A unit test of the CLI's sandbox command, provision_records_the_bindings_that_verification_and_the_scratch_binding_make, provisions a sandbox of each upper in process and makes that exact comparison. assert_bindings, and the RAM upper's lifecycle test, check what the test can tell of the images from outside: the bindings' versions, format, identity, policy verdict, absent manifest, schemes, kinds and lengths; each start checks the rest against the images. - an_interrupted_start_keeps_its_claim_until_recovery_confirms_exit checked the scratch claim with ScratchBinding::check: a sandbox run on the same images now finds the image claimed while the orphaned OpenVMM runs, with scratch-claimed, and claims it once recovery confirmed the exit, as a_running_sandbox_claims_its_scratch_image does. - run_boots_each_guest_with_its_default_memory and artifacts_list_every_guest_in_order spell the guests, their initramfs images and default memory, and their order, instead of reading Guest, whose own unit test checks the same values. The case matrix names the moved checklist tests where they now are. Part of #1124 (SL6.4). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
host::seal, host::sandbox's distro, scratch and layer modules, and host::artifacts were public API of nvx, although only NVX's CLI stages images and locates artifacts: the seals of checked files, the bindings of distro layers and scratch images, their checks and claims, the layer of a sandbox, and the artifact directories, guests and names of nvx.py. They become crate-private where they are, gated by the features of their users, with no change of behavior: - host::sandbox's distro, scratch and layer modules, and the dir, guest and identity modules and the other items of host::artifacts, become pub(crate) and cli-gated, and host::sandbox no longer re-exports LAYER_ROLES, LayerRole and SandboxLayer. require_existing stays in host::artifacts for host::sandbox::require_file, which is public until SL6.7b. - host::seal becomes pub(crate). host::snapshot opens snapshot files with open_read, and on Windows the platform layer names a log's job after the identity of FileSeal::of, so those stay with host; the seal's types take any(cli, windows), and what only the CLI's checks read, open_guarded, scheme, kind, length and difference, takes cli. - The CLI imports SandboxLayer from host::sandbox::layer, and the external-launch example resolves its paths with std::path::absolute rather than the private host::artifacts::absolute. Their unit tests, and the tests of host::sandbox's options and specifications that use a layer or a binding, take cli, so they run in the all-features tests. The image format and the identity that the guest expects stay public in protocol::root's RootImage. NVX_OPENVMM, NVX_AUTO_DOWNLOAD, the layouts, downloads, checks and claims are unchanged. The public API snapshots lose 132 lines on each platform, all under nvx::host::artifacts, nvx::host::seal and nvx::host::sandbox's distro, scratch and layer, with the three re-exports, and gain none. The crate's, host's and host::sandbox's docs and the README present these modules as private to the CLI, drop the README's sections and rows of host::artifacts and host::seal, whose details the CLI's sections hold, and the security checklist's paragraph names the unit tests that check staged images and scratch claims. Part of #1124 (SL6.4). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
508170f to
3276e77
Compare
|
Restacked onto |
8ae0617
into
feature/nvx-refactor
The build, distribution, and structure docs described the nvx crate only in passing: none listed its features, its Cargo profiles, or which of its binaries each build makes and where each ships; the guest docs spoke of an "aggregate nvx-rs source digest" without saying which files it covers; no document said how a guest that NVX does not build gets the guest tools; and the structure still credited the crate with artifact discovery, which SL6.4 (#1533) and SL6.6b made private to the CLI or deleted. Build gains two sections, traced to nvx-rs/Cargo.toml, Cargo.lock, scripts/nvx_tools/{guest_binaries,nvx_rs,release,build_constants}.py, ci.yml, package-platform.yml and the package-release action: - The nvx package: the one package, why it has its own lockfile, that NVX's builds pass --locked and the crate ships the lockfile; fixed tables of its five features and of its profiles, with the guest profile's settings, and of its binaries, with the feature, profile, target, builder and destination of each; its outputs; its caches, Cargo's alone, with CI's guest image keys on the guest inputs, which it lists as GuestRustBuildConstants selects them; its three provenance records; and its license inputs, nvx-rs/LICENSE, the lockfile and THIRD_PARTY_NOTICES.md, which the unit tests keep in step. - Release packages: the binary matrix of CI's three packages, the OpenVMM and nvx-rs build of each, the guest artifacts that each ships, the sandbox scratch template among them, and the archive. Distribution links them, adds the guest binaries and the crate's own license to its licensing paragraph, says what the crate holds, and documents installing the guest tools from the crate with cargo install nvx --version VERSION --locked --no-default-features --features guest --profile guest --target x86_64-unknown-linux-musl, with why each option is there. The structure lists the package's files, Cargo.toml, Cargo.lock, LICENSE and README.md, its top-level modules and what each binary calls, guest_binaries.py and guest_artifact_reuse.py, and what build/, .cache/ and nvx-rs/target/ hold. The Ubuntu and Azure Linux guests name the package's guest inputs, link the release packages, and point to the scratch template. Evidence, on nvx-mshv-test (Azure Linux 3, Rust 1.95.0) at 04fbbd4: cargo build --no-default-features --features guest --profile guest finished the guest profile; cargo install --path nvx-rs and cargo install nvx --version 0.1.0-alpha.16 with the documented options installed nvx-ingress as a static-pie executable, which prints its usage and exits 2; without --target it is dynamic, and without --version cargo install finds no version; --bins installs all ten. build-guest-binaries wrote a manifest whose source_sha256 equals guest-binary-source-identity, and removed its work directory. Part of #1131 (SL6.10e). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The build, distribution, and structure docs described the nvx crate only in passing: none listed its features, its Cargo profiles, or which of its binaries each build makes and where each ships; the guest docs spoke of an "aggregate nvx-rs source digest" without saying which files it covers; no document said how a guest that NVX does not build gets the guest tools; and the structure still credited the crate with artifact discovery, which SL6.4 (#1533) and SL6.6b made private to the CLI or deleted. Build gains two sections, traced to nvx-rs/Cargo.toml, Cargo.lock, scripts/nvx_tools/{guest_binaries,nvx_rs,release,build_constants}.py, ci.yml, package-platform.yml and the package-release action: - The nvx package: the one package, why it has its own lockfile, that NVX's builds pass --locked and the crate ships the lockfile; fixed tables of its five features and of its profiles, with the guest profile's settings, and of its binaries, with the feature, profile, target, builder and destination of each; its outputs; its caches: Cargo's target directories and registry, the guest routine's fresh target directory, which keeps RUSTC_WRAPPER, the sccache cache of the self-hosted runners, and CI's guest image keys on the guest inputs, which it lists as GuestRustBuildConstants selects them; its three provenance records; and its license inputs, nvx-rs/LICENSE, the lockfile and THIRD_PARTY_NOTICES.md, which the unit tests keep in step. - Release packages: the binary matrix of CI's three packages, the OpenVMM and nvx-rs build of each, the guest artifacts that each ships, the sandbox scratch template among them, and the archive. Distribution links them, adds the guest binaries and the crate's own license to its licensing paragraph, says what the crate holds, and documents installing the guest tools from the crate with cargo install nvx --version VERSION --locked --no-default-features --features guest --profile guest --target x86_64-unknown-linux-musl, with why each option is there. The structure lists the package's files, Cargo.toml, Cargo.lock, LICENSE and README.md, its top-level modules and what each binary calls, guest_binaries.py and guest_artifact_reuse.py, and what build/, .cache/ and nvx-rs/target/ hold. The Ubuntu and Azure Linux guests name the package's guest inputs, link the release packages, and point to the scratch template. Evidence, on nvx-mshv-test (Azure Linux 3, Rust 1.95.0) at 04fbbd4: cargo build --no-default-features --features guest --profile guest finished the guest profile; cargo install --path nvx-rs and cargo install nvx --version 0.1.0-alpha.16 with the documented options installed nvx-ingress as a static-pie executable, which prints its usage and exits 2; without --target it is dynamic, and without --version cargo install finds no version; --bins installs all ten. build-guest-binaries wrote a manifest whose source_sha256 equals guest-binary-source-identity, and removed its work directory. Part of #1131 (SL6.10e). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The build, distribution, and structure docs described the nvx crate only in passing: none listed its features, its Cargo profiles, or which of its binaries each build makes and where each ships; the guest docs spoke of an "aggregate nvx-rs source digest" without saying which files it covers; no document said how a guest that NVX does not build gets the guest tools; and the structure still credited the crate with artifact discovery, which SL6.4 (#1533) and SL6.6b made private to the CLI or deleted. Build gains two sections, traced to nvx-rs/Cargo.toml, Cargo.lock, scripts/nvx_tools/{guest_binaries,nvx_rs,release,build_constants}.py, ci.yml, package-platform.yml and the package-release action: - The nvx package: the one package, why it has its own lockfile, that NVX's builds pass --locked and the crate ships the lockfile; fixed tables of its five features and of its profiles, with the guest profile's settings, and of its binaries, with the feature, profile, target, builder and destination of each; its outputs; its caches: Cargo's target directories and registry, the guest routine's fresh target directory, which keeps RUSTC_WRAPPER, the sccache cache of the self-hosted runners, and CI's guest image keys on the guest inputs, which it lists as GuestRustBuildConstants selects them; its three provenance records; and its license inputs, nvx-rs/LICENSE, the lockfile and THIRD_PARTY_NOTICES.md, which the unit tests keep in step. - Release packages: the binary matrix of CI's three packages, the OpenVMM and nvx-rs build of each, the guest artifacts that each ships, the sandbox scratch template among them, and the archive, with a link to Continuous integration's Release packages section, which describes the package jobs. Distribution links them, leaves the package jobs' mechanics to that section of Continuous integration, adds the guest binaries and the crate's own license to its licensing paragraph, says what the crate holds, and documents installing the guest tools from the crate with cargo install nvx --version VERSION --locked --no-default-features --features guest --profile guest --target x86_64-unknown-linux-musl, with why each option is there. The structure lists the package's files, Cargo.toml, Cargo.lock, LICENSE and README.md, its top-level modules, with what is private to the crate since SL6.5a2, SL6.7b, SL6.8c, SL6.13b and SL6.14 (the CLI's export planner, egress policy compiler and sandbox launch profile, the error codes, the guest's space, the platform layer), and what each binary calls, guest_binaries.py and guest_artifact_reuse.py, and what build/, .cache/ and nvx-rs/target/ hold. The Ubuntu and Azure Linux guests name the package's guest inputs, link the release packages, and point to the scratch template. Evidence, on nvx-mshv-test (Azure Linux 3, Rust 1.95.0) at 04fbbd4: cargo build --no-default-features --features guest --profile guest finished the guest profile; cargo install --path nvx-rs and cargo install nvx --version 0.1.0-alpha.16 with the documented options installed nvx-ingress as a static-pie executable, which prints its usage and exits 2; without --target it is dynamic, and without --version cargo install finds no version; --bins installs all ten. build-guest-binaries wrote a manifest whose source_sha256 equals guest-binary-source-identity, and removed its work directory. Part of #1131 (SL6.10e). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The build, distribution, and structure docs described the nvx crate only in passing: none listed its features, its Cargo profiles, or which of its binaries each build makes and where each ships; the guest docs spoke of an "aggregate nvx-rs source digest" without saying which files it covers; no document said how a guest that NVX does not build gets the guest tools; and the structure still credited the crate with artifact discovery, which SL6.4 (#1533) and SL6.6b made private to the CLI or deleted. Build gains two sections, traced to nvx-rs/Cargo.toml, Cargo.lock, scripts/nvx_tools/{guest_binaries,nvx_rs,release,build_constants}.py, ci.yml, package-platform.yml and the package-release action: - The nvx package: the one package, why it has its own lockfile, that NVX's builds pass --locked and the crate ships the lockfile; fixed tables of its five features and of its profiles, with the guest profile's settings, and of its binaries, with the feature, profile, target, builder and destination of each; its outputs; its caches: Cargo's target directories and registry, the guest routine's fresh target directory, which keeps RUSTC_WRAPPER, the sccache cache of the self-hosted runners, and CI's guest image keys on the guest inputs, which it lists as GuestRustBuildConstants selects them; its three provenance records; and its license inputs, nvx-rs/LICENSE, the lockfile and THIRD_PARTY_NOTICES.md, which the unit tests keep in step. - Release packages: the binary matrix of CI's three packages, the OpenVMM and nvx-rs build of each, the guest artifacts that each ships, the sandbox scratch template among them, and the archive, with a link to Continuous integration's Release packages section, which describes the package jobs. Distribution links them, leaves the package jobs' mechanics to that section of Continuous integration, adds the guest binaries and the crate's own license to its licensing paragraph, says what the crate holds, and documents installing the guest tools from the crate with cargo install nvx --version VERSION --locked --no-default-features --features guest --profile guest --target x86_64-unknown-linux-musl, with why each option is there. The structure lists the package's files, Cargo.toml, Cargo.lock, LICENSE and README.md, its top-level modules, with what is private to the crate since SL6.5a2, SL6.7b, SL6.8c, SL6.13b and SL6.14 (the CLI's export planner, egress policy compiler and sandbox launch profile, the error codes, the guest's space, the platform layer), and what each binary calls, guest_binaries.py and guest_artifact_reuse.py, and what build/, .cache/ and nvx-rs/target/ hold. The Ubuntu and Azure Linux guests name the package's guest inputs, link the release packages, and point to the scratch template. Evidence, on nvx-mshv-test (Azure Linux 3, Rust 1.95.0) at 04fbbd4: cargo build --no-default-features --features guest --profile guest finished the guest profile; cargo install --path nvx-rs and cargo install nvx --version 0.1.0-alpha.16 with the documented options installed nvx-ingress as a static-pie executable, which prints its usage and exits 2; without --target it is dynamic, and without --version cargo install finds no version; --bins installs all ten. build-guest-binaries wrote a manifest whose source_sha256 equals guest-binary-source-identity, and removed its work directory. Part of #1131 (SL6.10e). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The build, distribution, and structure docs described the nvx crate only in passing: none listed its features, its Cargo profiles, or which of its binaries each build makes and where each ships; the guest docs spoke of an "aggregate nvx-rs source digest" without saying which files it covers; no document said how a guest that NVX does not build gets the guest tools; and the structure still credited the crate with artifact discovery, which SL6.4 (#1533) and SL6.6b made private to the CLI or deleted. Build gains two sections, traced to nvx-rs/Cargo.toml, Cargo.lock, scripts/nvx_tools/{guest_binaries,nvx_rs,release,build_constants}.py, ci.yml, package-platform.yml and the package-release action: - The nvx package: the one package, why it has its own lockfile, that NVX's builds pass --locked and the crate ships the lockfile; fixed tables of its five features and of its profiles, with the guest profile's settings, and of its binaries, with the feature, profile, target, builder and destination of each; its outputs; its caches: Cargo's target directories and registry, the guest routine's fresh target directory, which keeps RUSTC_WRAPPER, the sccache cache of the self-hosted runners, and CI's guest image keys on the guest inputs, which it lists as GuestRustBuildConstants selects them; its three provenance records; and its license inputs, nvx-rs/LICENSE, the lockfile and THIRD_PARTY_NOTICES.md, which the unit tests keep in step. - Release packages: the binary matrix of CI's three packages, the OpenVMM and nvx-rs build of each, the guest artifacts that each ships, the sandbox scratch template among them, and the archive, with a link to Continuous integration's Release packages section, which describes the package jobs. Distribution links them, leaves the package jobs' mechanics to that section of Continuous integration, adds the guest binaries and the crate's own license to its licensing paragraph, says what the crate holds, and documents installing the guest tools from the crate with cargo install nvx --version VERSION --locked --no-default-features --features guest --profile guest --target x86_64-unknown-linux-musl, with why each option is there. The structure lists the package's files, Cargo.toml, Cargo.lock, LICENSE and README.md, its top-level modules, with what is private to the crate since SL6.5a2, SL6.7b, SL6.8c, SL6.13b and SL6.14 (the CLI's export planner, egress policy compiler and sandbox launch profile, the error codes, the guest's space, the platform layer), and what each binary calls, guest_binaries.py and guest_artifact_reuse.py, and what build/, .cache/ and nvx-rs/target/ hold. The Ubuntu and Azure Linux guests name the package's guest inputs, link the release packages, and point to the scratch template. Evidence, on nvx-mshv-test (Azure Linux 3, Rust 1.95.0) at 04fbbd4: cargo build --no-default-features --features guest --profile guest finished the guest profile; cargo install --path nvx-rs and cargo install nvx --version 0.1.0-alpha.16 with the documented options installed nvx-ingress as a static-pie executable, which prints its usage and exits 2; without --target it is dynamic, and without --version cargo install finds no version; --bins installs all ten. build-guest-binaries wrote a manifest whose source_sha256 equals guest-binary-source-identity, and removed its work directory. Part of #1131 (SL6.10e). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The build, distribution, and structure docs described the nvx crate only in passing: none listed its features, its Cargo profiles, or which of its binaries each build makes and where each ships; the guest docs spoke of an "aggregate nvx-rs source digest" without saying which files it covers; no document said how a guest that NVX does not build gets the guest tools; and the structure still credited the crate with artifact discovery, which SL6.4 (#1533) and SL6.6b made private to the CLI or deleted. Build gains two sections, traced to nvx-rs/Cargo.toml, Cargo.lock, scripts/nvx_tools/{guest_binaries,nvx_rs,release,build_constants}.py, ci.yml, package-platform.yml and the package-release action: - The nvx package: the one package, why it has its own lockfile, that NVX's builds pass --locked and the crate ships the lockfile; fixed tables of its five features and of its profiles, with the guest profile's settings, and of its binaries, with the feature, profile, target, builder and destination of each; its outputs; its caches: Cargo's target directories and registry, the guest routine's fresh target directory, which keeps RUSTC_WRAPPER, the sccache cache of the self-hosted runners, and CI's guest image keys on the guest inputs, which it lists as GuestRustBuildConstants selects them; its three provenance records; and its license inputs, nvx-rs/LICENSE, the lockfile and THIRD_PARTY_NOTICES.md, which the unit tests keep in step. - Release packages: the binary matrix of CI's three packages, the OpenVMM and nvx-rs build of each, the guest artifacts that each ships, the sandbox scratch template among them, and the archive, with a link to Continuous integration's Release packages section, which describes the package jobs. Distribution links them, leaves the package jobs' mechanics to that section of Continuous integration, adds the guest binaries and the crate's own license to its licensing paragraph, says what the crate holds, and documents installing the guest tools from the crate with cargo install nvx --version VERSION --locked --no-default-features --features guest --profile guest --target x86_64-unknown-linux-musl, with why each option is there. The structure lists the package's files, Cargo.toml, Cargo.lock, LICENSE and README.md, its top-level modules, with what is private to the crate since SL6.5a2, SL6.7b, SL6.8c, SL6.13b and SL6.14 (the CLI's export planner, egress policy compiler and sandbox launch profile, the error codes, the guest's space, the platform layer), and what each binary calls, guest_binaries.py and guest_artifact_reuse.py, and what build/, .cache/ and nvx-rs/target/ hold. The Ubuntu and Azure Linux guests name the package's guest inputs, link the release packages, and point to the scratch template. Evidence, on nvx-mshv-test (Azure Linux 3, Rust 1.95.0) at 04fbbd4: cargo build --no-default-features --features guest --profile guest finished the guest profile; cargo install --path nvx-rs and cargo install nvx --version 0.1.0-alpha.16 with the documented options installed nvx-ingress as a static-pie executable, which prints its usage and exits 2; without --target it is dynamic, and without --version cargo install finds no version; --bins installs all ten. build-guest-binaries wrote a manifest whose source_sha256 equals guest-binary-source-identity, and removed its work directory. Part of #1131 (SL6.10e). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Part of #1124 (SL6.4, "Image staging and artifact discovery are private to the CLI"). Parent #1088, umbrella #1076.
Stacked on #1532 (SL6.6b, in #1122), which deletes the items that this PR would otherwise leave without a caller, so that this one stays visibility-only. It needs SL6.3 (#1530) and SL6.6a (#1524) too, which have merged. Until #1532 merges, this PR's base is its branch.
What and why
Image staging and artifact discovery are the CLI's behavior, but their seals, bindings, checked files, artifact inventory and layouts were public API of
nvx. This PR does SL6.4's Scope: it makes them private to the CLI where they are, without changing image formats, discovery, environment variables, checks or launch behavior. Two commits:tests: check image staging through the CLI and the owners' unit tests(71815e2a): the integration tests that reached these modules through public paths become unit tests of their owners, or drive the binary, with the same cases (Test changes, below). It changes no production code, so it passes on its own, before the visibility changes.host: make image staging and artifact discovery private to the CLI(508170fb):host::artifactsandhost::sealbecomepub(crate)modules.host::sandbox::{distro, scratch, layer}becomepub(crate)andcli-gated, andhost::sandboxno longer re-exportsLAYER_ROLES,LayerRoleandSandboxLayer. The crate root'sArtifactswent in SL6.6b.pub(crate)and are gated by the feature or platform of their users:ArtifactDir,ArtifactPaths,GuestPaths,Layout,Guest(withscratch_template_name),MANIFEST_NAME, the artifacts' names,openvmm_executableandabsolutebycli;FileSealand its types (SealScheme,FileKind,SealTime,FileId) byany(feature = "cli", windows), since the Windows platform module names jobs byFileSeal::of's file ID outside the CLI, andSEAL_VERSIONby the hosts whose seal records it, Linux withcliand Windows;FileSeal::{scheme, kind, length, difference}andseal::open_guardedbycli. Three items stay ungated for their users outside the CLI:seal::open_read(host::snapshot),host::artifacts::require_existing(the publichost::sandbox::require_file) andhost::sandbox::block_geometry(host::vm,host::snapshot, the CLI).DistroBindingkeeps its serde form, whichnvx-rs sandbox provisionrecords, and so doScratchBindingandFileSeal; the policy verdict,DISTRO_POLICY_REVISION, the scratch claim (CLAIM_RELEASE_WAIT) and the checked files don't change.RootImageandLayeredRootdon't change. The CLI's discovery (--root, or the release or checkout that holds the executable, in the repository and release layouts),NVX_OPENVMMandNVX_AUTO_DOWNLOADkeep their behavior: the CLI reads them through its own constants. The guest inventory names the same kernel, initramfs, distro files and scratch template for each guest.examples/external-launch.rscallsstd::path::absolute, which the now-privatenvx::host::artifacts::absolutewraps, for its four paths. The crate's docs,host's andhost::sandbox's present the modules as private.host::artifacts,host::sealandhost::sandbox::{distro, layer, scratch}, and the three re-exports. Nothing is added, and no path of these items remains,nvx::Artifactsincluded.nvx-rs/README.md): the module table drops thehost::artifactsandhost::sealrows and their sections, thehost::sandboxrow and section say that the distro, scratch and layer modules are the CLI's, and Distro bindings, Images by path and the security checklist's paragraph name the moved tests.host::sandbox::{distro, scratch}; no row's fate changes, andcheck_matrix.pypasses.Size
Measured against
008035d2893(SL6.6b's head), by #1076's rules, with #1124's note that privatizing counts as a move. This PR is visibility-only: 0 core lines and no counted files, as estimated.nvx-rs/src: 0 core lines, no counted file. Every changed line of the 13 production files there only makes items crate-private, gates them byclior by the platform that uses them, edits the imports that this forces (such aslayer::SandboxLayerin place of the dropped re-export), or is the docs; rustfmt rewraps the signature ofDistroBinding::check, whichpub(crate)lengthens.examples/external-launch.rs: 0 core lines, no counted file. Examples count as docs, as decided for SL5.1a. Its four calls of the now-privatenvx::host::artifacts::absolutecallstd::path::absolute, which that function wraps, and its import no longer namesartifacts.Old tests of the area
security_checklist::a_staged_image_that_was_replaced_fails_its_checktohost::sandbox::distro::tests, andsecurity_checklist::a_scratch_image_is_claimed_by_one_launch_and_checked_again_after_a_releasetohost::sandbox::scratch::tests, where they make their private directories withhost::vm::create_private_dirinstead of the checklist's helper.host::artifacts,host::sealandhost::sandbox::{distro, layer, scratch}, now built withcli, as their modules are; the CLI's tests ofartifacts, ofNVX_OPENVMM(cli::artifacts::artifacts_list_every_guest_in_order,cli::a_relative_openvmm_override_is_relative_to_the_working_directory, and the sandbox and one-shot runs that name it) and ofNVX_AUTO_DOWNLOAD(cli::download).Test changes
python scripts/check_test_changes.py --base 008035d2893lists 140 changes to existing tests and 6 added items, hencetests-modified:cli-gated now build only withcli: thetestsmodules ofhost::artifacts,host::sealandhost::sandbox::{distro, layer, scratch}, and, inhost::sandbox::options::testsandhost::sandbox::tests::specification, the tests that build layers (distro_manifest_binds_the_layer,systemd_entrypoints_and_images_are_refused_independently,sandbox_allows_non_systemd_sbin_init,the_entrypoint_check_needs_no_manifest_and_precedes_the_distro_verification,sandbox_rejects_systemd_from_bound_distro_metadata,distro_manifests_are_strict_json,layer_values_are_role_path_uuidand the proptestcanonical_layer_uuids_round_trip), with their helpers (Layer,distro_sha256,UUID). CI'scargo test --all-featuresruns them all, as before.host::sandbox::options::tests,host::sandbox::tests::specification,tests/cli/artifacts.rs,tests/cli/lifecycle.rsandtests/security_checklist.rsstop importing the private items.tests/cli.rs:an_interrupted_start_keeps_its_claim_until_recovery_confirms_exitchecked the claim by checking the recordedScratchBindingagainst the image. It now runsnvx-rs sandbox runon the same images: while the interrupted VM holds the claim, the run fails withscratch-claimed("another sandbox claims the ext4 scratch image …"), and once recovery confirms the exit, the same run succeeds.run_boots_each_guest_with_its_default_memoryiteratedGuest::ALL; it now names each guest ofnvx.py, its initramfs and its default RAM (alpine 128 MiB, ubuntu and azurelinux 512 MiB).tests/cli/artifacts.rs:artifacts_list_every_guest_in_orderexpects the literal names,alpine,ubuntu,azurelinux, instead ofGuest::ALL's.tests/cli/lifecycle.rs: the helperassert_bindingsandlifecycle_of_a_sandbox_whose_upper_is_in_ramcompared the recorded bindings with bindings that the test made withDistroBinding::verifyandScratchBinding::bind. They now check the recorded serde form from outside, with the new helpersassert_distro_bindingandassert_seal: the version, format, identity, the image's seal (version, scheme, kind and length), the manifest's absence and the policy verdict, and the scratch binding's fields and seal. The device, file IDs and times that the test can't read portably are covered by the new unit test below and by each start's check.tests/security_checklist.rs:a_launch_takes_a_new_private_log_and_keeps_every_entry_that_it_did_not_createcompared the device and file ID ofFileSeal::offor the log's handle and its path; it now compares them with a test-localfile_id, which reads whatFileSeal::ofread:st_devandst_inoon Linux, and on Windows the volume serial number and file ID ofFILE_ID_INFO, or ofBY_HANDLE_FILE_INFORMATIONwhere that has none.host::cli::sandbox::tests::provision_records_the_bindings_that_verification_and_the_scratch_binding_make, which runssandbox provisionin process, for a scratch and a RAM upper, and checks that the recorded distro binding equals the one thatDistroBinding::verifymakes, that the scratch binding equals the one thatScratchBinding::bindmakes, and that the RAM upper records none; the helpersSEAL_SCHEME,assert_sealandassert_distro_bindingoftests/cli/lifecycle.rs; and the Linux and Windowsfile_idof the checklist.Validation
local_gates.py --files(fromdev) selectstest-changes,markdown-links,test-layout, thecheck-nvx-rssteps,nvx-clion both systems and the microVM tests; I ran them from this branch's action definitions, with Rust 1.95.0, locally on Windows, onnvx-mshv-test(Azure Linux 3, kernel 6.18, linux-mshv, virtual machine) and onnvx-kvm-test(Azure Linux 3, kernel 6.6, linux-kvm, virtual machine), in temporary worktrees.The checks first ran on
fee70396c43and, after a code review's two fixes (SEAL_VERSION's gate, which the macOS check showed unused there, and the checklist'sfile_idfallback), on0abb5ff4270, on a local base of SL6.3's and SL6.6a's pre-merge heads. After both merged, SL6.6b and this branch were rebased onto671a192d0a5with no conflicts, andgit range-diffshows=for every commit. On this head,508170fbefd:cargo fmt --all --check-D warnings:--all-targets --all-features,--lib,--lib --no-default-features,serde,cliandtestingalone--target x86_64-unknown-linux-gnu--target x86_64-unknown-linux-musl --no-default-features --features guest -D warningscargo check --all-targets --all-features --target aarch64-apple-darwinhost/snapshot/tests.rs, is the base'scargo test --locked --all-featurescli111 passed, 2 ignored) and the doc tests,nvx-rs/src/lib.rs - (line 57)included. Under the load of a second suite,cli::exec_lock::a_retry_that_waits_for_the_lifecycle_lock_past_the_deadline_is_busyonce found no round fast enough ("no round delayed a retry of the exec past its deadline"); it passed on its rerun and on SL6.6b's, and this PR doesn't touch itcargo test --locked,cargo build --locked --lib --no-default-features,cargo test --locked --lib --no-default-featuresRUSTDOCFLAGS=-D warnings cargo doc --locked --no-deps --all-featurescargo +1.89 check --locked --all-targets --all-featurespython scripts/public_api.pycheck-guest-binaries,build-guest-binaries,test-guest-binariescheck_test_layout.py,check_markdown_links.py,check_matrix.py <worktree> 99d2022085fpython3 scripts/nvx.py test-microvm --backend mshvwithmanaged-exec-config,sandbox-gpt-layer,sandbox-lifecycle,sandbox-proxy-only,sandbox-ram-upper,snapshot-core,snapshot-tiersandvm-lifecycle, withNVX_AUTO_DOWNLOAD=0, this head'snvx-rsand the artifacts of CI run 43203015701 (OpenVMM at the pin,14dc4116ec7, its provenance and SHA-256 checked, and the kernel, Alpine and Ubuntu distro artifacts with the scratch template): all 8 passed, as on0abb5ff4270. The CLI found its artifacts and OpenVMM in the checkout, and staged, verified, claimed and restored the images as before.nvx-kvm-test(kernel 6.6): onfee70396c43, everycheck-nvx-rsstep passed but for the lib's 28guest::tests and 7 guest-binary tests that fail there on the base too, by name; on0abb5ff4270, Clippy with every feature and withcli, the integration tests with every feature (207 passed) and the lib's tests ofhost::sandbox,host::cli,host::sealandhost::artifacts(331 passed) passed.-D warnings, with every feature, withcliand without default features, on Windows and for Linux, and the first commit, tests only, passes the tests that it changes on its own (Windows: the lib'shost::sandbox,host::cli::sandbox,host::sealandhost::artifactstests,cliandsecurity_checklist).validate-nvxunittest list passed on Windows (1824 tests, 73 skipped); this PR changes no script.Left to CI: the microVM scenarios on KVM and WHP, and
openvmm-ci, for the unchanged pin.