Repository navigation
nvx-rs: break the host module into finer-grained modules #896
Description
Goal. Break nvx::host (nvx-rs/src/host/) into finer-grained modules, in three phases: make the dependency graph between its children acyclic and guard it, split its oversized files, and, optionally, group its children into layered subsystems. No phase changes behavior or the public API.
Today (dev 6af32ba0):
-
nvx::host(featurehost) has 17 direct children (nvx-rs/src/host/mod.rs:48-67):artifacts,cli(featurecli),filesystem,instance,launch,network,nvxs,platform,process,python(pub(crate)),report,sandbox,seal,session,store,supervisorandsys(private, Unix), besides the test-onlytest_support(mod.rs:68-69). -
Its 89 files hold about 29.9k production lines and 25.3k test lines, counting test-only files and inline
#[cfg(test)]modules as tests. -
The production references between those children form one strongly connected component of 8:
artifacts,filesystem,launch,platform,process,sandbox,storeandsupervisor. The rest is acyclic. A reference is acrate::,super::orself::path in ausetree or an expression, or one of the crate-root re-exportscrate::Artifacts,crate::guest_pathandcrate::resolve_guest_path(nvx-rs/src/lib.rs:138-141), outside comments andcfg(test)code. nvx-rs: make the host module's dependency graph acyclic #897 lists the three back-edges. -
The largest files, in production lines, without their inline tests:
File Production lines Inline test lines filesystem.rs2,041 1,685 platform/windows.rs1,468 358 sandbox/mount.rs1,190 0 instance.rs1,036 212 cli/sandbox/lifecycle.rs996 118 store/mod.rs987 0 cli/sandbox/mod.rs941 0 network/mod.rs928 988 artifacts.rs919 727 sandbox/plan.rs853 0
PRs, in order:
| Issue | Delivers | Needs |
|---|---|---|
| #897 | An acyclic graph between host's children: three items move down, and a guard test keeps it acyclic | Nothing |
| #898 | The oversized files, split into directory modules along their sections | #897: the artifacts split includes the helpers that #897 moves there, and its guard protects the layering |
| #899 | Host's children, grouped into private, layered subsystems that re-export them at today's paths | #897, preferably #898, and a decision whether its test-name changes are acceptable |
Invariants. Every phase keeps them. Together they are the contract of "no behavioral change":
- The public API is identical. The crate is published (
nvx-rs/Cargo.toml:12-14:publish = ["crates-io"],links = "nvx"), so every public path undernvx::keeps resolving, throughpub usere-exports where items move. Downstream code imports from every public child butseal:aci_edge_sandboxes/(which also re-exports the crate asaci_edge_sandboxes::nvx,aci_edge_sandboxes/src/lib.rs:62),tests/runtime-adapter/,nvx-rs/tests/andnvx-rs/src/bin/usenvx::host::{artifacts, cli::main, filesystem, instance, launch, network::policy, nvxs, platform::{SUPPORTED, Transport, process_start_time}, process, report, sandbox::{distro, mount, scratch}, session, store, supervisor::{Inherited, Launched, VmmCommand, spawn}}andnvx::{Artifacts, guest_path, resolve_guest_path}. Check: a diff of the public surface from rustdoc JSON (RUSTC_BOOTSTRAP=1 cargo rustdoc --lib --all-features -- -Z unstable-options --output-format json), walking reachable paths, re-exports, inherent methods and trait impls, forx86_64-unknown-linux-gnuandx86_64-pc-windows-msvc, the targets that docs.rs documents (Cargo.toml:18-20), with zero differences. - Test names are stable, unless a phase says otherwise. Two references select tests by name:
FAMILIESinscripts/nvx_rs_coverage.py:80-82selects the Python golden tests byhost::python::golden::(also indoc/ci.md:1694-1696), and the artifact-bundling step of.github/actions/check-nvx-rs/action.yml:73-98runscargo test --locked --lib --features bundled artifacts, a name filter. The inputs of.github/workflows/nvx-rs-mutants.yml:12-24givesrc/host/cli/sandbox/state.rsandhost::sandbox::as examples. - Host code stays under
nvx-rs/src/host/.SOURCE_PATTERN(scripts/nvx_tools/build_constants.py:214-230) treats every other file undernvx-rs/src/, excepttesting/, the binaries other than the guest's, and test modules, as an input of the guest executables, so host code elsewhere would change the guest source identity. - Unsafe code stays confined.
host/mod.rs:46denies it. Onlysys(Unix,mod.rs:65-67),platform::windows(platform/mod.rs:22-25),seal::windows(seal.rs:32-34) andpython::windows(python/windows.rs:7) allow it, besides four test modules (cli/session/tests.rs:988,sandbox/distro/tests.rs:138,sandbox/scratch/tests.rs:133,store/lifecycle/tests.rs:840). - The cfg matrix builds: Linux and Windows, on which the
nvx-rsjob of.github/workflows/ci.yml:78-94runs check-nvx-rs; other Unix hosts, throughplatform::other, which CI checks for macOS (aarch64-apple-darwin,action.yml:118-129); and the featureshost,cli,testing,guest,bundledandserde, and--no-default-features(action.yml:42-69). - Intra-doc links keep their targets. A link written with
super::can retarget silently when its file moves:[launch](super::launch)insupervisor/child.rs:166names the functionsupervisor::launch, but would name the modulehost::launchfrom a file inhost/, andcargo docwith-D warnings(action.yml:100-106) would not notice. Moved links usecrate::paths. - Nothing depends on source locations at run time. Host uses no
module_path!,file!,include_str!orinclude_bytes!, and its test fixtures resolve fromCARGO_MANIFEST_DIR(artifacts.rs:1030and1130,python/golden.rs:17). Moving code changes test names and source paths, not behavior.
Not in scope:
- Promoting host modules to the crate root, or into crates of their own: the guest source identity (invariant 3), the published crate's
links = "nvx", and the crate-privatepythonandsys, which would need public exposure. - Merging the private-file helpers that
instance.rs:84-205andstore/files.rsduplicate (io_error,private_options,write_private,remove_if_present, …). Those ofinstanceinclude public API, those of the store are store-private, and their semantics may differ.
Coordination. Open PRs edit the same files:
- The template and clone stack, nvx-rs: derive the compatibility keys of templates #879, nvx-rs: add the template store #881, nvx-rs: lease eligible templates to clones, and retire them #885, nvx-rs: reserve the launch of a leased clone, and document the lock order #886, nvx-rs: lower adapter plans into the plans of template captures #884, nvx-rs: capture templates into their store, and publish them #887 and nvx-rs: plan the clones of templates, and check their block geometry #888, in stack order, adds an 18th child,
host::template, and editshost/mod.rs,filesystem.rs,instance.rs,platform/{mod,linux,windows,other}.rs,store/{mod,files,lifecycle,record}.rs,supervisor/mod.rs,sandbox/{mod,plan,distro,scratch}.rs,sys/mod.rsandcli/sandbox/lifecycle.rs. At its head,templatejoins the cycle; nvx-rs: make the host module's dependency graph acyclic #897 names the two edges that whichever lands second resolves. - nvx-rs: mount the host export as a source of a root's mappings #864 and nvx-rs: bind a resolver file into entries, and return removable runtime binds #876 edit
filesystem.rs, and sandbox: refuse the (uid_t)-1 sentinel in --workload-user #829 editssandbox/mod.rs.
Each phase keeps re-exports at the old paths, so that these PRs rebase without API breaks, and #898 splits the files that they edit after they land.
Acceptance. #897 and #898 are merged, #899 is merged or declined, and every invariant above holds at each merge.
Activity
akhil9tiet commentedon Oct 25, 2026
lgtm