Repository navigation
host: make the policy-file reader and the mount syntax private to the CLI (SL6.7b) - #1539
Merged
Pedro Henrique Penna (ppenna) merged 2 commits intoNov 12, 2026
Conversation
Contributor
This pull request changes existing testsIt modifies or removes 410 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 360 more, which the job's summary lists. Relocated unchanged: 0; added: 1. Compared the merge base |
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The review has no outstanding issues.
No open issues 🎉
What changed in this PR
This PR implements SL6.7b of the library-slimming workstream: it removes CLI-owned policy-file and mount helpers from nvx’s public API while retaining shared network normalization and internal VM/snapshot dependencies.
Changes:
- Makes policy reading and sandbox helpers crate-private, with CLI-only functionality gated by
cli. - Updates integration tests to avoid private APIs and aligns unit-test imports and feature gates.
- Updates documentation and removes 132 entries from each platform’s public API snapshot.
| File | Description |
|---|---|
nvx-rs/tests/cli/openvmm.rs |
Replaces private mount-parser dependencies with an independent fixture helper. |
nvx-rs/tests/cli/egress.rs |
Checks CLI output against expected rules and errors without calling private helpers. |
nvx-rs/src/protocol/cmdline.rs |
Attributes sandbox kernel-parameter checks to the CLI in documentation. |
nvx-rs/src/host/sandbox/tests/specification.rs |
Adjusts imports to use internal mount types and test helpers. |
nvx-rs/src/host/sandbox/tests.rs |
Updates imports and validation paths after re-export removal. |
nvx-rs/src/host/sandbox/options.rs |
Makes sandbox option types, limits, and validators crate-private. |
nvx-rs/src/host/sandbox/mount/tests.rs |
Exposes target validation through the internal test module. |
nvx-rs/src/host/sandbox/mount/request.rs |
Gates mount parsing and validation while retaining shared error conversion. |
nvx-rs/src/host/sandbox/mount/mod.rs |
Narrows mount visibility and gates CLI-only types and modules. |
nvx-rs/src/host/sandbox/mount/host_paths.rs |
Makes host-path validation crate-private and removes an obsolete allowance. |
nvx-rs/src/host/sandbox/mount/aggregate.rs |
Makes mount planning crate-private. |
nvx-rs/src/host/sandbox/mod.rs |
Gates CLI helpers, removes re-exports, and retains shared geometry support. |
nvx-rs/src/host/paths/tests.rs |
Gates resolution tests and their filesystem import with cli. |
nvx-rs/src/host/paths.rs |
Gates path resolution and its platform helpers with cli. |
nvx-rs/src/host/network/rule.rs |
Removes a documentation link to the now-private policy module. |
nvx-rs/src/host/network/policy/mod.rs |
Makes policy compilation functions, results, and limits crate-private. |
nvx-rs/src/host/network/mod.rs |
Makes the policy module crate-private and CLI-gated. |
nvx-rs/src/host/network/lowering.rs |
Updates documentation to describe the private policy reader. |
nvx-rs/src/host/network/arguments.rs |
Removes the private-module link from public API documentation. |
nvx-rs/src/host/mod.rs |
Makes sandbox crate-private and documents its remaining shared uses. |
nvx-rs/src/host/artifacts/require.rs |
Removes item-level gates now supplied by the module gate. |
nvx-rs/src/host/artifacts/mod.rs |
Gates artifact requirement helpers and their re-exports with cli. |
nvx-rs/README.md |
Moves private-helper details out of the public module reference. |
nvx-rs/public-api/windows.txt |
Removes policy and sandbox paths from the Windows API snapshot. |
nvx-rs/public-api/linux.txt |
Removes policy and sandbox paths from the Linux API snapshot. |
Review effort: Balanced
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/slim-sl6-6c-sandbox-test-only
branch
from
November 12, 2026 14:35
eed421f to
e757a18
Compare
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/slim-sl6-7b-policy-private
branch
from
November 12, 2026 14:39
ede4ebe to
893419a
Compare
This was referenced Nov 12, 2026
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/slim-sl6-6c-sandbox-test-only
branch
from
November 12, 2026 20:09
e757a18 to
8abb8f7
Compare
Base automatically changed from
agents/slim-sl6-6c-sandbox-test-only
to
feature/nvx-refactor
November 12, 2026 20:34
SL6.7b (#1124) makes host::network::policy and host::sandbox private to the CLI. Two of the CLI's scenario tests reached them through their public paths, which they cannot once those are private, so they drive the nvx-rs binary alone, with the same expectations: - egress_compile_prints_the_library_lowering compared what `nvx-rs egress compile` printed with the rules of compile_policy_file, and its refusals with the reader's error. It keeps every case's native rules, error code and message fragments, which the binary must print, and the grammar, model and property tests of host::network::policy check the reader's own rules and refusals. - two_share_command_line_room spells the tag of OpenVMM's virtio-fs device, `microvm`, as the lifecycle tests do, in place of MOUNT_TAG, and cold_run_expected splits a fixture's --mount and --mount-child values as OpenVMM reads them, with a helper of its own, in place of parse_mount_value: independently of the CLI's parser, as its documentation says. Part of #1124 (SL6.7b). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… CLI host::network::policy and host::sandbox were public API of nvx, although only NVX's CLI reads egress policy files and the options of nvx-rs sandbox and nvx-rs run: the policy-file reader and its limits, the rules that it compiles, the --mount syntax, the shares that it requests and their plan, the checks of the options, and the sandbox's defaults. They become crate-private where they are, gated by the features of their users, with no change of behavior: - host::network::policy becomes a pub(crate) module that only the cli feature builds, with its JSON reader, compile_policy_file, compile_policy_bytes, compile_policy and CompiledEgressPolicy, and its limits, MAX_RULES_PER_ACTION, MAX_POLICY_FILE_SIZE and MAX_JSON_DEPTH. The lowering already takes MAX_RULES directly, and the shared normalization stays public: EgressRule, Destination, PortSelector and NetworkPolicy::native_egress_rules. - host::sandbox becomes pub(crate). Its options module, with SandboxOptions, PolicyPathOption, SandboxOperation and the checks of the options, takes cli, and so do, in its mount module, the --mount syntax, SandboxMount, the mount types and limits, plan_mounts and plan_mounts_with, the checks of host paths and path_text, and, at its root, the defaults, parse_workload_identity, parse_decimal, has_kernel_separator and require_file. What the crate uses outside the CLI stays ungated: block_geometry and BlockGeometry, which host::vm and host::snapshot read, MOUNT_TAG, which a snapshot's key names, refused and os_error. - host::sandbox no longer re-exports the mount types, nor its mount module the reserved targets of protocol::share or validate_mount_target, which nothing reads at those paths once they are private. The sandbox's tests import the mount types from the mount module, and validate_mount_target through the mount module's tests, as they do validate_mount_host_paths_with. - What these users leave to the CLI takes cli too: host::artifacts::require_existing, which only require_file and the CLI's require_artifact call, and host::paths::resolve, with without_verbatim_prefix and its two tests, which only the CLI and the checks of shares call. The unit tests of host::network::policy and host::sandbox, and the two host::paths tests of resolve, take cli with their modules, so the all-features tests run them as before. The public API snapshots lose 132 lines on each platform, every path under nvx::host::sandbox and nvx::host::network::policy, and gain none. The docs of host, host::network and host::sandbox, and the doc links of openvmm_arguments, Destination and the lowering, name the reader and the profile as the CLI's; the README drops the two modules' rows and sections and holds their details in Egress policy files and Sandbox input contract. Part of #1124 (SL6.7b). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/slim-sl6-7b-policy-private
branch
from
November 12, 2026 20:36
893419a to
484e0c7
Compare
Pedro Henrique Penna (ppenna)
marked this pull request as ready for review
November 12, 2026 20:37
Pedro Henrique Penna (ppenna)
merged commit Nov 12, 2026
adfc481
into
feature/nvx-refactor
86 checks passed
Pedro Henrique Penna (ppenna)
deleted the
agents/slim-sl6-7b-policy-private
branch
November 12, 2026 20:58
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 #1124 (SL6.7b, "The policy-file reader and the mount syntax are private to the CLI"). Parent #1088, umbrella #1076.
It needs SL6.6c (#1538), which deletes the twelve
host::sandboxitems that this PR would otherwise leave without a caller, so that this one stays visibility-only, and SL6.3 (#1530), SL6.7a (#1298) and SL6.4 (#1533). All have merged; this branch starts from27c61345c57, the tip after SL6.6c.What and why
The egress policy-file reader and the
--mountsyntax are the CLI's, buthost::network::policyandhost::sandboxwere public API ofnvx. This PR does SL6.7b's Scope: it makes them private to the CLI where they are, without changing policy compilation, mount parsing, export planning or host-path checks. Two commits:tests: check the policy reader and the mount syntax through the CLI(e48c68c6): the two integration tests that reached these modules through their public paths drive the binary alone, with the same expectations (Test changes, below). It changes no production code, so it passes on its own, before the visibility change.host: make the policy-file reader and the mount syntax private to the CLI(484e0c7f):host::network::policybecomes apub(crate)module that onlyclibuilds, with its JSON reader,compile_policy_file,compile_policy_bytes,compile_policy,CompiledEgressPolicy, and its limits,MAX_RULES_PER_ACTION,MAX_POLICY_FILE_SIZEandMAX_JSON_DEPTH. The network lowering already takesMAX_RULESdirectly (lowering.rs), so that item needed no change, and the shared normalization stays public:EgressRule,Destination,PortSelector,NetworkPolicy::native_egress_rulesandMAX_RULES.host::sandboxbecomespub(crate). Itsoptionsmodule (SandboxOptions,PolicyPathOption,SandboxOperationand the checks of the options) takescli, and so do, inmount, the--mountsyntax,SandboxMount, the mount types and limits,plan_mounts,plan_mounts_with, the checks of host paths andpath_text, and, at the root, the defaults,parse_workload_identity,parse_decimal,has_kernel_separatorandrequire_file. What the crate uses outside the CLI stays ungated:block_geometryandBlockGeometry, whichhost::vmandhost::snapshotread,MOUNT_TAG, which a snapshot's key names,refusedandos_error.host::sandbox's re-export of the mount types, andmount's ofprotocol::share's reserved targets, which stay public there, and ofvalidate_mount_target. The sandbox's unit tests import the mount types frommount, andvalidate_mount_targetthroughmount::tests, as they importvalidate_mount_host_paths_with.clitoo:host::artifacts::require_existing, which onlyrequire_fileand the CLI'srequire_artifactcall, andhost::paths::resolve, withwithout_verbatim_prefixand its two tests, which only the CLI and the checks of shares call. Thecfg_attr(not(feature = "cli"), allow(...))attributes that the gates replace go.host's,host::network's,host::sandbox's andmount's docs name the reader and the profile as the CLI's, andopenvmm_arguments,Destinationand the lowering no longer link topolicy.protocol::cmdlinesays that the CLI checks a sandbox's kernel parameters, where it saidnvx::host::sandbox. The README drops the rows and sections ofnvx::host::network::policyandnvx::host::sandboxand keeps their details in its sections Egress policy files and Sandbox input contract.nvx::host::sandboxandnvx::host::network::policy, and gain none. No path under either module remains.Policy grammar, rule normalization, mount syntax, option validation, export planning and path rules don't change, and neither do
BOOT_CONTRACT_VERSIONandCONTROL_CONTRACT_REVISION.Size
Measured against
27c61345c57, the tip after SL6.6c (#1538), 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. The measuring script counts 162 added code lines in 16 production files, and every one of them makes an item crate-private (pub(crate)), gates it bycli, or is an import that the gates force, with its continuation lines; rustfmt rewrapsSYSTEMD_ENTRYPOINTS, whichpub(crate)lengthens. The rest of the production diff is docs and the removed attributes and re-exports.Old tests of the area
host::network::policy(the grammar, model and property tests and those of its JSON reader) and ofhost::sandbox(its own, the specification tests, and those ofmountandoptions), with the same assertions, built withclias their modules now are; CI'scargo test --all-featuresruns them all, as before. So the grammar, model and property tests still compare the same native rules and failures; the--mounttests still cover access, ownership, policy paths, commas, links and reserved targets; and the option tests still attribute policy paths to the preceding mount and check the shares' exports.cli::egress::egress_compile_prints_the_library_lowering, and the helpers oftests/cli/openvmm.rs.Test changes
python scripts/check_test_changes.py --base 27c61345c57lists 410 changes to existing tests and 1 added helper, hencetests-modified. By kind:cligates, bodies unchanged (405): the tests, helpers, imports, inner attributes and module declarations of the test modules that now build only withcli, as their modules do: 298 inhost::network::policy(itstests,tests::{generator, grammar, model, properties}andjson::tests), 105 inhost::sandbox(itstests,tests::specification,mount::testsandoptions::tests), andhost::paths::tests::{resolution_follows_links_and_keeps_missing_components, resolution_keeps_the_verbatim_path_that_alone_names_the_object}, the two tests ofresolve, which takescli. Of these, only imports and one path change:host::sandbox::testsandtests::specificationimport the mount types frommount, andvalidate_mount_targetthroughmount::tests, which re-exports it, sincehost::sandboxandmountno longer re-export them;file_shares_take_no_policy_paths_or_reserved_targetscallsmount::tests::validate_mount_target, with the same assertions.host::paths::testsimportsstd::fswithcli, which only the two tests ofresolveuse.tests/cli/egress.rs(2, approved in the slice's decision):egress_compile_prints_the_library_loweringkeeps every case's literal native rules, error code and message fragments, whichnvx-rs egress compilemust print, and no longer compares them withcompile_policy_file, which is private now, and its imports drop it. The grammar, model and property tests ofhost::network::policycheck the reader's own rules and refusals.tests/cli/openvmm.rs(2, and 1 added):two_share_command_line_roomspells the tag of OpenVMM's virtio-fs device,microvm, as the lifecycle tests do, in place ofMOUNT_TAG, andcold_run_expectedsplits a fixture's--mountand--mount-childvalues with the new helpermount_value, as OpenVMM reads them, in place ofparse_mount_valueandMountAccess: independently of the CLI's parser, as its docs say. Thedry_run,validationandone_shottests that call them pass unchanged.doc/acceptance-case-matrix.mdnames none of these tests as coverage, andcheck_matrix.pypasses.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 and onnvx-mshv-test(Azure Linux 3, kernel 6.18, linux-mshv, virtual machine), in temporary worktrees.Before this merge turn, the branch was rebased with SL6.6c onto
5715bb6d709, after SL7.8c, SL6.14, SL4.4a to SL4.4c, SL6.11b, SL6.11d and SL6.13b, and the checks below ran on that rebase,41430a0ddb4. Only the README conflicted: SL6.14 rewrote thenvx::host::reportrow and section beside the row and the section ofnvx::host::sandboxthat this PR deletes, so the resolution keeps the tip's text and deletes those two, andgit range-diffshows only those context lines changed. At this turn the branch was rebased with SL6.6c onto55f44aa4607, after SL4.4d (#1545), and then onto27c61345c57, after SL6.6c merged, both with no conflicts:public_api.py --updateleaves the snapshots as they are, andgit range-diffshows=against41430a0ddb4, so this head,484e0c7ff03, carries the same change. Its rebase onto8abb8f7f031,49ba0bab976, passed the table's Windows checks again, with SL4.4d's tests (with every feature, lib 1061 passed, 18 ignored, andcli113 passed, 2 ignored; with default features, lib 541 passed, 10 ignored; without, 191 passed). On41430a0ddb4:cargo fmt --all --check-D warnings:--all-targets --all-features,--lib,--lib --no-default-features,serde,cliandtestingalone--target x86_64-unknown-linux-gnu, and so did--all-targetswith default features--target x86_64-unknown-linux-musl --no-default-features --features guest -D warningscheck-guest-binaries)cargo check --all-targets --all-features --target aarch64-apple-darwinhost/snapshot/tests.rs, is the base'scargo test --locked --all-featurescli114 passed, 2 ignored) and the doc testscli124 passed) and the doc testscargo 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 mshvon41430a0ddb4, withNVX_AUTO_DOWNLOAD=0, its releasenvx-rsand the artifacts of CI run 43285713039, the run of host: speak NVXC v2, and stream execs in the CLI (SL4.4c) #1541, whose head has the tree of5715bb6d709(OpenVMM at the pin,14dc4116ec7, its provenance and SHA-256 checked, and the kernel, the Alpine initramfs, and the Ubuntu distro layer with the scratch template): all 18 passed:managed-exec-config,sandbox-gpt-layer,sandbox-lifecycle,sandbox-proxy-only,sandbox-ram-upper,snapshot-core,snapshot-tiers,untiered-network-policyandvm-lifecycle;nvx-rs egress compileand launch with--network-egress-policy-file:l3-l4-egress-policy,l3-l4-egress-protocols,l3-l4-egress-port-rangesandipv6-egress-policy;nvx-rs run's--mountsyntax, policy paths and exports:filesystem-shares,filesystem-policy,filesystem-owner,filesystem-comma-pathsanddenied-filesystem-paths.-D warnings, with every feature, withcliand without default features, on Windows, and the first commit, tests only, passes the CLI's integration tests on its own (114 passed, 2 ignored).validate-nvxunittest list is unaffected: this PR changes no script.Left to CI: the microVM scenarios on KVM and WHP, and
openvmm-ci, for the unchanged pin.