Skip to content

nvx-rs slimming 3.1.1: the old CLI moves into nvx-cli unchanged #1106

Closed as not planned

Description

Parent: #1083, in #1076. Needs: #1092, #1093. Unblocks: #1107, #1112, #1125.

Goal. The CLI moves out of nvx into nvx-cli, and behaves as before. First, the crate-private helpers that it uses become #[doc(hidden)] pub without the cli feature; then the nvx-rs binary moves, and then nvx-rs/src/host/cli/. The CLI reaches what phase 4 moves into nvx-cli through local alias modules, so those later moves don't edit its users.

Notes.

  • The move counts only edited lines. The CLI's crate:: imports become nvx::.
  • The exposed helpers are temporary. Their docs say so: phase 4 moves or deletes them, and SL6.8c removes the last of them from nvx.

PRs, in order. Each PR has one goal, leaves dev green, and names in its description each old test of its area as kept, rewritten or retired, with each change that check_test_changes.py reports. Its tests follow the repository's test layout: a module's unit tests, and the code that only they use, sit in its tests.rs or tests/ and move with it. The estimates count core lines (code, not comments, docs or tests) and counted files; each PR records its measured values. Each PR does what its Scope says and no more: a case, input or layout that its Scope doesn't name, and whatever "Not in this PR" lists, is out of scope. Address every review comment within the scope, and ask before acting on one that asks for more. A PR whose measured core lines pass the stop that its Estimate names (twice the estimate, at most 600) stops and asks before continuing.

  1. SL3.1a: The network parsers that the CLI uses are public, without the cli feature.

    • Objective: The CLI cannot move to nvx-cli while the network parsers and strict policy-document reader it calls remain crate-private or available only with cli. This PR exposes only those existing entry points so the later move compiles without changing their behavior.
    • Contents: The parsers of loopback forwards, proxy endpoints and native rules, and policy::json::read_document with its ReadError, become #[doc(hidden)] pub, as does the policy::json module, and their cfg(feature = "cli") gates go (nvx-rs/src/host/network/{loopback, proxy, rule}.rs, policy/json.rs and policy/mod.rs). SL6.7b moves the policy-file reader, with policy::json, into nvx-cli; once nvx-cli has its own option parsers (SL3.10c), SL6.8c removes the loopback, proxy-endpoint and native-rule parsers from nvx.
    • Scope:
      • nvx-rs/src/host/network/loopback.rs, proxy.rs and rule.rs: make the CLI's loopback-forward, proxy-endpoint and native-rule parsers #[doc(hidden)] pub and remove their cli gates.
      • nvx-rs/src/host/network/policy/json.rs and policy/mod.rs: expose the json module, read_document and ReadError as #[doc(hidden)] pub without the cli feature.
      • Keep the existing parser and strict JSON-reader tests in nvx, and run them when host is enabled without cli.
    • Not in this PR:
      • Changing accepted network syntax, policy JSON validation, errors or normalization; this PR changes visibility and feature gates only.
      • Moving the policy-file reader to nvx-cli; SL6.7b does that after its remaining library users are gone.
      • Writing nvx-cli's own option parsers or deleting these exports; SL3.10c adds the parsers and SL6.8c removes the temporary exports.
      • Exposing other network internals such as lowering, address parsing or policy compilation; no CLI caller needs them.
    • Approach: Change the existing items' visibility, add #[doc(hidden)], and remove only the cli conditions that guard them or their tests. Do not add wrappers, duplicate parsers, reorganize the network modules or alter parsing code.
    • Done when:
      • The loopback-forward, proxy-endpoint and native-rule parser tests pass with host and without cli.
      • The strict JSON reader's duplicate-key and malformed-document tests pass with host and without cli.
      • The exposed items are reachable through nvx::host::network only where the CLI move needs them.
    • Needs: nothing.
    • Estimate: 30 core lines, 5 counted files. Past 60 core lines, stop and ask before continuing.
  2. SL3.1b: The sandbox and artifact helpers that the CLI uses are public, without the cli feature.

    • Objective: The CLI's one-shot launch, sandbox option and artifact calls are private or gated by cli, so nvx-cli cannot keep using them after the move. This PR temporarily exposes those existing helpers without changing launch or artifact behavior.
    • Contents: The one-shot launch (one_shot_openvmm_arguments, one_shot_kernel_command_line, PreparedLaunch::one_shot and the boot-token delivery), guest_gateway, parse_decimal, has_kernel_separator, require_artifact and REPO_BUILD_DIR become #[doc(hidden)] pub, and their cli gates go (nvx-rs/src/host/sandbox/{mod, plan, prepared}.rs and nvx-rs/src/host/artifacts/{mod, require}.rs). Later PRs move or delete them, and SL6.8c removes the last of them from nvx.
    • Scope:
      • nvx-rs/src/host/sandbox/mod.rs, plan.rs and prepared.rs: expose parse_decimal, has_kernel_separator, guest_gateway, the two one-shot renderers, PreparedLaunch::one_shot and boot-token delivery as #[doc(hidden)] pub.
      • nvx-rs/src/host/artifacts/mod.rs and require.rs: expose require_artifact and REPO_BUILD_DIR as #[doc(hidden)] pub.
      • Remove the exposed items' cli gates, while keeping their existing one-shot launch, parsing and artifact tests in nvx.
    • Not in this PR:
      • Changing OpenVMM arguments, kernel command-line tokens, boot-token delivery or one-shot launch semantics; callers must behave as before.
      • Moving or redesigning sandbox launch code and artifact discovery; later PRs move or delete these helpers after their library users leave.
      • Adding a general numeric parser, command-line framework or artifact abstraction; the CLI needs only the named existing functions and constant.
      • Exposing other sandbox planners, checked-image helpers or artifact internals; no moved CLI call requires them.
    • Approach: Adjust visibility and feature conditions on the existing definitions and re-exports. Keep their signatures and implementations intact, mark the temporary API #[doc(hidden)], and do not introduce forwarding modules or copies.
    • Done when:
      • The one-shot launch tests still check the same OpenVMM arguments, kernel command line and boot-token delivery without cli.
      • The decimal, kernel-separator, guest-gateway and artifact requirement tests pass with host and without cli.
      • nvx-cli can import exactly the named helpers from nvx.
    • Needs: nothing.
    • Estimate: 50 core lines, 5 counted files. Past 100 core lines, stop and ask before continuing.
  3. SL3.1c: The process helpers and path rules that the CLI uses are public, without the cli feature.

    • Objective: The moved CLI still needs timed child waits, termination, killing, the supervisor's child and host path rules. This PR temporarily makes those existing items reachable from nvx-cli without requiring the cli feature.
    • Contents: The timed wait, termination and kill of nvx-rs/src/host/spawn.rs, the supervisor's child, and host::paths, which nvx-rs/src/host/mod.rs declares crate-private, become #[doc(hidden)] pub, and their cli gates go. Later PRs move or delete them, and SL6.8c removes the last of them from nvx.
    • Scope:
      • nvx-rs/src/host/spawn.rs: make the CLI-used timed wait, terminate and kill methods #[doc(hidden)] pub, and remove their cli gates.
      • nvx-rs/src/host/supervisor/launch.rs: expose the launched supervisor's child accessor as #[doc(hidden)] pub without its cli gate.
      • nvx-rs/src/host/mod.rs and paths.rs: make host::paths and the path functions used by the CLI #[doc(hidden)] pub.
      • Keep the existing process and host::paths tests in nvx, available with host and without cli.
    • Not in this PR:
      • Changing wait deadlines, process signaling, verified-process rules or supervisor behavior; this PR changes access only.
      • Moving path rules or process helpers into nvx-cli; later PRs do so after their remaining library users are gone.
      • Adding async process APIs, recursive path policy, new canonicalization cases or cross-platform fallbacks; no moved CLI caller needs them.
      • Exposing the rest of spawn or supervisor internals; only the named CLI calls become public.
    • Approach: Promote the existing methods and module along their current paths, mark them #[doc(hidden)], and remove only their cli conditions. Do not wrap process handles, duplicate path code or refactor the supervisor.
    • Done when:
      • Timed wait, terminate and kill tests retain their current results with host and without cli.
      • host::paths tests retain their current absolute-path, resolution and platform behavior without cli.
      • The moved CLI can reach the supervisor's child and only the process and path helpers it already calls.
    • Needs: nothing.
    • Estimate: 30 core lines, 4 counted files. Past 60 core lines, stop and ask before continuing.
  4. SL3.1d: nvx-rs is built from nvx-cli.

    • Objective: The nvx-rs executable must belong to nvx-cli before the CLI implementation moves there. This PR moves the binary and its integration tests, and redirects every repository build to the new package while preserving the executable's path and behavior.
    • Contents: git mv of nvx-rs/src/bin/nvx-rs.rs to crates/nvx-cli/src/bin/nvx-rs.rs; it still calls nvx::host::cli. Cargo discovers the binary by its file name without editing nvx-cli's manifest. Remove the old declaration from nvx in the same change, so exactly one package owns the executable. CI and the scripts build it with -p nvx-cli (ci.yml, nvx_rs.py, scripts/setup/setup-linux.sh and scripts/setup/setup-windows-whp.ps1), and it lands in nvx-rs/target as before. The CLI's integration tests (nvx-rs/tests/cli.rs and nvx-rs/tests/cli/) move with it: they keep CARGO_BIN_EXE_nvx-rs, and take nvx-fake-openvmm from the workspace build instead of CARGO_BIN_EXE_nvx-fake-openvmm. The CLI's tests of the restore's network policy and of a restrictive umask move with them, and CI's two jobs that build the binary and record its provenance follow.
    • Scope:
      • Move nvx-rs/src/bin/nvx-rs.rs to crates/nvx-cli/src/bin/nvx-rs.rs for Cargo auto-discovery; it continues to call nvx::host::cli::main. Remove the old binary declaration without editing nvx-cli's manifest.
      • Move nvx-rs/tests/cli.rs and nvx-rs/tests/cli/ into crates/nvx-cli/tests/, including the restore-network-policy and restrictive-umask scenarios.
      • Keep CARGO_BIN_EXE_nvx-rs; obtain nvx-fake-openvmm from the workspace build rather than a same-package Cargo variable.
      • Update .github/workflows/ci.yml, scripts/nvx_tools/nvx_rs.py, scripts/setup/setup-linux.sh and scripts/setup/setup-windows-whp.ps1 to build -p nvx-cli.
      • Keep Cargo output at nvx-rs/target, and update both CI binary-and-provenance jobs to read and publish the same paths.
    • Not in this PR:
      • Moving nvx-rs/src/host/cli/; SL3.1e moves the implementation after the binary's package is established.
      • Changing CLI commands, output, errors, arguments or exit statuses; this is a package move.
      • Renaming the executable, its environment variables, provenance file or target directory; scripts and packages rely on the current names.
      • Moving or rewriting nvx-fake-openvmm; its workspace executable is only located differently by these tests.
      • Cleaning up CI or setup scripts beyond the package selector and paths forced by the move.
    • Approach: Use git mv for the binary and integration-test tree, retaining Cargo auto-discovery in the CLI package and removing the old declaration. Change only the forced package selection and fake executable lookup; rely on the workspace target-directory configuration instead of adding copy steps, new build scripts or test harnesses.
    • Done when:
      • CI and both setup scripts build nvx-rs with -p nvx-cli and find it under nvx-rs/target.
      • Cargo metadata lists exactly one nvx-rs binary, owned by nvx-cli, and the CLI manifest is unchanged by the move.
      • The moved integration tests find nvx-rs through CARGO_BIN_EXE_nvx-rs and the workspace-built fake OpenVMM.
      • The moved command scenarios, including restore network policy and restrictive umasks, pass as before.
      • Both CI jobs record and upload the binary and provenance from their existing output paths.
    • Needs: SL0.2c, in nvx-rs slimming 1.1.2: one Cargo workspace, and the new crates' empty shells #1092.
    • Estimate: 40 core lines, 5 counted files. Past 80 core lines, stop and ask before continuing.
  5. SL3.1e: The CLI's code lives in nvx-cli, and behaves as before.

    • Objective: The CLI implementation still lives inside the nvx library after its executable has moved. This PR moves that implementation into nvx-cli without changing commands, using short-lived local aliases for helpers that move later.
    • Contents: git mv of nvx-rs/src/host/cli/ (6.4K core lines), with what dev added to it: run --restore-network-policy and the scratch template's download. Its crate:: imports become nvx::, except for NVXC, the helpers that phase 4 moves into nvx-cli, and the old error: it reaches those through local modules (nvxc, images, paths, artifacts, egress, mounts and errors) that re-export them from nvx until then. paths gives a free verify, which every CLI caller uses instead of the method.
    • Scope:
      • Move nvx-rs/src/host/cli/ into crates/nvx-cli/src/, including run --restore-network-policy, the scratch template's download support, and every tests.rs and tests/ below it, whose test-only code (Syntax::assert_lists, Curl::plain) stays in them.
      • Replace moved code's crate:: references with nvx:: references where the called API remains in nvx.
      • Add local nvxc, images, paths, artifacts, egress, mounts and errors modules that re-export the current nvx items until later moves replace them.
      • In the local paths module, expose a free verify function and switch every moved CLI caller from the old method to it.
      • Keep the existing command modules, command dispatch, output, errors and unit-test cases otherwise unchanged.
    • Not in this PR:
      • Rewriting commands onto the new launch or store interfaces; later groups switch dependency-closed command sets.
      • Copying helper implementations into nvx-cli; aliases prevent duplicate implementations until each helper can move.
      • Changing command-line syntax, output compatibility, error codes, download behavior or sandbox behavior.
      • Renaming, reorganizing or cleaning up the moved CLI modules beyond import edits forced by the new crate.
      • Moving the aliased helpers now; their remaining nvx users prevent a move in this PR.
    • Approach: Use git mv for the CLI tree, then make mechanical import edits. Keep each temporary local module as a thin re-export, with only the free paths::verify adapter required by later path moves; do not create a facade framework or duplicate code.
    • Done when:
      • All moved CLI unit tests pass from nvx-cli with their existing cases and expectations.
      • nvx-rs dispatches every existing command through the implementation now owned by nvx-cli.
      • The moved code reaches temporary dependencies only through the seven local alias modules.
      • Every moved path-verification caller uses the local free verify function.
    • Needs: SL3.1a, above; SL3.1b, above; SL3.1c, above; SL3.1d, above; SL0.3d, in nvx-rs slimming 1.1.3: the guest's and the host's OS layers live in nvx-sys #1093.
    • Estimate: 150 core lines, 3 counted files. Past 300 core lines, stop and ask before continuing.

Tests. SL3.1a–SL3.1c keep the library tests of the items that they expose in nvx (such as the network parsers', the strict JSON reader's, the one-shot launch's and host::paths' tests), now run without the cli feature. SL3.1d's build and script checks build nvx-rs with -p nvx-cli into nvx-rs/target, and SL3.1d moves the CLI's integration-test root and modules (nvx-rs/tests/cli.rs and nvx-rs/tests/cli/**) with the binary: they pass as before, find nvx-rs through CARGO_BIN_EXE_nvx-rs, and take nvx-fake-openvmm from the workspace build. SL3.1e moves the CLI's unit tests (nvx-rs/src/host/cli/**) to nvx-cli, where they pass as before.

Done when: every PR above has merged, with dev green.

Activity

  1. esaurez commented on Nov 3, 2026

    @esaurez
    ContributorAuthor

    Closing as not planned: the plan in #1076 changed. nvx stays the only crate, with no Cargo workspace and no new crates. NVX's own programs, its control protocol and the OS layers stay in nvx, private to it, and CI checks the public API against committed snapshots (#1091). The CLI stays under host::cli, and #1083 switches it to the new interface in place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions