Repository navigation
guest: delete the old layered init and the managed agent's sandbox mode (SL7.8b) - #1534
Merged
Pedro Henrique Penna (ppenna) merged 2 commits intoNov 12, 2026
Conversation
Contributor
This pull request changes existing testsIt modifies or removes 159 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 102 more, which the job's summary lists. Test data
CI test wiring
Relocated unchanged: 0; added: 0. Compared the merge base |
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues remain for the cleanup of obsolete guest execution paths.
No open issues 🎉
What changed in this PR
Implements SL7.8b of #1123 by removing obsolete guest execution paths after layered boots moved to nvx-init. The retained mapping table, direct agent, layered-root execution, and blockless snapshot handling remain in place.
Changes:
- Deletes the old layered init and Azure Linux one-shot container helpers, including build and lint entries.
- Removes the managed agent’s sandbox mode and its unused private support code; rejects
ROOTFSvalues other than-. - Retires obsolete tests and updates retained test helpers, fixtures, and documentation.
| File | Description |
|---|---|
scripts/test_microvm_tests.py |
Retires the test that reads the deleted init. |
scripts/nvx_tools/build.py |
Stops installing nvx-init-agent. |
nvx-rs/tests/fixtures/root-tokens.json |
Removes shell-only expectations; preserves parser cases. |
nvx-rs/src/protocol/root/tests.rs |
Removes the comment about shell replay. |
nvx-rs/src/protocol/root.rs |
Removes obsolete shell-parser documentation. |
nvx-rs/src/protocol/features.rs |
Gates legacy sandbox features on testing only. |
nvx-rs/src/protocol/export.rs |
Removes documentation references to the deleted init. |
nvx-rs/src/host/cli/session/tests.rs |
Aligns the legacy-feature test’s conditional compilation. |
nvx-rs/src/guest/sys/spawn/tests.rs |
Deletes sandbox-only test accessors. |
nvx-rs/src/guest/sys/entry/tests.rs |
Removes the unused successful-entry simulation variant. |
nvx-rs/src/guest/spawn.rs |
Removes the managed-agent caller claim from documentation. |
nvx-rs/src/guest/root.rs |
Removes the shell-init comparison from a permission comment. |
nvx-rs/src/guest/process.rs |
Deletes the unused private child constructor. |
nvx-rs/src/guest/mod.rs |
Updates the managed agent’s documented module usage. |
nvx-rs/src/guest/mappings/table.rs |
Removes sandbox-mode usage documentation. |
nvx-rs/src/guest/mappings.rs |
Removes sandbox-root mapping documentation. |
nvx-rs/src/guest/managed_agent/tests/loopback/tests.rs |
Drops deleted configuration fields from loopback tests. |
nvx-rs/src/guest/managed_agent/tests.rs |
Retires sandbox-entry tests and adds root-rejection coverage. |
nvx-rs/src/guest/managed_agent/seam/tests.rs |
Removes sandbox-only system mocks and helpers. |
nvx-rs/src/guest/managed_agent/seam.rs |
Removes sandbox paths and system operations. |
nvx-rs/src/guest/managed_agent/mod.rs |
Removes sandbox setup and teardown; requires ROOTFS=-. |
nvx-rs/src/guest/managed_agent/mappings/tests.rs |
Retires sandbox mapping tests and preserves layered coverage. |
nvx-rs/src/guest/managed_agent/mappings.rs |
Removes sandbox table roots and teardown. |
nvx-rs/src/guest/managed_agent/launch/tests.rs |
Retires sandbox launch tests and adjusts direct helpers. |
nvx-rs/src/guest/managed_agent/launch.rs |
Deletes sandbox command construction and its inputs. |
nvx-rs/src/guest/managed_agent/exec/tests.rs |
Keeps environment-failure coverage for direct launches. |
nvx-rs/src/guest/managed_agent/exec.rs |
Removes sandbox execution, placement, and error branches. |
nvx-rs/src/guest/managed_agent/dispatch/tests/runtime.rs |
Updates mapping-table construction in runtime tests. |
nvx-rs/src/guest/managed_agent/dispatch/tests.rs |
Retires sandbox cases and updates retained test signatures. |
nvx-rs/src/guest/managed_agent/dispatch.rs |
Drops sandbox configuration and always advertises direct features. |
nvx-rs/src/guest/managed_agent/diagnostics.rs |
Deletes the unused unmapping diagnostic. |
nvx-rs/src/guest/managed_agent/cgroup.rs |
Deletes sandbox workload placement. |
nvx-rs/src/guest/init/boot.rs |
Removes the unused hostname handoff and conversion. |
nvx-rs/src/guest/init.rs |
Removes old-init references from status documentation. |
nvx-rs/src/guest/exec/tests.rs |
Removes coverage of the deleted private wait method. |
nvx-rs/src/guest/exec.rs |
Deletes two unused private methods and updates caller docs. |
nvx-rs/src/guest/entry/tests.rs |
Deletes the sandbox-only prepared-entry helper. |
nvx-rs/src/bin/nvx-managed-agent.rs |
Documents PID-1 operation without sandbox mode. |
nvx-rs/README.md |
Removes obsolete mode and caller descriptions. |
guest/common/nvx-init-agent |
Deletes the old layered init script. |
guest/common/nvx-container-launch-azurelinux |
Deletes the Azure Linux one-shot launcher. |
guest/common/nvx-container-enter-azurelinux |
Deletes the Azure Linux container-entry helper. |
docker/Dockerfile |
Stops installing the deleted Azure Linux helpers. |
doc/setup.md |
Removes deleted scripts from documented lint commands. |
doc/project-structure.md |
Removes descriptions of deleted guest components. |
doc/guests/ubuntu-guest.md |
Describes layered execution through nvx-init. |
doc/guests/azurelinux-guest.md |
Removes the obsolete sandbox-init omission explanation. |
doc/acceptance-case-matrix.md |
Updates two retained doctest line references. |
.github/actions/check-quality/action.yml |
Removes deleted scripts from ShellCheck and shfmt lists. |
Review effort: Balanced
This was referenced Nov 12, 2026
Closed
Since SL6.3, the shell /init hands every layered root to nvx-init, so nothing starts the old layered init, nvx-init-agent, any more. The Azure Linux one-shot container helpers, nvx-container-launch-azurelinux and nvx-container-enter-azurelinux, had no caller either: the Azure Linux initramfs installed them, but never the old init that ran the container launcher. Delete guest/common/nvx-init-agent and the two helpers, with their build steps: the Alpine initramfs no longer installs nvx-init-agent, and the Azure Linux Docker stage no longer installs the helpers. ShellCheck and shfmt, in check-quality and in the setup guide, no longer name them. Tests: - SandboxShareAgentTests and SandboxRootTokenAgentTests, which ran the old init's share and root-token readers, retire, except the two tests of nvx-hostmount, which move to HostmountShareTests and name nvx-hostmount by its own path rather than beside the deleted init: test_hostmount_accepts_only_child_names_inside_the_aggregate and test_hostmount_makes_file_mount_points_without_following_links. - test_managed_executions_enter_through_the_agent_not_the_container_helpers, which read the old init, retires. - GuestInitRoutingTests no longer stubs /sbin/nvx-init-agent, and its routes no longer check that the deleted init does not run. - test_azurelinux_initramfs_uses_locked_busybox_applets no longer reads the deleted Azure Linux launcher. - root-tokens.json drops shell_error, which only the old init's root-token test read, and its description no longer names the init. Docs: the project structure, the Azure Linux guest, nvx-init's rustdoc and the nvx README no longer name the deleted programs. The rustdoc of protocol::root, protocol::export and guest::root no longer describes the checks with which the deleted init read the root tokens and mounted the export. The Ubuntu guest no longer describes the one-shot workloads that the deleted init ran through the Alpine container helpers. Part of #1123 (SL7.8b). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Only the old layered init started the managed agent with a root other than its own, `-`: the sandbox mode, in which the agent entered each workload into the container's assembled root through guest::entry, held it at a barrier until it had placed it in the container cgroup that the old init prepared, and after STOP unmounted its host mappings and returned to that init. With the old init gone, nothing starts the mode. The agent now refuses any ROOTFS but `-` with status 125, as it does a wrong number of arguments, and runs only as the direct agent, whose loop nvx-init's layered roots and Fresh captures share. Its mapping table and its direct, layered and capture modes stay as they are; only the sandbox mode's use of the table goes, with TableRoot::Sandbox and the teardown that returned to the init. Deleted with the mode: the agent's cgroup module, the sandbox entry, the barrier and cgroup placement of each workload, the sandbox launch command, the seam's spawn, entry preparation and runtime binds and their paths, the AgentConfig fields that only the mode read (rootfs, hostname, direct and entry), and the teardown's diagnostic. So does what the warning-denied builds then find unused: RestoreHandoff::hostname, which only the sandbox entry read, through AgentConfig::hostname; Execution::has_open_output and Execution::wait in guest::exec, and Child::from_process in guest::process, which only the sandbox mode called; and GuestFeatures::SANDBOX_AGENT in the guest feature, since only the fake OpenVMM still announces it, so the testing feature alone gates it. Among the test helpers, so do Prepared::simulated in guest::entry's tests, with Simulation::Skip, which only it used, and PreparedChild's accessors program, arguments, environment, physical_pwd, physical_pwd_index, has_cgroup and barrier_entry_and_session, with the impl that held them, in guest::sys::spawn's tests, which only the sandbox launch tests read. Tests: - The agent's tests.rs retires sandbox_config with its three cases, the_sandbox_entry_takes_an_existing_account_and_one_machine_id_per_boot, a_refused_sandbox_entry_generates_nothing_and_stops_the_agent and a_failed_runtime_bind_stops_the_sandbox_agent_before_its_session, and the_agent_refuses_any_root_but_its_own checks the refusal. - dispatch/tests.rs retires the sandbox mode's mapping and launch tests: sandbox_mappings_mount_in_order_beneath_its_root_and_unblock_workloads, sandbox_mappings_refuse_the_targets_of_the_container_runtime, a_failed_sandbox_mapping_keeps_refusing_workloads, a_sandbox_without_mappings_maps_nothing_and_admits_workloads, sandbox_does_not_launch_when_an_environment_export_fails, sandbox_launch_places_its_workload_before_releasing_it, sandbox_launch_reports_unusable_directories_and_programs_as_its_helper_did and sandbox_launch_fails_on_its_entry_and_its_placement_without_running. - launch/tests.rs retires sandbox_launch_runs_the_workload_itself_through_its_entry, sandbox_launch_applies_exact_and_layered_environments_in_order, sandbox_pwd_is_physical_only_for_noncanonical_names_without_an_entry and sandbox_launch_reports_a_simulated_stage_without_privileges. - mappings/tests.rs retires the teardown's tests, a_sandbox_table_unmounts_in_reverse_order, a_sandbox_table_reports_each_mapping_that_stays_mounted and a_table_without_mappings_has_nothing_to_tear_down. - environment_failures_stop_direct_and_sandbox_launches_before_exec becomes environment_failures_stop_direct_launches_before_exec, with the direct agent's cases alone. - guest::exec's a_status_that_another_collector_took_first_is_left_to_it loses its case of Execution::wait, which goes. - AgentConfig::for_test builds only with the cli feature, as the dispatch tests that call it do, and the host CLI's features_of_a_guest_that_predates_them_are_none only with the testing feature, as the SANDBOX_AGENT that it announces does. - The kept tests lose what only the sandbox mode had: the harness's mode, the sandbox cases of agent_advertises_the_control_features_of_its_mode_and_stops and the_root_of_the_export_is_refused_though_it_decodes, the checks that the direct agent creates nothing under the deleted cgroup root, and the entry count of prepared_layered_mappings_and_cli_identity_use_the_existing_dispatcher. a_layered_table_that_announces_mappings_needs_its_retained_export builds its layered root without the sandbox agent's helper. Docs: the agent's rustdoc, that of guest, guest::mappings, guest::exec and guest::spawn, and the nvx README no longer describe the sandbox mode, or the agent as a caller of the process modules. The case matrix names guest::exec's doc tests by the lines to which they move. Part of #1123 (SL7.8b). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/slim-sl7-8b-old-init
branch
from
November 12, 2026 13:18
0034154 to
a873028
Compare
Pedro Henrique Penna (ppenna)
marked this pull request as ready for review
November 12, 2026 13:19
Pedro Henrique Penna (ppenna)
merged commit Nov 12, 2026
2afac62
into
feature/nvx-refactor
82 of 84 checks passed
Pedro Henrique Penna (ppenna)
deleted the
agents/slim-sl7-8b-old-init
branch
November 12, 2026 13:40
Pedro Henrique Penna (ppenna)
added a commit
that referenced
this pull request
Nov 12, 2026
SL7.8b (#1534) deleted the old layered init, nvx-init-agent, with the managed agent's sandbox mode, and SL7.8c (#1536) deleted the Alpine one-shot container helpers. The build guide still said that the Alpine initramfs includes "the sandbox PID-1 bootstrap and its container namespace scripts", that the kernel checks cover what "the sandbox bootstrap" needs, and that the APK manifest records the tools "used by the bootstrap". The Ubuntu guest still named "the Alpine control initramfs and its init agent" as the boot supervisor of the distro layer, and the cgroups and namespaces "that the sandbox uses". The project structure still credited the common scripts with shutdown and the time ABI, which the Rust guest binaries took over. Say instead what the code does now: - the Alpine initramfs is the one that nvx-rs sandbox boots, and with nvx_sandbox=1 the common /init hands PID 1 to nvx-init (exec /sbin/nvx-init in guest/common/init), which initializes the sandbox's layered root and serves its managed control session; - the APK manifest records every package of the image, among them the five that AlpineBuildConstants.PACKAGES adds to the minirootfs; - nvx-init supervises the Ubuntu distro layer, and the kernel provides the memory and process-count cgroups and the PID, mount, UTS and network namespaces for the guest's programs, without claiming that the sandbox uses them; - the common scripts mount the host share (nvx-hostmount), prepare the guest for a snapshot and repair its restores (nvx-snapshot), and probe for the tests and benchmarks; the Rust binaries provide PID 1, the time ABI's guest side, shutdown and the rest. The kernel inventory and its checks table keep their text: SL6.11b (#1542) rewrites them. Part of #1131 (SL6.10e). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
added a commit
that referenced
this pull request
Nov 13, 2026
SL7.8b (#1534) deleted the old layered init, nvx-init-agent, with the managed agent's sandbox mode, and SL7.8c (#1536) deleted the Alpine one-shot container helpers. The build guide still said that the Alpine initramfs includes "the sandbox PID-1 bootstrap and its container namespace scripts", that the kernel checks cover what "the sandbox bootstrap" needs, and that the APK manifest records the tools "used by the bootstrap". The Ubuntu guest still named "the Alpine control initramfs and its init agent" as the boot supervisor of the distro layer, and the cgroups and namespaces "that the sandbox uses". The project structure still credited the common scripts with shutdown and the time ABI, which the Rust guest binaries took over. Say instead what the code does now: - the Alpine initramfs is the one that nvx-rs sandbox boots, and with nvx_sandbox=1 the common /init hands PID 1 to nvx-init (exec /sbin/nvx-init in guest/common/init), which initializes the sandbox's layered root and serves its managed control session; - the APK manifest records every package of the image, among them the five that AlpineBuildConstants.PACKAGES adds to the minirootfs; - nvx-init supervises the Ubuntu distro layer, and the kernel provides the memory and process-count cgroups and the PID, mount, UTS and network namespaces for the guest's programs, without claiming that the sandbox uses them; - the common scripts mount the host share (nvx-hostmount), prepare the guest for a snapshot and repair its restores (nvx-snapshot), and probe for the tests and benchmarks; the Rust binaries provide PID 1, the time ABI's guest side, shutdown and the rest. The kernel inventory and its checks table keep the text that SL6.11b (#1542) gave them. Part of #1131 (SL6.10e). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
added a commit
that referenced
this pull request
Nov 13, 2026
SL7.8b (#1534) deleted the old layered init, nvx-init-agent, with the managed agent's sandbox mode, and SL7.8c (#1536) deleted the Alpine one-shot container helpers. The build guide still said that the Alpine initramfs includes "the sandbox PID-1 bootstrap and its container namespace scripts", that the kernel checks cover what "the sandbox bootstrap" needs, and that the APK manifest records the tools "used by the bootstrap". The Ubuntu guest still named "the Alpine control initramfs and its init agent" as the boot supervisor of the distro layer, and the cgroups and namespaces "that the sandbox uses". The project structure still credited the common scripts with shutdown and the time ABI, which the Rust guest binaries took over. Say instead what the code does now: - the Alpine initramfs is the one that nvx-rs sandbox boots, and with nvx_sandbox=1 the common /init hands PID 1 to nvx-init (exec /sbin/nvx-init in guest/common/init), which initializes the sandbox's layered root and serves its managed control session; - the APK manifest records every package of the image, among them the five that AlpineBuildConstants.PACKAGES adds to the minirootfs; - nvx-init supervises the Ubuntu distro layer, and the kernel provides the memory and process-count cgroups and the PID, mount, UTS and network namespaces for the guest's programs, without claiming that the sandbox uses them; - the common scripts mount the host share (nvx-hostmount), prepare the guest for a snapshot and repair its restores (nvx-snapshot), and probe for the tests and benchmarks; the Rust binaries provide PID 1, the time ABI's guest side, shutdown and the rest. The kernel inventory and its checks table keep the text that SL6.11b (#1542) gave them. Part of #1131 (SL6.10e). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
added a commit
that referenced
this pull request
Nov 13, 2026
SL7.8b (#1534) deleted the old layered init, nvx-init-agent, with the managed agent's sandbox mode, and SL7.8c (#1536) deleted the Alpine one-shot container helpers. The build guide still said that the Alpine initramfs includes "the sandbox PID-1 bootstrap and its container namespace scripts", that the kernel checks cover what "the sandbox bootstrap" needs, and that the APK manifest records the tools "used by the bootstrap". The Ubuntu guest still named "the Alpine control initramfs and its init agent" as the boot supervisor of the distro layer, and the cgroups and namespaces "that the sandbox uses". The project structure still credited the common scripts with shutdown and the time ABI, which the Rust guest binaries took over. Say instead what the code does now: - the Alpine initramfs is the one that nvx-rs sandbox boots, and with nvx_sandbox=1 the common /init hands PID 1 to nvx-init (exec /sbin/nvx-init in guest/common/init), which initializes the sandbox's layered root and serves its managed control session; - the APK manifest records every package of the image, among them the five that AlpineBuildConstants.PACKAGES adds to the minirootfs; - nvx-init supervises the Ubuntu distro layer, and the kernel provides the memory and process-count cgroups and the PID, mount, UTS and network namespaces for the guest's programs, without claiming that the sandbox uses them; - the common scripts mount the host share (nvx-hostmount), prepare the guest for a snapshot and repair its restores (nvx-snapshot), and probe for the tests and benchmarks; the Rust binaries provide PID 1, the time ABI's guest side, shutdown and the rest. The kernel inventory and its checks table keep the text that SL6.11b (#1542) gave them. Part of #1131 (SL6.10e). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
added a commit
that referenced
this pull request
Nov 13, 2026
SL7.8b (#1534) deleted the old layered init, nvx-init-agent, with the managed agent's sandbox mode, and SL7.8c (#1536) deleted the Alpine one-shot container helpers. The build guide still said that the Alpine initramfs includes "the sandbox PID-1 bootstrap and its container namespace scripts", that the kernel checks cover what "the sandbox bootstrap" needs, and that the APK manifest records the tools "used by the bootstrap". The Ubuntu guest still named "the Alpine control initramfs and its init agent" as the boot supervisor of the distro layer, and the cgroups and namespaces "that the sandbox uses". The project structure still credited the common scripts with shutdown and the time ABI, which the Rust guest binaries took over. Say instead what the code does now: - the Alpine initramfs is the one that nvx-rs sandbox boots, and with nvx_sandbox=1 the common /init hands PID 1 to nvx-init (exec /sbin/nvx-init in guest/common/init), which initializes the sandbox's layered root and serves its managed control session; - the APK manifest records every package of the image, among them the five that AlpineBuildConstants.PACKAGES adds to the minirootfs; - nvx-init supervises the Ubuntu distro layer, and the kernel provides the memory and process-count cgroups and the PID, mount, UTS and network namespaces for the guest's programs, without claiming that the sandbox uses them; - the common scripts mount the host share (nvx-hostmount), prepare the guest for a snapshot and repair its restores (nvx-snapshot), and probe for the tests and benchmarks; the Rust binaries provide PID 1, the time ABI's guest side, shutdown and the rest. The kernel inventory and its checks table keep the text that SL6.11b (#1542) gave them. Part of #1131 (SL6.10e). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.
Leaving code only. This PR changes only code that this effort removes from NVX: the old layered init (
guest/common/nvx-init-agent), the Azure Linux one-shot container helpers (nvx-container-launch-azurelinuxandnvx-container-enter-azurelinux) and the managed agent's sandbox mode, with the edits that remove references to them. Nothing that stays changes, and no later PR uses what it changes, so the size limits for kept code don't apply.Part of #1123 (SL7.8b, "The old layered init is gone"). Parent #1087, umbrella #1076.
What and why
Since SL6.3 (#1530), the shell
/initexecs/sbin/nvx-initfor everynvx_sandbox=1boot, and startsnvx-managed-agentonly with its own root,-, for a managed blockless boot. So nothing starts the old layered init,nvx-init-agent, any more, nor the managed agent's sandbox mode, which only that init started, with the container's assembled root as itsROOTFS. The two Azure Linux one-shot container helpers had no caller before either: the Azure Linux initramfs installed them, but not the old init that ran a container launcher. This PR does SL7.8b's Scope in two commits:abe7a8c4deletes the old layered init and the Azure Linux helpers, with their build steps:build.pyno longer installsnvx-init-agentamong the Alpine initramfs's sandbox-control files, and the Dockerfile's Azure Linux stage no longer installs the two helpers. The ShellCheck and shfmt lists ofcheck-quality, and their copies indoc/setup.md, no longer name them.00341544deletes the managed agent's sandbox mode: its root entry (sandbox_entry, throughguest::entry), each workload's barrier and cgroup placement (the sandbox launch andmanaged_agent/cgroup.rs), and its return to the init agent (the teardown that unmounted its mappings, and the exit that handed the VM back to the init). The agent now refuses anyROOTFSbut-with status 125, as it does a wrong number of arguments, and runs only as the direct agent, whose loop nvx-init's layered roots and Fresh captures share. Its mapping table and its direct, layered and capture modes stay as they are; only the sandbox mode's use of the table goes:TableRoot::Sandbox,HostMappings::newandteardown. With the mode go the seam'sspawn,prepare_entryandbind_runtimewith their paths, theAgentConfigfields that only it read (rootfs,hostname,directandentry),LaunchRequest,sandbox_command,null_device,Workload::Sandbox,LaunchFailure::Sandbox,LaunchError::Entry,Event::CgroupKillFailedanddiagnostics::unmapping_error.RestoreHandoff::hostname(guest::init::boot), which only the sandbox entry read, throughAgentConfig::hostname. With it goes its conversion to a C string, which restore: report the attribution of a restore that fails in its guest (SL5.1d) #1515's9dece307(SL5.1d) classed asACTIVATION_WORKLOAD: it cannot fail, since admission (activation::is_hostname) refuses a hostname with a NUL;Execution::has_open_outputandExecution::wait(guest::exec), andChild::from_process(guest::process), which only the sandbox mode called. They are in the process modules that SL6.11b deletes, which this PR otherwise leaves alone;GuestFeatures::SANDBOX_AGENTleaves theguestfeature: only the fake OpenVMM still announces it, sotestingalone gates it;Prepared::simulatedinguest::entry's tests, withSimulation::Skipinguest::sys::entry's, which only it used; andPreparedChild's accessorsprogram,arguments,environment,physical_pwd,physical_pwd_index,has_cgroupandbarrier_entry_and_session, with theimplthat held them, inguest::sys::spawn's tests, which only the sandbox launch tests read;AgentConfig::for_testbuilds only withcli, as the dispatch tests that call it do, and the host CLI's testfeatures_of_a_guest_that_predates_them_are_noneonly withtesting, as theSANDBOX_AGENTthat it announces does.guest,guest::mappings,guest::exec,guest::spawn,guest::init,guest::root,protocol::rootandprotocol::export, no longer describe the sandbox mode, the deleted init's checks, or the agent as a caller of the process modules. Nor donvx-rs/README.md,doc/project-structure.md, the Azure Linux guest's page, or the Ubuntu guest's, which described the one-shot workloads that the deleted init ran through the Alpine container helpers.nvx-rs/tests/fixtures/root-tokens.jsondropsshell_error, which only the old init's root-token test read.guest::exec's two doc-test rows move to lines 79 and 619, below a deleted rustdoc line. No other inventoried test changes. The three rows that name a test that this PR modifies as coverage (a_failed_mapping_keeps_refusing_workloads_through_dispatch,restored_ready_maps_and_first_exec_share_the_existing_start_transitionandrestored_proxy_defaults_replace_template_values_before_exec_overrides) stay true: those tests change only in the harness's and the config's signatures.What stays:
guest/common/nvx-snapshot, which the blockless snapshot scenarios run, is unchanged, and so are the managed agent's mapping table and its other modes, nvx-init, the process modules but the three dead methods above,BOOT_CONTRACT_VERSION,CONTROL_CONTRACT_REVISIONand the public API snapshots: every deleted item was crate-private.Deliberately left:
guest/alpine/nvx-container-enterandnvx-container-launch, the Alpine one-shot container helpers. The deletednvx-init-agentwas their only caller, so nothing runs them now, but the Scope names only the Azure Linux helpers ("the three deleted programs"). Deleting them emptiesguest/alpine, whichSOURCE-MANIFEST.json, the Alpine image's input hash inbuild-guest-artifacts,release.py's source-tree check,build.py,check-qualityand several docs and tests name, so they are left for a follow-up decision.SANDBOX_AGENTfor a layered sandbox and calls it the sandbox agent's: the fake is outside this Scope.scripts/nvx_tools/kernel_features.py, which still namesnvx-init-agentas a consumer: nvx-rs slimming 4.2.4: the exec engine, the process modules and the old layered init are gone #1123's follow-up K1 waits for SL6.11b.doc/modules, whose diagrams still drawmanaged_agent::cgroup: CI redraws and commits them (doc/ci.md).WorkloadandLaunchFailure, now of one variant each: folding them would rework a mode that stays.guest::activation::Applied::hostname, a hidden public method whose last caller in the crate was that conversion: it is public API, which this PR doesn't change.Size
Measured as #1076 defines them, against
feature/nvx-refactor:managed_agent/exec.rs(the run loop's and the launch's conditions on the mode, folded into the direct agent's, and an import), 7 inmanaged_agent/mod.rs(the root check, the config and the finish without the mode), 6 inmanaged_agent/dispatch.rs(the features reply, alwaysDIRECT_AGENT), an import each inmanaged_agent/launch.rsandmanaged_agent/mappings.rs, and 1 indocker/Dockerfile(the install list's new last line). The rest are deletions, comments and docs..github/actions/check-quality/action.yml,docker/Dockerfile,scripts/nvx_tools/build.py, and innvx-rs/src/:bin/nvx-managed-agent.rs,guest/exec.rs,guest/init.rs,guest/init/boot.rs,guest/managed_agent/{diagnostics,dispatch,exec,launch,mappings,mod,seam}.rs,guest/mappings.rs,guest/mappings/table.rs,guest/mod.rs,guest/process.rs,guest/root.rs,guest/spawn.rs,protocol/export.rs,protocol/root.rsandprotocol/features.rs, which only narrows acfgand rewords the two docs that this forces, so it could be left out (22). The deletednvx-init-agent, the two helpers andmanaged_agent/cgroup.rsdon't count.Old tests of the area
scripts/test_nvx_tools.py:SandboxShareAgentTests(21 tests:test_agent_mounts_share_after_lifecycle_checks_for_both_lifecycles,test_managed_lifecycle_gives_back_the_launcher_process,test_agent_teardown_unmounts_share_before_overlay_layers_and_scratch,test_agent_teardown_unmounts_the_tmpfs_upper_last,test_agent_teardown_unmounts_shares_in_reverse_mount_order,test_agent_teardown_reports_share_unmount_failure,test_agent_fatal_unmounts_share_before_power_off,test_agent_skips_share_without_bootstrap_tokens,test_agent_mounts_share_inside_container_rootfs,test_managed_agent_mounts_no_export_without_bootstrap_tokens,test_managed_agent_mounts_the_export_where_only_root_can_enter,test_managed_agent_refuses_share_tokens_and_other_exports,test_managed_agent_refuses_an_export_directory_that_exists,test_agent_binds_every_child_of_an_aggregate,test_agent_binds_children_by_the_names_that_nvx_gives_them,test_agent_binds_a_file_child_at_a_file,test_agent_rejects_repeated_children_and_overlapping_targets,test_agent_parses_every_share_before_mounting_any,test_agent_fatal_unmounts_mounted_shares,test_agent_fails_closed_for_invalid_share_bootstrapandtest_agent_rejects_symbolic_link_in_share_target) andSandboxRootTokenAgentTests(8 tests:test_agent_reads_the_boot_tokens_as_nvx_rs_reads_them,test_agent_explains_the_roots_that_it_cannot_assemble,test_agent_refuses_the_settings_with_the_messages_of_nvx_rs,test_agent_requires_one_upper,test_agent_refuses_a_scratch_device_beside_a_ram_upper,test_agent_checks_a_ram_upper_before_it_mounts_anything,test_agent_mounts_the_upper_that_the_tokens_nameandtest_agent_checks_the_layer_uuid_only_when_the_token_names_one);scripts/test_microvm_tests.py::MicrovmTests.test_managed_executions_enter_through_the_agent_not_the_container_helpers, which read the old init;sandbox_config's three cases in the agent'stests.rs:the_sandbox_entry_takes_an_existing_account_and_one_machine_id_per_boot,a_refused_sandbox_entry_generates_nothing_and_stops_the_agentanda_failed_runtime_bind_stops_the_sandbox_agent_before_its_session;managed_agent::dispatch::tests:sandbox_mappings_mount_in_order_beneath_its_root_and_unblock_workloads,sandbox_mappings_refuse_the_targets_of_the_container_runtime,a_failed_sandbox_mapping_keeps_refusing_workloads,a_sandbox_without_mappings_maps_nothing_and_admits_workloads,sandbox_does_not_launch_when_an_environment_export_fails,sandbox_launch_places_its_workload_before_releasing_it,sandbox_launch_reports_unusable_directories_and_programs_as_its_helper_didandsandbox_launch_fails_on_its_entry_and_its_placement_without_running;managed_agent::launch::tests:sandbox_launch_runs_the_workload_itself_through_its_entry,sandbox_launch_applies_exact_and_layered_environments_in_order,sandbox_pwd_is_physical_only_for_noncanonical_names_without_an_entryandsandbox_launch_reports_a_simulated_stage_without_privileges;managed_agent::mappings::tests:a_sandbox_table_unmounts_in_reverse_order,a_sandbox_table_reports_each_mapping_that_stays_mountedanda_table_without_mappings_has_nothing_to_tear_down;managed_agent::exec::tests::environment_failures_stop_direct_and_sandbox_launches_before_execbecomesenvironment_failures_stop_direct_launches_before_exec, with the direct agent's cases alone.managed_agent::tests::the_agent_refuses_any_root_but_its_ownis new: it starts the agent with a container's root as itsROOTFS, as the deleted init did, and checks that the agent refuses it before it configures its terminal, reports a diagnostic or runs anything.check_test_changes.pypairs it witha_failed_runtime_bind_stops_the_sandbox_agent_before_its_session, whose place it takes.test_hostmount_accepts_only_child_names_inside_the_aggregateandtest_hostmount_makes_file_mount_points_without_following_links, the two tests ofnvx-hostmountinSandboxShareAgentTests, move to a newHostmountShareTests, which namesguest/common/nvx-hostmountby its own path rather than beside the deleted init's. They check the same.nvx-snapshot, the shell/initand the guest images; the ones thatcheck_test_changes.pylists below change only to stop naming what left.Test changes
python scripts/check_test_changes.py --base origin/feature/nvx-refactorlists 159 changes to existing tests, hencetests-modified:scripts/test_nvx_tools.py, 1 inscripts/test_microvm_tests.py, and 17 Rust tests) and 6 lines of CI test wiring in.github/actions/check-quality/action.yml, the ShellCheck and shfmt entries of the three deleted programs.scripts/test_nvx_tools.py, the classSandboxShareAgentTestswith itssetUp,_aggregate,_export,_runand_run_teardown, andSandboxRootTokenAgentTests._read; in the agent's tests,sandbox_config,Harness::in_sandbox,Harness::spawn_at,spawn_sandboxandsandbox_system(dispatch),descriptor,request,direct_pathsandprepare_sandbox(launch),HostMappings::announced_for,sandboxandmap_three(mappings), and the seam'swith_container_cgroup,spawn,prepare_entryandbind_runtime(TestSystem); and the dead test helpers named above inguest::entry(Prepared::simulatedwith itsimpl) andguest::sys::spawn(PreparedChild's seven accessors with theirimpl).Harness'snew,with_systemandspawn, andrunning_restored_workload,lost_status_harnessanddirect_harness;configandvalidate(exec),configandprepare_direct(launch); the seam'sTestSystem,TestSystem::newandTestSystem::with_direct;AgentConfig::for_test(no argument,clionly);Simulation(withoutSkip);GuestInitRoutingTests.setUpand_run, which no longer stub/sbin/nvx-init-agent; andSandboxRootTokenAgentTests's class andsetUp, whichcheck_test_changes.pypairs with the newHostmountShareTests. The imports of three test modules follow.Harness::new(),Harness::with_system(system, n),AgentConfig::for_test(),HostMappings::announced(n),config()andprepare_direct(config, execution), which no longer takes the deleted paths): 24 inmanaged_agent::dispatch::tests, the 4 ofdispatch::tests::runtime, andlaunch::tests::restored_proxy_defaults_replace_template_values_before_exec_overrides,privileged_direct_launch_hardens_credentials_and_resets_priority,direct_launch_applies_exact_empty_and_layered_environments_in_orderanddirect_pwd_is_deferred_only_for_noncanonical_names.agent_advertises_the_control_features_of_its_mode_and_stops(the sandbox agent's features),the_root_of_the_export_is_refused_though_it_decodes(the sandbox agent's case),prepared_layered_mappings_and_cli_identity_use_the_existing_dispatcher(the entry count),direct_core_applies_inherited_exact_and_layered_environmentsanddirect_launch_uses_the_plain_process_core_without_a_helper_or_cgroup(their check that nothing appears under the deleted cgroup root),a_layered_cold_boot_takes_only_the_clis_workload_identity(the deleteddirectandentryfields), the two loopback tests (the deletedAgentConfigfields),guest::exec::tests::a_status_that_another_collector_took_first_is_left_to_it(its case of the deletedExecution::wait), anda_layered_table_that_announces_mappings_needs_its_retained_export, which builds its layered root itself rather than through the sandbox helper.nvx-hostmounttests (Moved, above), andfeatures_of_a_guest_that_predates_them_are_none, whosecfgnarrows totesting.scripts/test_nvx_tools.py:GuestInitRoutingTests.test_blockless_platform_and_snapshot_vms_keep_their_routesandtest_missing_helpers_or_selected_init_fail_without_fallbackno longer check that the deleted init does not run, andBuildTests.test_azurelinux_initramfs_uses_locked_busybox_appletsno longer reads the deleted launcher.nvx-rs/tests/fixtures/root-tokens.jsondropsshell_errorfrom its 27 cases, which only the old init's root-token test read, and its description no longer names that init.Validation
local_gates.py --files(fromdev) selects, for these files,test-changes,markdown-links,test-layout,quality-code, every step ofcheck-nvx-rsandnvx-cli(validate-nvx), on both systems; its runtime-adapter gates no longer exist on this branch. I ran them from this branch's action definitions, and the microVM scenarios on all three backends, on the final head,00341544, unless a row says otherwise.The branch was first validated on SL6.3's head,
604d8dac: the same gates passed, and so did the scenarios below on KVM, MSHV and WHP. SL6.3 then merged, and its branch was deleted, so I rebased ontofeature/nvx-refactortwice, withrerereoff:671a192d(SL6.3, SL6.6a and SL6.11a).guest/exec.rs,guest/sys/spawn/tests.rs,nvx-rs/README.mdand the case matrix conflicted, since SL6.11a had already deletedExecution::output_hung_up,report_writer_copyand the binding's docs. The resolutions keep the base's text without what this PR deletes;PreparedChild's testimplthen held nothing and went, and the twoguest::execdoc-test rows moved to 79 and 619. The scenarios and every gate passed there too, atbc8fed95.00c55b96(SL5.1d, restore: report the attribution of a restore that fails in its guest (SL5.1d) #1515).guest/init.rs's docs andguest/init/boot.rs's handoff conflicted with the new activation-failure classes: the docs keep restore: report the attribution of a restore that fails in its guest (SL5.1d) #1515's text withoutnvx-init-agent, and the handoff loseshostname, as above.git range-diffshows no other change.Windows, this workstation (Rust 1.95.0):
cargo fmt --all --checkcargo clippy --lockedwith-D warnings:--all-targets --all-features,--lib,--lib --no-default-features, andserde,cliandtestingalonecargo test --locked --all-featurescargo test --lockedcargo 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-features(MSRV)ruff check scripts .github/specula,ruff format --check ...,compileall .github/specula,pyright --pythonplatform Linux,--pythonplatform Windowsvalidate-nvx's unittest list,test_adversarial.py,test_hosts.pyandnvx.py's--helpcommandstest_adversarial.py(11 skipped) andtest_hosts.pypasscheck_test_layout.py,check_markdown_links.pycheck_matrix.py <worktree> 99d2022085fcheck_test_changes.py --base origin/feature/nvx-refactorLinux,
nvx-mshv-test(Azure Linux 3, kernel 6.18, MSHV, virtual machine), in a worktree of this branch with its own target directory, every signal at its default disposition:cargo test --locked --all-features --no-fail-fastcli120,guest_tools33,host_modules22, the other integration tests, and 24 doc testscargo test --lockedcargo build --locked --lib --no-default-features,cargo test --locked --lib --no-default-featurespython3 scripts/nvx.py check-guest-binaries --toolchain 1.95.0validate-nvx's unittest list,test_adversarial.py,test_hosts.pyandnvx.py's--helpcommands/initrouting andnvx-hostmounttests that Windows skips; 84; 4Linux,
nvx-kvm-test(Azure Linux 3, kernel 6.6, KVM, virtual machine), likewise:cargo fmt, and everyclippyofcheck-nvx-rswith-D warnings, with--features guestalone on the host target tooRUSTDOCFLAGS=-D warnings cargo doc --locked --no-deps --all-features, which documents the Linux-only guest modules--target aarch64-apple-darwin)all_processors_onlineandconsole_listenerare unused, as it does at the basepython3 scripts/public_api.pypython3 scripts/nvx.py check-guest-binaries --toolchain 1.95.0guest::tests (965 passed), the identical 7 at the base00c55b96on this host (974 passed there, with the 9 guest-only tests that this PR retires):guest::entry::tests::runtime_binds_need_a_mount_root_unless_there_are_none,guest::exec::tests::a_start_after_another_collector_took_the_status_ends_nothing_by_id,guest::exec::tests::adopting_a_program_whose_status_another_collector_took_ends_nothing_by_id, andguest::init::tests::exec::{a_stolen_or_auto_reaped_status_is_reported_once_and_never_reclassified_by_an_ending, host_launch_tests_use_the_syscall_seam_without_mocking_the_execution_core, native_workload_cwd_accepts_procfs_links_but_closes_inherited_descriptors, only_the_collectors_terminal_status_settles_the_owned_leader_and_output}. MSHV's kernel 6.18 runs all 972build-guest-binaries,test-guest-binariescheck-quality's ShellCheck and shfmt commands, with its pinned imagesbc8fed95; no file that they check has changed sincepython3 scripts/nvx.py build-initramfs --guest alpine,--guest ubuntu(native) and--guest azurelinux(Docker)6a3a1818…, Ubuntu52ae53c7…, Azure Linuxef9a1ac0…. The Alpine image's/sbinholdsnvx-init,nvx-managed-agentandnvx-snapshot, and nonvx-init-agent; the Azure Linux image holdsnvx-snapshotand nonvx-container-*helperMicroVM scenarios, with those images, and the kernel, Ubuntu distro layer and OpenVMM (
openvmm-linux-gnu,openvmm-windows-msvc) of run 43185976865 atf03c21c3, each checked by SHA-256, since neither theopenvmmpin (14dc4116) nor the kernel's inputs have changed since;NVX_AUTO_DOWNLOAD=0:nvx-whp-test)guest-boot,guest-identity,console-exit,lifecycle,managed-lifecycle,workload-identity,console-snapshot,network-snapshot,filesystem-snapshotmanaged-exec-config,sandbox-lifecycle,sandbox-proxy-only,sandbox-ram-upper,sandbox-gpt-layer,vm-lifecycle,snapshot-core,snapshot-tiersguest-boot,guest-identity,console-exit,lifecycle,virtio-net,filesystem-snapshot(WHP:guest-boot,lifecycle,filesystem-snapshot)guest-boot,guest-identity,console-exit,virtio-net,network-snapshot,workload-identity,managed-lifecycleThe Done-when, on real VMs:
nvx_sandbox=1 nvx_mode=managedandnvx_layer=distro,...on the kernel command line, which the shell/inithands to/sbin/nvx-initin the Alpine image that no longer hasnvx-init-agent. nvx-init serves the root's executions in-process, through the managed agent's direct loop (AgentConfig::layered), so they run this branch's agent.nvx-snapshotstill builds and serves blockless snapshots:console-snapshot,network-snapshotandfilesystem-snapshotcall/sbin/nvx-snapshotin blockless Alpine, Ubuntu and Azure Linux guests and restore from what it captured.Not run, left to CI:
build-guest --guest allandverify-guest-determinism. The hosts have nomkfs.erofs, so the Ubuntu distro layer above is CI's: its input digest coversguest/commonand the guest binaries' sources, so CI rebuilds it for this PR, while the layered boots above already run nvx-init and its agent from the initramfs that this branch builds. Also left to CI: the benchmarks, OpenVMM's own tests (the pin doesn't move), the debug-kernel runs, and the rest of the default scenario suite and its other vCPU counts.