From cd9cce3d85b01ef32394b85a3f253d0e1e4c20e7 Mon Sep 17 00:00:00 2001 From: Enrique Saurez Date: Wed, 21 Oct 2026 22:35:52 -0700 Subject: [PATCH 1/4] nvx-rs: terminate a VM of another runtime identity on stop A VM that another runtime identity started may speak other boot or control contracts, so nothing drives it through a control session. Its owner could stop it only with the artifacts that started it. Now the owner stops it by identity-verified forced termination: - supervisor: Vmm::terminate takes the forced step alone, through the VMM's verified process identity, bounded by the caller. It clears the runtime record once the VMM has exited, and keeps it when the exit is not confirmed, so that a later call retries. Records whose process has exited, as after a reuse of its ID or an earlier boot, end nothing. - instance: LockedInstance::terminate ends a Mismatched VM, and the Mismatched error points at it. - CLI: stop terminates a VM of another runtime identity within --timeout and warns on standard error that it did. start and exec refuse it, naming the parts that differ, and point at stop. The stop of a VM of the same identity is unchanged. - aci_edge_sandboxes: stop terminates such a VM and reports it as forced. Every other operation still fails with backend_error. - fake OpenVMM: count the control connections that it accepts, so that tests prove that no session reached the VM. Part of #622 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 84d06582-33fd-47b2-954e-904c4ea1a084 --- aci_edge_sandboxes/README.md | 21 ++- aci_edge_sandboxes/src/openvmm/config.rs | 4 +- aci_edge_sandboxes/src/openvmm/mod.rs | 17 +- aci_edge_sandboxes/tests/openvmm_e2e.rs | 70 +++++++- aci_edge_sandboxes/tests/openvmm_fake.rs | 33 +++- doc/run.md | 13 +- doc/usage.md | 5 +- nvx-rs/README.md | 31 ++-- nvx-rs/src/host/cli/sandbox/lifecycle.rs | 103 +++++++++-- nvx-rs/src/host/instance.rs | 62 +++++-- nvx-rs/src/host/supervisor/mod.rs | 166 +++++++++++++----- nvx-rs/src/host/supervisor/tests.rs | 54 ++++++ nvx-rs/src/testing/fake_openvmm.rs | 20 ++- nvx-rs/tests/cli.rs | 209 +++++++++++++++++++++-- nvx-rs/tests/fake_openvmm.rs | 138 ++++++++++++++- nvx-rs/tests/supervisor.rs | 103 +++++++++-- 16 files changed, 898 insertions(+), 151 deletions(-) diff --git a/aci_edge_sandboxes/README.md b/aci_edge_sandboxes/README.md index f973b0c8b..6a36322bb 100644 --- a/aci_edge_sandboxes/README.md +++ b/aci_edge_sandboxes/README.md @@ -662,10 +662,13 @@ build, or other artifacts, started. Without a runtime identity, `probe`, `provision`, and `start` fail with `backend_unavailable`, as does any operation on a sandbox whose store records a -VM. An operation on a sandbox whose VM runs under another runtime identity, -such as one that the build before an upgrade started, fails with -`backend_error`, naming the parts that differ and OpenVMM's process ID, and -leaves the VM running: stop it with the build and artifacts that started it. +VM. A sandbox whose VM runs under another runtime identity, such as one that the +build before an upgrade started, is never driven, since its guest might speak +other contracts. `stop` terminates its OpenVMM through its verified process +identity, without a control session, and reports `forced`, but no summary of +OpenVMM's outcome report, which follows that runtime's contracts. Every other +operation fails with `backend_error`, naming the parts that differ and +OpenVMM's process ID, and leaves the VM running. ### How it runs OpenVMM @@ -700,8 +703,11 @@ leaves the VM running: stop it with the build and artifacts that started it. agent kills whatever it left behind, including processes in other sessions, so no workload process outlives its exec. - **Stop** asks the guest to shut down. If the guest does not finish within - `stop_timeout`, OpenVMM is terminated. Everything the workloads wrote is - discarded, because the root file system lives in guest memory. + `stop_timeout`, OpenVMM is terminated. The OpenVMM of a VM of another + [runtime identity](#runtime-identity) is terminated without a shutdown + request, and the stop waits up to `stop_timeout` for it to exit. Everything + the workloads wrote is discarded, because the root file system lives in guest + memory. - **Deprovision** deletes the state directory. It refuses to remove a directory that contains unexpected files. @@ -1010,7 +1016,7 @@ conversion, without the exec case, turns any `nvx::Error` into an `Error`. | --- | --- | | provision | none | | start | `bootMilliseconds`: time from launch to guest readiness | -| stop | `forced`: whether OpenVMM had to be terminated; `vmOutcome`, `vmStatusCode`, `teardownComplete`: summary of OpenVMM's outcome report | +| stop | `forced`: whether OpenVMM had to be terminated; `vmOutcome`, `vmStatusCode`, `teardownComplete`: summary of OpenVMM's outcome report, for a VM of the backend's runtime identity | | deprovision | none | ### Security notes @@ -1063,6 +1069,7 @@ fake-OpenVMM lifecycle test. discovered artifacts. - `nvx.py test-aci-edge-sandboxes` runs the ignored `openvmm_e2e` tests against a real hypervisor with the repository's kernel and Alpine initramfs: the lifecycle, + reattachment and the termination of a VM of another runtime identity, working directories, host path mapping, network rules, private-network ingress, bidirectional host-loopback access, and exec environments. CI runs them on diff --git a/aci_edge_sandboxes/src/openvmm/config.rs b/aci_edge_sandboxes/src/openvmm/config.rs index 94cc54bb9..5b12e1981 100644 --- a/aci_edge_sandboxes/src/openvmm/config.rs +++ b/aci_edge_sandboxes/src/openvmm/config.rs @@ -27,8 +27,8 @@ pub struct OpenVmmConfig { pub initrd: PathBuf, /// The runtime identity of the artifacts, which the store records with each sandbox's VM: /// the identities of OpenVMM, the kernel, and the initramfs, with the contract versions of - /// this build. A VM that runs under another runtime identity, as after an upgrade, is reported - /// and neither driven nor stopped. + /// this build. A VM that runs under another runtime identity, as after an upgrade, is not + /// driven: a stop terminates its OpenVMM, and every other operation reports it. /// /// Leave it unset for artifacts located in an NVX release or repository checkout, as by /// [`from_release_dir`](Self::from_release_dir), [`from_repo_layout`](Self::from_repo_layout), diff --git a/aci_edge_sandboxes/src/openvmm/mod.rs b/aci_edge_sandboxes/src/openvmm/mod.rs index 2a8d85aaf..41e0d56f3 100644 --- a/aci_edge_sandboxes/src/openvmm/mod.rs +++ b/aci_edge_sandboxes/src/openvmm/mod.rs @@ -32,8 +32,10 @@ //! OpenVMM, kernel, and initramfs, which [`OpenVmmConfig::runtime_identity`] gives or the install //! metadata of the artifacts' release or checkout names, and the contract versions of the build //! that started it. A VM whose runtime identity differs from the backend's, as after an upgrade, -//! fails every operation with [`ErrorCode::BackendError`](crate::ErrorCode::BackendError), and -//! keeps running: only the build and artifacts that started it can drive or stop it. +//! is never driven, since its guest might speak other contracts: **stop** terminates its OpenVMM +//! through its verified process identity, without a control session, waiting up to +//! [`OpenVmmConfig::stop_timeout`] for it to exit, and every other operation fails with +//! [`ErrorCode::BackendError`](crate::ErrorCode::BackendError) and leaves the VM running. //! //! # Policy honor matrix //! @@ -648,16 +650,19 @@ impl Backend for OpenVmmBackend { fn stop(&self, sandbox_id: &SandboxId) -> Result { let (mut locked, _) = self.store.lock_and_load(sandbox_id)?; - let running = match self.find(&mut locked)? { + let stopped = match self.find(&mut locked)? { Found::Stopped => { return Err(Error::already_stopped(format!( "sandbox {sandbox_id} is not running" ))); } - Found::Running(running) => running, - Found::Mismatched(mismatched) => return Err(mismatched.error().into()), + Found::Running(running) => locked.stop(running, self.config.stop_timeout)?, + // Its guest might not speak this build's control protocol, so OpenVMM is terminated + // through its verified process identity, without a control session. + Found::Mismatched(mismatched) => { + locked.terminate(mismatched, self.config.stop_timeout)? + } }; - let stopped = locked.stop(running, self.config.stop_timeout)?; let mut metadata = Metadata::new(); metadata.insert("forced".to_owned(), stopped.forced.into()); if let Some(report) = &stopped.report { diff --git a/aci_edge_sandboxes/tests/openvmm_e2e.rs b/aci_edge_sandboxes/tests/openvmm_e2e.rs index ee850dcfd..26cd4f43b 100644 --- a/aci_edge_sandboxes/tests/openvmm_e2e.rs +++ b/aci_edge_sandboxes/tests/openvmm_e2e.rs @@ -19,6 +19,7 @@ use std::thread; use std::time::{Duration, Instant}; use aci_edge_sandboxes::nvx::Artifacts; +use aci_edge_sandboxes::nvx::host::store::ArtifactIdentity; use aci_edge_sandboxes::nvx::resolve_guest_path as guest_path; use aci_edge_sandboxes::openvmm::{OpenVmmBackend, OpenVmmConfig}; use aci_edge_sandboxes::{ @@ -35,11 +36,15 @@ fn variable(name: &str) -> String { }) } +/// Returns the artifacts that the environment names. +fn artifacts() -> Artifacts { + Artifacts::from_dir(variable("ACI_EDGE_SANDBOXES_E2E_ARTIFACTS_DIR")).unwrap() +} + /// Returns the configuration of the artifacts that the environment names, with `state_root`. fn config(state_root: PathBuf) -> OpenVmmConfig { - let artifacts = Artifacts::from_dir(variable("ACI_EDGE_SANDBOXES_E2E_ARTIFACTS_DIR")).unwrap(); OpenVmmConfig::from_artifacts( - artifacts, + artifacts(), variable("ACI_EDGE_SANDBOXES_E2E_HYPERVISOR") .parse() .unwrap(), @@ -89,19 +94,23 @@ fn shell(nvx: &AciEdgeSandbox, sandbox_id: &SandboxId, command_line: &str) -> Ex run(nvx, sandbox_id, ExecRequest::command_line(command_line)) } +/// Returns the state root of the clients named `name`. +fn state_root(name: &str) -> PathBuf { + env::var("ACI_EDGE_SANDBOXES_E2E_STATE_ROOT") + .map(PathBuf::from) + .unwrap_or_else(|_| { + env::temp_dir().join(format!("aci-edge-sandboxes-e2e-{}", std::process::id())) + }) + .join(name) +} + /// Creates a client over the artifacts named by the environment. /// /// Keep `name` short: on Unix, each sandbox's control socket path, /// `//<32-character token>/control.sock`, must fit in 107 bytes, and the /// state root of `scripts/nvx.py test-aci-edge-sandboxes` takes 42 of them under `/tmp`. fn client(name: &str) -> (AciEdgeSandbox, Arc) { - let state_root = env::var("ACI_EDGE_SANDBOXES_E2E_STATE_ROOT") - .map(PathBuf::from) - .unwrap_or_else(|_| { - env::temp_dir().join(format!("aci-edge-sandboxes-e2e-{}", std::process::id())) - }) - .join(name); - let backend = Arc::new(OpenVmmBackend::new(config(state_root)).unwrap()); + let backend = Arc::new(OpenVmmBackend::new(config(state_root(name))).unwrap()); (AciEdgeSandbox::from_shared(backend.clone()), backend) } @@ -1715,3 +1724,46 @@ fn openvmm_lifecycle_on_a_real_hypervisor() { ErrorCode::StaleId ); } + +#[test] +#[ignore = "requires a hypervisor and NVX guest artifacts; run scripts/nvx.py test-aci-edge-sandboxes"] +fn a_vm_of_another_runtime_identity_is_only_terminated() { + let (nvx, backend) = client("identity"); + let cleanup = started(&nvx, &backend, &ProvisionRequest::new()); + let sandbox_id = id(&cleanup); + // A backend over the same artifacts, as after its host restarts, reattaches to the VM. + let (restarted, _) = client("identity"); + assert_eq!(shell(&restarted, sandbox_id, "echo same").stdout, b"same\n"); + + // One whose initramfs differs, as after an upgrade, drives the VM through no control session, + // and its stop terminates OpenVMM. + let mut config = config(state_root("identity")); + let mut identity = artifacts().runtime_identity().unwrap(); + identity.initramfs = ArtifactIdentity::sha256(&"0".repeat(64)).unwrap(); + config.runtime_identity = Some(identity); + let upgraded = AciEdgeSandbox::openvmm(config).unwrap(); + let runtime: serde_json::Value = serde_json::from_slice( + &fs::read(backend.log_path(sandbox_id).with_file_name("runtime.json")).unwrap(), + ) + .unwrap(); + let pid = support::recorded_pid(&runtime); + let error = upgraded + .exec(sandbox_id, &ExecRequest::command_line("true")) + .unwrap_err(); + assert_eq!(error.code(), ErrorCode::BackendError, "{error}"); + assert!( + error.message().contains(&format!( + "runs under another runtime identity, which differs in initramfs, so it is not \ + driven: stop it to terminate its OpenVMM process {pid}" + )), + "{error}" + ); + assert!(support::process_running(pid)); + let stopped = upgraded.stop(sandbox_id).unwrap(); + assert_eq!(stopped.metadata.unwrap()["forced"], true); + assert!(!support::process_running(pid)); + + // The sandbox stopped, so the artifacts that started it start it again. + nvx.start(sandbox_id).unwrap(); + assert_eq!(shell(&nvx, sandbox_id, "echo again").stdout, b"again\n"); +} diff --git a/aci_edge_sandboxes/tests/openvmm_fake.rs b/aci_edge_sandboxes/tests/openvmm_fake.rs index 5e5c10128..46e22bd09 100644 --- a/aci_edge_sandboxes/tests/openvmm_fake.rs +++ b/aci_edge_sandboxes/tests/openvmm_fake.rs @@ -2239,21 +2239,21 @@ fn runtime_identities_come_from_the_install_metadata() { ); assert_eq!(run(&nvx, &sandbox_id, "echo before").stdout, b"before\n"); - // The release is upgraded in place: the backend reads the new identity, and reports the VM - // that the earlier OpenVMM started rather than driving or stopping it. + // The release is upgraded in place: the backend reads the new identity, and does not drive + // the VM that the earlier OpenVMM started. write_checksums(&release, '4'); for error in [ nvx.exec(&sandbox_id, &ExecRequest::command_line("echo")) .unwrap_err(), - nvx.stop(&sandbox_id).unwrap_err(), nvx.start(&sandbox_id).unwrap_err(), nvx.deprovision(&sandbox_id).unwrap_err(), ] { assert_eq!(error.code(), ErrorCode::BackendError, "{error}"); assert!( - error - .message() - .contains("runs under another runtime identity, which differs in OpenVMM"), + error.message().contains( + "runs under another runtime identity, which differs in OpenVMM, so it is not \ + driven: stop it" + ), "{error}" ); } @@ -2263,7 +2263,26 @@ fn runtime_identities_come_from_the_install_metadata() { // Back on the artifacts that started it, the backend drives the VM again. write_checksums(&release, '1'); assert_eq!(run(&nvx, &sandbox_id, "echo after").stdout, b"after\n"); - nvx.stop(&sandbox_id).unwrap(); + + // After another upgrade, a stop terminates the VM's OpenVMM, which it asks nothing, and + // summarizes no outcome report, since a report beside the VM would be the other runtime's. + write_checksums(&release, '4'); + fs::write( + fixture + .state_root + .join(sandbox_id.token()) + .join("outcome.json"), + r#"{"outcome":{"category":"success","status_code":0},"teardown":{"workers":true}}"#, + ) + .unwrap(); + let stopped = nvx.stop(&sandbox_id).unwrap().metadata.unwrap(); + assert_eq!( + stopped.keys().map(String::as_str).collect::>(), + ["forced"], + "{stopped:?}" + ); + assert_eq!(stopped["forced"], true); + assert!(!support::process_running(pid)); nvx.deprovision(&sandbox_id).unwrap(); // A release without its checksum list cannot be identified. diff --git a/doc/run.md b/doc/run.md index 38ca7621e..2d28540e6 100644 --- a/doc/run.md +++ b/doc/run.md @@ -1165,10 +1165,15 @@ digests of OpenVMM, the kernel, and the Alpine initramfs, as the install metadata lists them, without hashing an artifact. A release lists them in its `SHA256SUMS`, and a checkout in the build provenance that `nvx.py` writes to `build/` with each artifact that it builds, and that `nvx.py download` -installs. `exec`, `stop`, and `deprovision` drive only a VM that artifacts of -the same identity started: one that other artifacts started, as before they -were rebuilt or replaced, is reported, and must be stopped with the artifacts -that started it. The store reads runtime records of its own format only, so +installs. The transitions drive only a VM that artifacts of the same identity +started. One that other artifacts started, as before they were rebuilt or +replaced, may speak other contracts, so `start` and `exec` refuse it, naming +the parts that differ, `deprovision` refuses it as running, and `stop` +terminates its OpenVMM without a guest shutdown, waits up to `--timeout` +seconds for it to exit, and warns that it did. A `stop` that cannot determine +the OpenVMM process, or whose terminated OpenVMM does not exit in time, keeps +the sandbox's runtime record, and the next `stop` retries. The store reads +runtime records of its own format only, so stop every running sandbox with the NVX version that started it before you switch versions: a version with another format fails every transition of such a sandbox with a message that names the format of its record. An OpenVMM that diff --git a/doc/usage.md b/doc/usage.md index 7d0d8c2ec..a8439cdf4 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -774,7 +774,10 @@ against a real hypervisor. The tests start sandboxes with `build/vmlinux` and the Alpine initramfs, whose userland the workloads use directly, and run workloads. They check the workload identity, timeouts, and cancellation, that guest state lasts until a stop, and that a start terminates the VM of an -interrupted earlier start before deprovisioning. They check that each workload +interrupted earlier start before deprovisioning. They check that a backend +over the same artifacts reattaches to a running VM, and that one whose +initramfs differs drives it through no control session, and only terminates +it on stop. They check that each workload starts in its requested working directory, or `/` without one, and that a missing, non-directory, or inaccessible working directory fails the launch. They also map temporary host directories read-only, read-write, and denied, diff --git a/nvx-rs/README.md b/nvx-rs/README.md index 9efd37bff..4865679fd 100644 --- a/nvx-rs/README.md +++ b/nvx-rs/README.md @@ -79,10 +79,10 @@ nvx-rs/ | `nvx::host::network::policy` | Egress policy files: `compile_policy_file`, `compile_policy_bytes`, and `compile_policy` compile one to a `CompiledEgressPolicy` of native rules; see [Egress policy files](#egress-policy-files) | | `nvx::host::filesystem` | The `ExportPlan` of host paths through OpenVMM's aggregate virtio-fs device, the host-mapping table, the reserved guest targets, and `guest_path` and `resolve_guest_path` (also at `nvx::`) | | `nvx::host::store` | `SandboxStore`: the runtime records of one sandbox in a private directory with one lock, which every host that supervises the sandbox shares. The `RuntimeRecord` names the running VM: the `ProcessRef` of its VMM, its control endpoint, and the `RuntimeIdentity` that it was launched with, the identities of its OpenVMM, kernel, and initramfs from install or staging metadata and its boot and control contract versions, which decide whether another build of the host may reattach to it. The `LaunchJournal` of a launch holds a marker written before the spawn, the VMM's `ProcessRef` right after it, and an inherited claim on the VMM's log, which proves that a launch that never published its endpoint has exited, so that recovery ends an interrupted launch and signals only a VMM that it holds through a verified `Process`. Records are JSON in one versioned format, and records in any other format fail rather than being migrated. The caller declares the files that it keeps in the directory, its configuration record, whose presence means that the sandbox is provisioned, and any others, as `CallerFiles`, and takes the lifecycle locks with them: `SandboxStore::lock_for_provision` creates the directory, again if a removal deletes it meanwhile, `SandboxStore::lock_existing` fails with `ErrorKind::NotFound` once it is gone, and a holder that leaves the directory without the configuration record removes its lock file as it releases the lock. `LockedStore::remove` removes a sandbox that no VMM can run in, for a caller that declares its configuration record: the store's files, the caller's, and the directory, unless it holds entries that are neither, which it refuses and keeps, and `Lingering` waits for open files, such as the lock files of other transitions, that keep the emptied directory; both remove the directory only while the path still names it. The store also owns the file in which the VMM stages its outcome report, which a VMM that is killed while it writes the report leaves, and removes it once no process of its launch runs | -| `nvx::host::instance` | `Instance`: a VM in a sandbox store of its own, which `nvx::host::store`, `nvx::host::supervisor`, and `nvx::host::session` drive, and in which the caller keeps the files that it declares as `CallerFiles`. Under the store's lifecycle lock of an existing sandbox, `LockedInstance::find` reattaches to the VM, ends a start that was interrupted, and reports a VM of another runtime identity as `Mismatched` rather than driving it; `LockedInstance::start` launches OpenVMM through the supervisor with a fresh capability, under the caller's `RuntimeIdentity`, waits until the guest is ready and has mounted the mapped paths, and commits the launch; `LockedInstance::stop` stops the VM with a forced fallback; and `LockedInstance::remove` removes a stopped instance, with the caller's files and its directory, through the store. `Instance::exec` runs workloads without the lock and pumps their output. `write_json` and `read_json` keep the configuration records that callers store beside an instance | +| `nvx::host::instance` | `Instance`: a VM in a sandbox store of its own, which `nvx::host::store`, `nvx::host::supervisor`, and `nvx::host::session` drive, and in which the caller keeps the files that it declares as `CallerFiles`. Under the store's lifecycle lock of an existing sandbox, `LockedInstance::find` reattaches to the VM, ends a start that was interrupted, and reports a VM of another runtime identity as `Mismatched` rather than driving it; `LockedInstance::start` launches OpenVMM through the supervisor with a fresh capability, under the caller's `RuntimeIdentity`, waits until the guest is ready and has mounted the mapped paths, and commits the launch; `LockedInstance::stop` stops the VM with a forced fallback; `LockedInstance::terminate` stops a `Mismatched` VM by identity-verified forced termination, without a control session or its outcome report; and `LockedInstance::remove` removes a stopped instance, with the caller's files and its directory, through the store. `Instance::exec` runs workloads without the lock and pumps their output. `write_json` and `read_json` keep the configuration records that callers store beside an instance | | `nvx::host::nvxs` | `HostConnection`: the host's role of the NVXS session over a platform transport, on which `nvx::host::session` and other host applications run their protocols. It attaches with the launch capability, waiting while the broker asks it to, sends application bytes in as many DATA records as they take, and returns each DATA payload from the guest, with deadlines; a receive that times out keeps a partial record | | `nvx::host::process` | Verified process references. A `ProcessRef` names one process by its ID, its start time, and the `BootId` of the host boot during which it started. `Process::open` checks a reference and holds its process through a pidfd on Linux or a process handle on Windows, whether or not the caller started it, so that waits sleep until the process exits and termination never reaches a process that reuses its ID. A reference from an earlier boot names an exited process, and a process whose identity this user cannot check, such as another user's, makes `Process::open` fail rather than report an exit. Linux hosts without pidfds poll the reference instead, and cannot terminate the process | -| `nvx::host::supervisor` | The supervisor of a sandbox's VMM, beneath the CLI, `Instance`, and external orchestrators, which keep the configuration, the authorization, and the application protocol. `launch` runs the store's launch steps under the sandbox's lock: it writes the journal's marker, spawns OpenVMM with the claimed log, records its `ProcessRef` right after, and returns a `Starting` launch that the caller commits once the VMM serves its control endpoint, or abandons. A launch that fails never leaves an unrecorded VMM running. `VmmCommand::inherit` lists the descriptors (Linux) or handles (Windows) that the VMM inherits under their numbers, besides its standard streams, and it inherits nothing else of the caller's: on Linux, they must be close-on-exec, a flag that only the VMM's own process clears; on Windows, they join the VMM's explicit handle list. `Vmm::stop` runs one graceful step of the caller's and waits for the VMM's exit event until a deadline, and takes a bounded forced step through the VMM's verified identity only on request. `reattach` recovers an interrupted launch, and holds the recorded VMM again after the orchestrator restarts within the same host boot: `Live`, `Mismatched` with another runtime identity, `Exited`, or `Indeterminate` | +| `nvx::host::supervisor` | The supervisor of a sandbox's VMM, beneath the CLI, `Instance`, and external orchestrators, which keep the configuration, the authorization, and the application protocol. `launch` runs the store's launch steps under the sandbox's lock: it writes the journal's marker, spawns OpenVMM with the claimed log, records its `ProcessRef` right after, and returns a `Starting` launch that the caller commits once the VMM serves its control endpoint, or abandons. A launch that fails never leaves an unrecorded VMM running. `VmmCommand::inherit` lists the descriptors (Linux) or handles (Windows) that the VMM inherits under their numbers, besides its standard streams, and it inherits nothing else of the caller's: on Linux, they must be close-on-exec, a flag that only the VMM's own process clears; on Windows, they join the VMM's explicit handle list. `Vmm::stop` runs one graceful step of the caller's and waits for the VMM's exit event until a deadline, and takes a bounded forced step through the VMM's verified identity only on request. `Vmm::terminate` takes that forced step alone, within the caller's bound, for a VM whose guest the caller must not ask anything, such as one of another runtime identity. `reattach` recovers an interrupted launch, and holds the recorded VMM again after the orchestrator restarts within the same host boot: `Live`, `Mismatched` with another runtime identity, `Exited`, or `Indeterminate` | | `nvx::host::seal` | `FileSeal`: what the host reports about an open file from its metadata alone, without reading it: the platform scheme, the device or volume serial number, the file ID, the kind, the length, the modification time, and on Linux the change time, with a versioned serde form. A seal detects accidental change, not tampering; see [Distro bindings](#distro-bindings) | | `nvx::host::session`, `platform`, `report` | The authenticated control session, which carries NVX's control protocol, `NVXC`, one frame per DATA record of a `HostConnection`; Linux and Windows primitives; and OpenVMM's outcome report | | `nvx::host::sandbox` | The launch profile of `nvx.py sandbox`, ported from the one that `scripts/nvx_tools/sandbox.py` held: `SandboxLaunch`, with the EROFS distro `SandboxLayer`, the one layer that a sandbox takes, the ext4 scratch disk, the entrypoint, arguments, hostname, workload identity, and resource limits, and the `SandboxPlan` that it makes of them. `plan`: `SandboxPlan`, the typed plan of a cold layered launch, which is persistable in a versioned serde form: one read-only `distro` block device, an EROFS filesystem or a GPT disk with the identity that the guest expects of it, if any, an upper, the ext4 scratch disk or RAM, the launch settings, and optionally a `SandboxNetwork`, the guest network and its typed `NetworkPolicy`, whose proxy's URL as the guest sees it the plan reports. A plan knows only the `distro` and `scratch` `BlockRole`s, and gives, for every combination, its `--microvm-sandbox-block` and `--microvm-workload-identity` arguments, with no scratch block device for a RAM upper, and those of its network, which `nvx::host::network` lowers, and its kernel command line, with the boot tokens of `nvx::protocol::root`, within the 1024-byte budget that OpenVMM leaves it, refusing one whose root tokens the guest's parser refuses. `mount`: `SandboxMount` live shares of host directories and files, their guest targets and the reserved ones, their access policies and owner, the aggregate of several shares, and the checks of their host paths. `options`: the checks that `nvx.py sandbox` and `nvx.py run` apply to their options: the attribution of `--mount-deny`, `--mount-allow`, and `--mount-write` to shares, the systemd entrypoint check and the explicit verification of the distro layer, the targets of `nvx.py run` shares, and the managed exec environment; see [Python parity](#python-parity). `distro`: the `DistroBinding` of a distro layer, which explicit verification makes or a staging caller imports, and its check from metadata alone, which returns the layer open; see [Distro bindings](#distro-bindings). `scratch`: the `ScratchBinding` of a scratch image, its identity, kind, and length, and its check from metadata alone, which claims the image for one sandbox at a time and returns it open. `prepared`: `PreparedLaunch`, the launch of a plan with the checked files of its block devices, which renders the plan's OpenVMM arguments and kernel command line, naming the checked files as `/proc/self/fd/N` on Linux and by their final paths on Windows, and lists the descriptors that the VMM inherits through `VmmCommand::inherit`; see [Checked handoff](#checked-handoff) | @@ -534,7 +534,9 @@ before them. with its status; `--outcome-report` writes `{"operation_id": HEX, "outcome": {"category": CATEGORY, "operation": "exec", "status_code": STATUS}, "schema_version": 1}`. `stop` shuts the VM - down and prints nothing. `deprovision` removes the state directory. + down and prints nothing, but for a warning when it terminates a VM of another + [runtime identity](#runtime-identity). `deprovision` removes the state + directory. The state directory is the directory of the sandbox's [store](src/host/store/mod.rs), the runtime records that every host of a @@ -575,7 +577,8 @@ state is stale, while `start` launches OpenVMM again and `deprovision` removes the sandbox. `start` launches OpenVMM with `nvx::host::supervisor::launch`, and `stop` asks the guest to shut down through the control session, waits up to `--timeout` seconds for OpenVMM to exit, and reports one that does not, which -keeps running: it never ends OpenVMM otherwise. +keeps running: it never ends OpenVMM otherwise, except one of another +[runtime identity](#runtime-identity). #### Runtime identity @@ -594,12 +597,18 @@ root's install metadata, and no artifact is hashed: `start` needs that metadata, and so does every other transition but `provision` while the store records a start of the sandbox: each fails when -the metadata is missing or names no valid digest. `start` runs the root's own -OpenVMM, which the metadata identifies, and refuses another one that -`NVX_OPENVMM` names. The transitions drive only a VM that the same identity -started: one that other artifacts started, as before they were rebuilt or -replaced, is reported with the parts that differ, and must be stopped with the -artifacts that started it. +the metadata is missing or names no valid digest, and signals nothing. `start` +runs the root's own OpenVMM, which the metadata identifies, and refuses another +one that `NVX_OPENVMM` names. The transitions drive only a VM that the same +identity started. One that other artifacts started, as before they were rebuilt +or replaced, may speak other contracts, so no transition opens a control +session to it: `start` and `exec` refuse it, naming the parts that differ, +`deprovision` refuses it as running, and `stop` terminates its OpenVMM through +its verified process identity, waits up to `--timeout` seconds for it to exit, +and warns on standard error that it did. The guest does not shut down, so +OpenVMM publishes no outcome report. An OpenVMM that does not exit in time, or +whose identity the stop cannot determine, keeps the runtime record, and the +next `stop` retries. The store reads runtime records of its format alone. A sandbox that a build with another format started, such as one whose `runtime.json` has format 1, @@ -676,6 +685,8 @@ guest agents of NVX advertise bits 0, 2, and 4 in sandbox mode. descriptor or handle of `run` beyond its standard streams, as `subprocess.run` passes none with `close_fds`: on Windows, OpenVMM's handle list holds copies of `run`'s standard handles and the scratch image's claim alone. +- `start` and `exec` refuse, and `stop` terminates, a VM that another runtime + identity started; see [Runtime identity](#runtime-identity). ### Test hooks diff --git a/nvx-rs/src/host/cli/sandbox/lifecycle.rs b/nvx-rs/src/host/cli/sandbox/lifecycle.rs index 811d32d8a..133159f9b 100644 --- a/nvx-rs/src/host/cli/sandbox/lifecycle.rs +++ b/nvx-rs/src/host/cli/sandbox/lifecycle.rs @@ -35,10 +35,12 @@ //! OpenVMM that still runs through its verified identity, and clears the runtime record of one //! that exited without a stop, which the first transition to find it reports, or which a start //! replaces. A VM that another runtime identity than the artifacts' started, as after the -//! artifacts were replaced, is reported, and never driven. [`start`] launches OpenVMM with -//! [`supervisor::launch`], under the runtime identity that the install metadata of the artifacts -//! names, and [`stop`] asks the guest to shut down, waits for OpenVMM to exit, and reports a VM -//! that does not, without ending it otherwise. +//! artifacts were replaced, is never driven, since its guest may speak other contracts: [`stop`] +//! ends it by identity-verified forced termination, without a control session, and the other +//! transitions refuse it. [`start`] launches OpenVMM with [`supervisor::launch`], under the +//! runtime identity that the install metadata of the artifacts names, and [`stop`] asks the guest +//! of a VM of that identity to shut down, waits for OpenVMM to exit, and reports a VM that does +//! not, without ending it otherwise. //! //! [`start`] hands OpenVMM, through a [`PreparedLaunch`] of the checked files, the objects that //! the checks found, rather than paths that something could replace meanwhile, and claims the @@ -60,7 +62,8 @@ use super::{Artifacts, error_with_cause}; use crate::ErrorKind; use crate::host::cli::deadline::{Deadline, RETRY_INTERVAL}; use crate::host::cli::session::{EXIT_CATEGORIES, ExecRequest, ExecResult, Session}; -use crate::host::cli::{Exit, Result, check_interrupt}; +use crate::host::cli::{Exit, Result, check_interrupt, output}; +use crate::host::launch::MAX_TIMEOUT; use crate::host::python::builtins::{Int, repr}; use crate::host::python::dumps::{self, Value, dict}; use crate::host::python::fs::{self, os_error_message}; @@ -388,14 +391,21 @@ fn find_vm(locked: &mut LockedStore, artifacts: &Artifacts<'_>) -> Result ) } -/// Returns the error of a VM that another runtime identity than the artifacts' started, which -/// differs in `differences`: the CLI does not drive it, since it may speak other contracts. -fn mismatched(vmm: &Vmm, differences: &[IdentityPart]) -> Exit { +/// Returns the parts of a runtime identity that `differences` names, as messages list them. +fn differing_parts(differences: &[IdentityPart]) -> String { let parts: Vec<&str> = differences.iter().map(|part| part.name()).collect(); + parts.join(", ") +} + +/// Returns the error of a transition other than stop on a VM that another runtime identity than +/// the artifacts' started, which differs in `differences`: the CLI does not drive it, since it may +/// speak other contracts, and only its stop ends it. +fn mismatched(vmm: &Vmm, differences: &[IdentityPart]) -> Exit { Exit::error(format!( - "sandbox runs under another runtime identity than these artifacts, which differ in {}: \ - stop it with the artifacts that started it (OpenVMM process {})", - parts.join(", "), + "sandbox runs under another runtime identity than these artifacts, which differ in {}, \ + so it is not driven: stop it to terminate its OpenVMM process {} without a guest \ + shutdown", + differing_parts(differences), vmm.record().process().pid )) } @@ -408,9 +418,16 @@ struct Running { capability: [u8; CAPABILITY_LEN], } -/// Returns the running VM of the sandbox in the locked store, as exec and stop require it. +/// Returns the running VM of the sandbox in the locked store, as exec requires it. fn running_vm(locked: &mut LockedStore, artifacts: &Artifacts<'_>) -> Result { - let vmm = match find_vm(locked, artifacts)? { + let found = find_vm(locked, artifacts)?; + running(locked, found) +} + +/// Returns the running VM that `found` describes in the locked store, as exec and stop require +/// it, with its control capability. +fn running(locked: &mut LockedStore, found: Found) -> Result { + let vmm = match found { Found::Live(vmm) => vmm, Found::Nothing => return Err(Exit::error("sandbox is not running")), Found::Exited => { @@ -730,17 +747,31 @@ pub(crate) fn exec_workload( session.exec(request, response_timeout) } -/// Stops a running sandbox and returns OpenVMM's outcome report, as `stop` does. +/// Stops a running sandbox and returns OpenVMM's outcome report, as `stop` does, or `None` for a +/// VM that another runtime identity than the artifacts' started. /// /// The supervisor's stop runs one graceful step, which asks the guest to shut the VM down and /// waits up to `timeout` seconds for OpenVMM to exit, so that Ctrl-C ends the wait. A VM whose /// OpenVMM is still running then is reported, and keeps its runtime record: the stop never takes /// the forced step. -pub(crate) fn stop(state_path: &str, artifacts: &Artifacts<'_>, timeout: f64) -> Result { +/// +/// A VM of another runtime identity may speak other contracts, so the stop asks it nothing: it +/// ends the VM as [`terminate_mismatched`] does. +pub(crate) fn stop( + state_path: &str, + artifacts: &Artifacts<'_>, + timeout: f64, +) -> Result> { let state_dir = prepare_state_directory(state_path, false)?; let mut lock = LifecycleLock::acquire(&state_dir, timeout, false)?; let locked = lock.locked(); - let Running { vmm, capability } = running_vm(locked, artifacts)?; + let Running { vmm, capability } = match find_vm(locked, artifacts)? { + Found::Mismatched(vmm, differences) => { + terminate_mismatched(locked, &vmm, &differences, timeout)?; + return Ok(None); + } + found => running(locked, found)?, + }; // The graceful step waits for the exit itself, so the stop's own wait, until a deadline that // has passed by then, only checks whether OpenVMM has exited. let stopped = vmm @@ -758,7 +789,45 @@ pub(crate) fn stop(state_path: &str, artifacts: &Artifacts<'_>, timeout: f64) -> if stopped.outcome == StopOutcome::TimedOut { return Err(Exit::error("OpenVMM did not terminate after managed stop")); } - read_openvmm_outcome(&state_dir.join(OUTCOME_NAME)) + read_openvmm_outcome(&state_dir.join(OUTCOME_NAME)).map(Some) +} + +/// Ends the VM `vmm`, which another runtime identity than the artifacts' started, and which +/// differs from them in `differences`, by identity-verified forced termination, and warns on +/// standard error that it did. +/// +/// Its guest is not asked to shut down, and no control session is opened to it: its OpenVMM is +/// terminated through its verified process identity, as [`Vmm::terminate`] does, and the stop +/// waits up to `timeout` seconds for it to exit. One that does not exit then, or whose exit cannot +/// be determined, fails the stop, and keeps its runtime record, so that a later stop retries. +fn terminate_mismatched( + locked: &mut LockedStore, + vmm: &Vmm, + differences: &[IdentityPart], + timeout: f64, +) -> Result { + // `--timeout` is positive and finite, but may be shorter than a nanosecond or longer than a + // termination may wait. + let bound = Duration::try_from_secs_f64(timeout) + .unwrap_or(MAX_TIMEOUT) + .clamp(Duration::from_nanos(1), MAX_TIMEOUT); + let pid = vmm.record().process().pid; + let parts = differing_parts(differences); + let ended = match vmm.terminate(locked, bound).map_err(error_with_cause)? { + StopOutcome::Forced => "was terminated without a guest shutdown", + StopOutcome::Graceful => "had exited", + StopOutcome::TimedOut => { + return Err(Exit::error(format!( + "OpenVMM process {pid} of the sandbox, which runs under another runtime identity \ + than these artifacts, did not exit after it was terminated" + ))); + } + }; + output::print_stderr(&format!( + "warning: sandbox ran under another runtime identity than these artifacts, which differ \ + in {parts}: its OpenVMM process {pid} {ended}" + )); + Ok(()) } /// Waits until the OpenVMM of `vmm` exits or `deadline` passes, failing if Ctrl-C arrives first. diff --git a/nvx-rs/src/host/instance.rs b/nvx-rs/src/host/instance.rs index 81e8e40f6..da4fcf625 100644 --- a/nvx-rs/src/host/instance.rs +++ b/nvx-rs/src/host/instance.rs @@ -30,7 +30,7 @@ //! forgets a VM that exited, and compares the caller's runtime identity with the one that a //! running VM was launched with. A VM of another runtime identity is [`Found::Mismatched`]: it //! runs through artifacts or contracts that the caller does not have, so the instance does not -//! drive it. +//! drive it, and only ends it. //! - [`LockedInstance::start`] launches a detached OpenVMM process with the managed lifecycle //! through [`supervisor::launch`], passes it a fresh 32-byte capability through standard input, //! and waits until the guest agent answers on the authenticated control console. The agent must @@ -40,6 +40,9 @@ //! cannot mount them all. //! - [`LockedInstance::stop`] asks the guest to shut down and falls back to terminating OpenVMM //! through its verified process identity. +//! - [`LockedInstance::terminate`] stops a mismatched VM: it terminates OpenVMM through its +//! verified process identity, opens no control session, whose protocol the guest might not +//! speak, and reads no outcome report, which follows the other runtime's contracts. //! - [`LockedInstance::remove`] removes a stopped instance, with the caller's files, and its //! directory, through the store's [removal](super::store#removal). //! @@ -275,12 +278,14 @@ pub struct Started { pub boot: Duration, } -/// A VM that [`LockedInstance::stop`] stopped. +/// A VM that [`LockedInstance::stop`] stopped, or that [`LockedInstance::terminate`] ended. #[derive(Debug, Clone, PartialEq, Eq)] pub struct Stopped { - /// Whether OpenVMM had to be terminated because the guest did not shut down in time. + /// Whether OpenVMM was terminated: because the guest did not shut down in time, or because + /// the VM ran under another runtime identity. pub forced: bool, - /// Summary of OpenVMM's outcome report, if it wrote one. + /// Summary of OpenVMM's outcome report, if it wrote one. [`LockedInstance::terminate`] reads + /// none, since the other runtime's OpenVMM wrote it. pub report: Option, } @@ -329,7 +334,7 @@ impl fmt::Debug for Running { } /// The running VM of an instance, which [`LockedInstance::find`] found under another runtime -/// identity than the caller's. +/// identity than the caller's, and which [`LockedInstance::terminate`] ends. #[derive(Debug)] pub struct Mismatched { /// The instance's name in messages. @@ -352,13 +357,14 @@ impl Mismatched { &self.differences } - /// Returns the error that reports the VM, which the instance does not drive: only the build - /// and artifacts that started it speak its contracts. + /// Returns the error that reports the VM, which the instance does not drive, since only the + /// build and artifacts that started it speak its contracts: it names the parts that differ, + /// and that stopping the VM terminates it. pub fn error(&self) -> Error { let parts: Vec<&str> = self.differences.iter().map(|part| part.name()).collect(); Error::other(format!( "sandbox {} runs under another runtime identity, which differs in {}, so it is not \ - driven: stop it with the NVX build and artifacts that started it (OpenVMM process {})", + driven: stop it to terminate its OpenVMM process {} without a guest shutdown", self.name, parts.join(", "), self.vmm.record().process().pid @@ -374,8 +380,8 @@ pub enum Found { Stopped, /// The VM runs under the caller's runtime identity. Running(Running), - /// The VM runs under another runtime identity, which the caller reports, as - /// [`Mismatched::error`] does. + /// The VM runs under another runtime identity: the caller ends it with + /// [`LockedInstance::terminate`], or reports it, as [`Mismatched::error`] does. Mismatched(Mismatched), } @@ -770,6 +776,42 @@ impl LockedInstance { }) } + /// Stops the VM `mismatched`, which runs under another runtime identity than the caller's, by + /// identity-verified forced termination: terminates OpenVMM through its verified process + /// identity, as [`Vmm::terminate`] does, and waits up to `timeout` for it to exit. + /// + /// The VM's guest might not speak this build's control protocol, so the stop opens no control + /// session to it, and does not ask it to shut down: only the OpenVMM process that + /// [`find`](Self::find) verified is signaled. Once OpenVMM has exited, the stop clears the + /// runtime record. It reads no outcome report, so [`Stopped::report`] is `None`: a terminated + /// OpenVMM writes none, and one that exited before it was terminated wrote it under the other + /// runtime's contracts. [`Stopped::forced`] is false only for an OpenVMM that exited before it + /// was terminated. + /// + /// Fails with [`ErrorKind::Unsupported`] when `timeout` is zero or longer than + /// [`MAX_TIMEOUT`](super::launch::MAX_TIMEOUT), and when OpenVMM's state cannot be + /// determined, OpenVMM cannot be terminated, or it does not exit within `timeout`: its runtime + /// record then remains, and a later stop retries. + pub fn terminate(&mut self, mismatched: Mismatched, timeout: Duration) -> Result { + check_timeout("stop timeout", timeout, true)?; + let Mismatched { vmm, .. } = mismatched; + let forced = match vmm.terminate(&mut self.locked, timeout)? { + StopOutcome::Graceful => false, + StopOutcome::Forced => true, + StopOutcome::TimedOut => { + return Err(Error::other(format!( + "OpenVMM process {} of sandbox {} did not exit after it was terminated", + vmm.record().process().pid, + self.instance.name + ))); + } + }; + Ok(Stopped { + forced, + report: None, + }) + } + /// Removes the stopped instance: its store's records and files, the caller's files that it /// declared, the configuration record last, and its directory, through the store's /// [`LockedStore::remove`], and releases the lock. Open files, such as the lock files of other diff --git a/nvx-rs/src/host/supervisor/mod.rs b/nvx-rs/src/host/supervisor/mod.rs index f3c685a2a..b61a00ecf 100644 --- a/nvx-rs/src/host/supervisor/mod.rs +++ b/nvx-rs/src/host/supervisor/mod.rs @@ -45,11 +45,7 @@ //! // Other artifacts or contracts started the VM: end it through its verified handle, //! // without a graceful step that it might not understand. //! Reattached::Mismatched { vmm, .. } => { -//! let forced = Some(Duration::from_secs(10)); -//! let stopped = vmm.stop(&mut locked, Instant::now(), forced, |_, _| { -//! Ok::<(), std::convert::Infallible>(()) -//! })?; -//! if stopped.outcome == StopOutcome::TimedOut { +//! if vmm.terminate(&mut locked, Duration::from_secs(10))? == StopOutcome::TimedOut { //! return Err(nvx::Error::timed_out("the VM of another runtime still runs")); //! } //! } @@ -83,13 +79,17 @@ //! //! [`Vmm::stop`] runs one graceful step of the caller's, with a bounded deadline, and takes a //! bounded forced step against the VMM's verified identity only when the caller requests it. +//! [`Vmm::terminate`] takes that forced step alone, with no graceful step: it ends a VM whose +//! guest the caller cannot ask to shut down, such as one that another runtime identity started. //! //! # Reattach //! //! After an orchestrator restarts within the same host boot, [`reattach`] ends an interrupted //! launch with [`LockedStore::recover`], compares the runtime identity of the recorded VM with the //! caller's own, with [`RuntimeRecord::check_identity`], and holds the VMM with -//! [`Process::open`]. A record from an earlier boot names a VMM that has exited. +//! [`Process::open`]. A record from an earlier boot names a VMM that has exited. A VM of another +//! runtime identity is ended with [`Vmm::terminate`], never through the caller's own protocol, +//! which its guest might not speak. //! //! The supervisor signals only a process that it holds through a verified identity: the child //! that it has not released, a [`Process`] that matched its recorded reference, or, during the @@ -395,17 +395,9 @@ impl Vmm { forced: Option, graceful: impl FnOnce(&Self, Instant) -> std::result::Result<(), E>, ) -> Result> { - if locked.dir() != self.store.dir() { - return Err(Error::other(format!( - "the VM of the sandbox in {} cannot be stopped through the store in {}", - self.store.dir().display(), - locked.dir().display() - ))); - } - if let Some(problem) = forced.and_then(|bound| timeout_problem(bound, true)) { - return Err(Error::unsupported(format!( - "the bound of the forced step {problem}" - ))); + self.check_store(locked)?; + if let Some(bound) = forced { + check_bound(bound, "the forced step")?; } let stopped = stop_process( &self.process, @@ -414,29 +406,88 @@ impl Vmm { forced, || graceful(self, deadline), )?; - if stopped.outcome != StopOutcome::TimedOut + self.clear_if_exited(locked, stopped.outcome)?; + Ok(stopped) + } + + /// Ends the VM by identity-verified forced termination: terminates its VMM through its + /// verified handle, and waits up to `bound` for it to exit. It is the forced step of + /// [`stop`](Self::stop), taken alone, with no graceful step before it. + /// + /// It ends a VM whose guest the caller must not ask to shut down, such as one that another + /// runtime identity started, which [`reattach`] reports as [`Reattached::Mismatched`]: its + /// guest might not speak the caller's protocol, so the termination sends it nothing, and runs + /// nothing of the caller's. It signals only the VMM that this holds, whose process ID, start + /// time, and host boot were verified, never a process that reuses its ID. + /// + /// The result says whether the VMM exited: [`StopOutcome::Forced`] once the termination ended + /// it within `bound`, [`StopOutcome::Graceful`] if it had exited before, and was not + /// signaled, and [`StopOutcome::TimedOut`] if it still runs. Once the VMM has exited, the + /// termination clears the runtime record of its launch, as [`stop`](Self::stop) does. A VMM + /// that still runs, or whose exit cannot be determined, keeps its record, so that a later + /// termination may retry. + /// + /// `locked` must be the locked store of the VM's sandbox. Fails with + /// [`ErrorKind::Unsupported`](crate::ErrorKind::Unsupported) if `bound` is zero or longer + /// than [`MAX_TIMEOUT`](super::launch::MAX_TIMEOUT), and fails when the VMM's state cannot be + /// determined, or when it cannot be terminated, as on Linux hosts without pidfds, which cannot + /// hold it. + pub fn terminate(&self, locked: &mut LockedStore, bound: Duration) -> Result { + self.check_store(locked)?; + check_bound(bound, "the termination")?; + let outcome = terminate_process(&self.process, self.record.process().pid, bound)?; + self.clear_if_exited(locked, outcome)?; + Ok(outcome) + } + + /// Fails unless `locked` is the locked store of the VM's sandbox. + fn check_store(&self, locked: &LockedStore) -> Result<()> { + if locked.dir() == self.store.dir() { + return Ok(()); + } + Err(Error::other(format!( + "the VM of the sandbox in {} cannot be stopped through the store in {}", + self.store.dir().display(), + locked.dir().display() + ))) + } + + /// Clears the runtime record of the VM's launch from `locked` once its VMM has exited, which + /// `outcome` tells, unless the record names another launch by then. + fn clear_if_exited(&self, locked: &mut LockedStore, outcome: StopOutcome) -> Result<()> { + if outcome != StopOutcome::TimedOut && locked .runtime()? .is_some_and(|record| record.launch() == self.record.launch()) { locked.clear_runtime()?; } - Ok(stopped) + Ok(()) + } +} + +/// Fails with [`ErrorKind::Unsupported`](crate::ErrorKind::Unsupported) if `bound`, the bound of +/// `what`, is zero or longer than [`MAX_TIMEOUT`](super::launch::MAX_TIMEOUT). +fn check_bound(bound: Duration, what: &str) -> Result<()> { + match timeout_problem(bound, true) { + Some(problem) => Err(Error::unsupported(format!("the bound of {what} {problem}"))), + None => Ok(()), } } -/// How [`Vmm::stop`] ended. +/// How [`Vmm::stop`] or [`Vmm::terminate`] ended. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum StopOutcome { /// The VMM exited without the forced step: by the deadline of the graceful step, or before - /// the stop began. + /// the stop or the termination began. Graceful, - /// The graceful step did not end the VMM, and the forced step that the caller requested - /// terminated it through its verified handle: it exited within the forced step's bound. + /// The forced step terminated the VMM through its verified handle, and it exited within the + /// step's bound: the graceful step of a stop did not end it, or a termination took the step + /// alone. Forced, /// The VMM still runs: it did not exit by the deadline of the graceful step, or, after a - /// graceful step that failed, had not exited, and the caller requested no forced step, or it - /// did not exit within the forced step's bound either. + /// graceful step that failed, had not exited, and the caller requested no forced step; or it + /// did not exit within the bound of the forced step, which a termination takes alone. TimedOut, } @@ -450,7 +501,7 @@ pub struct Stopped { pub graceful_error: Option, } -/// The operations on a VMM that a stop takes, which tests replace. +/// The operations on a VMM that a stop or a termination takes, which tests replace. trait Stoppable { /// Returns whether the VMM has exited, without waiting. fn has_exited(&self) -> io::Result; @@ -486,10 +537,10 @@ fn stop_process( forced: Option, graceful: impl FnOnce() -> std::result::Result<(), E>, ) -> Result> { - let undetermined = |error: io::Error| { - Error::io(format!("cannot determine whether VMM process {pid} exited")).with_source(error) - }; - if process.has_exited().map_err(undetermined)? { + if process + .has_exited() + .map_err(|error| undetermined(pid, error))? + { return Ok(Stopped { outcome: StopOutcome::Graceful, graceful_error: None, @@ -500,21 +551,11 @@ fn stop_process( None => process.wait(deadline), Some(_) => process.has_exited(), } - .map_err(undetermined)?; + .map_err(|error| undetermined(pid, error))?; let outcome = match forced { _ if exited => StopOutcome::Graceful, None => StopOutcome::TimedOut, - Some(bound) => { - process.kill().map_err(|error| { - Error::io(format!("cannot terminate VMM process {pid}")).with_source(error) - })?; - let forced_deadline = Instant::now() + bound; - if process.wait(forced_deadline).map_err(undetermined)? { - StopOutcome::Forced - } else { - StopOutcome::TimedOut - } - } + Some(bound) => force(process, pid, bound)?, }; Ok(Stopped { outcome, @@ -522,6 +563,40 @@ fn stop_process( }) } +/// Terminates the VMM `process`, whose ID is `pid`, unless it has exited, and waits up to `bound` +/// for it to exit, as [`Vmm::terminate`] describes, without clearing its runtime record. +fn terminate_process(process: &impl Stoppable, pid: u32, bound: Duration) -> Result { + if process + .has_exited() + .map_err(|error| undetermined(pid, error))? + { + return Ok(StopOutcome::Graceful); + } + force(process, pid, bound) +} + +/// Takes the forced step of a stop or a termination: terminates the VMM `process`, whose ID is +/// `pid`, through its verified handle, and waits up to `bound` for it to exit. +fn force(process: &impl Stoppable, pid: u32, bound: Duration) -> Result { + process.kill().map_err(|error| { + Error::io(format!("cannot terminate VMM process {pid}")).with_source(error) + })?; + let exited = process + .wait(Instant::now() + bound) + .map_err(|error| undetermined(pid, error))?; + Ok(if exited { + StopOutcome::Forced + } else { + StopOutcome::TimedOut + }) +} + +/// Returns the error of a stop or a termination that cannot determine whether VMM process `pid` +/// exited, for the reason `error`. +fn undetermined(pid: u32, error: io::Error) -> Error { + Error::io(format!("cannot determine whether VMM process {pid} exited")).with_source(error) +} + /// What [`reattach`] found of the VM of a sandbox. #[derive(Debug)] pub enum Reattached { @@ -529,10 +604,11 @@ pub enum Reattached { /// keep driving the VM, which it now holds. Live(Vmm), /// The recorded VMM runs, but was launched with another runtime identity, which would drive - /// the VM through artifacts or contracts that did not start it: the caller must stop it, - /// through the [`Vmm`] that holds it by its verified identity. + /// the VM through artifacts or contracts that did not start it: the caller must end it with + /// [`Vmm::terminate`], which signals only the VMM that the [`Vmm`] holds by its verified + /// identity, and asks its guest nothing. Mismatched { - /// The VM, which the caller must stop. + /// The VM, which the caller must end. vmm: Vmm, /// The parts of the runtime identity that differ, as /// [`RuntimeIdentity::differences`] returns them. diff --git a/nvx-rs/src/host/supervisor/tests.rs b/nvx-rs/src/host/supervisor/tests.rs index 2ef6cb877..7d9ca6218 100644 --- a/nvx-rs/src/host/supervisor/tests.rs +++ b/nvx-rs/src/host/supervisor/tests.rs @@ -115,6 +115,11 @@ impl Scripted { fn operations(&self) -> Vec<&'static str> { self.operations.borrow().clone() } + + /// Terminates the VMM, as [`Vmm::terminate`] does. + fn terminate(&self) -> Result { + terminate_process(self, 7, Duration::from_secs(10)) + } } impl Stoppable for Scripted { @@ -261,6 +266,55 @@ fn undetermined_states_and_failed_terminations_are_errors() { assert_eq!(error.message(), "cannot terminate VMM process 7"); } +#[test] +fn a_termination_takes_the_forced_step_alone() { + // No graceful step runs, even for a VMM that would heed one. + let vmm = Scripted { + heeds_graceful: true, + dies_when_killed: true, + ..Scripted::default() + }; + assert_eq!(vmm.terminate().unwrap(), StopOutcome::Forced); + assert_eq!(vmm.operations(), ["check", "kill", "wait"]); + + // A VMM that outlives the bound still runs. + let survivor = Scripted::default(); + assert_eq!(survivor.terminate().unwrap(), StopOutcome::TimedOut); + assert_eq!(survivor.operations(), ["check", "kill", "wait"]); + + // A VMM that exited already is not signaled. + let exited = Scripted::default(); + exited.exited.set(true); + assert_eq!(exited.terminate().unwrap(), StopOutcome::Graceful); + assert_eq!(exited.operations(), ["check"]); +} + +#[test] +fn terminations_whose_effect_cannot_be_determined_are_errors() { + // A VMM whose state cannot be read is never signaled. + let unreadable = Scripted { + unreadable: true, + dies_when_killed: true, + ..Scripted::default() + }; + let error = unreadable.terminate().unwrap_err(); + assert_eq!(error.kind(), ErrorKind::Io); + assert_eq!( + error.message(), + "cannot determine whether VMM process 7 exited" + ); + assert_eq!(unreadable.operations(), ["check"]); + + let unkillable = Scripted { + unkillable: true, + ..Scripted::default() + }; + let error = unkillable.terminate().unwrap_err(); + assert_eq!(error.kind(), ErrorKind::Io); + assert_eq!(error.message(), "cannot terminate VMM process 7"); + assert_eq!(unkillable.operations(), ["check", "kill"]); +} + #[test] fn a_sandbox_without_a_record_has_no_vm() { let (_directory, store) = store(); diff --git a/nvx-rs/src/testing/fake_openvmm.rs b/nvx-rs/src/testing/fake_openvmm.rs index d8dc4bc45..d58ee599c 100644 --- a/nvx-rs/src/testing/fake_openvmm.rs +++ b/nvx-rs/src/testing/fake_openvmm.rs @@ -47,7 +47,8 @@ //! guest's, `fake_legacy_guest=1` refuses the features request like a guest agent that //! predates it, and `fake_refuse_maps=1` fails every `MAPS` request like a guest that cannot //! mount a mapped path. The command line is recorded in `fake-openvmm-.json` next to the -//! kernel. +//! kernel, and each connection to the control endpoint that the fake accepts adds a line to +//! `fake-openvmm--sessions.log` there, so that a test can tell whether a host connected. //! //! The fake also serves the sandbox profile of `nvx.py sandbox` and `nvx-rs sandbox`, which a //! `--microvm-sandbox-block` option selects: read-only `distro`, `runtime`, and `custom` layers @@ -221,6 +222,8 @@ struct Options { blocks: Vec, /// Artificial delay before the fake opens the sandbox block devices. block_delay: Duration, + /// Path that receives a line for each control connection that the fake accepts. + sessions_log: PathBuf, /// Status with which to stop immediately after launch, when requested. exit_on_start: Option, /// Status with which a one-shot workload ends instead of its own, when requested. @@ -790,6 +793,7 @@ fn parse(program: &str, arguments: &[String]) -> Result { blocks_dump: anchor.with_file_name(format!("fake-openvmm-{token}-blocks.json")), blocks, block_delay: millis("fake_block_delay_ms").unwrap_or_default(), + sessions_log: anchor.with_file_name(format!("fake-openvmm-{token}-sessions.log")), report, hypervisor: hypervisor.to_owned(), exit_on_start: knob("fake_exit_on_start").and_then(|value| value.parse().ok()), @@ -1729,6 +1733,18 @@ fn write_report(options: &Options, operation: &str, category: &str, status_code: } } +/// Records a connection to the control endpoint that the fake accepted, before it reads anything +/// of it, as a line of the session log. +fn record_session(options: &Options) { + if let Ok(mut log) = OpenOptions::new() + .create(true) + .append(true) + .open(&options.sessions_log) + { + let _ = log.write_all(b"connection\n"); + } +} + #[cfg(unix)] /// Serves the fake control endpoint as a Unix-domain socket until a stop request. fn serve(options: &Options, capability: &[u8; CAPABILITY_LEN]) -> io::Result<()> { @@ -1742,6 +1758,7 @@ fn serve(options: &Options, capability: &[u8; CAPABILITY_LEN]) -> io::Result<()> for stream in listener.incoming() { let mut stream = stream?; epoch += 1; + record_session(options); if let Flow::Exit = serve_client(&mut stream, options, capability, epoch, &mut guest) { let _ = fs::remove_file(&options.endpoint); return Ok(()); @@ -1811,6 +1828,7 @@ fn serve(options: &Options, capability: &[u8; CAPABILITY_LEN]) -> io::Result<()> } } epoch += 1; + record_session(options); let flow = serve_client(&mut file, options, capability, epoch, &mut guest); // Wait until the client has read every reply: disconnecting discards unread data. let _ = file.sync_all(); diff --git a/nvx-rs/tests/cli.rs b/nvx-rs/tests/cli.rs index 225e2824d..4c8c3fc12 100644 --- a/nvx-rs/tests/cli.rs +++ b/nvx-rs/tests/cli.rs @@ -1026,20 +1026,17 @@ fn a_restarted_cli_drives_only_a_vm_of_its_runtime_identity() { ); // Artifacts of another kernel did not start the VM, so no transition drives it, and it runs - // on. + // on until a stop terminates it. let kernel = root.below("build/vmlinux.provenance.json"); let provenance = fs::read_to_string(&kernel).unwrap(); - let other = format!( - "{{\"format\": 1, \"kernel_sha256\": \"{}\"}}\n", - "0".repeat(64) - ); - fs::write(&kernel, other).unwrap(); + fs::write(&kernel, other_kernel_provenance()).unwrap(); let pid = record["process"]["pid"].as_u64().unwrap(); let mismatched = format!( "sandbox runs under another runtime identity than these artifacts, which differ in \ - kernel: stop it with the artifacts that started it (OpenVMM process {pid})" + kernel, so it is not driven: stop it to terminate its OpenVMM process {pid} without a \ + guest shutdown" ); - for operation in ["start", "exec", "stop"] { + for operation in ["start", "exec"] { assert_eq!( transition(&root, operation, "state", &[]), failed(&mismatched), @@ -1051,15 +1048,207 @@ fn a_restarted_cli_drives_only_a_vm_of_its_runtime_identity() { failed("sandbox must be stopped before deprovision") ); assert_eq!(runtime_record(&root, "state").unwrap(), record); - assert!(recorded_process(&root, "state").is_some()); + let process = recorded_process(&root, "state").expect("the VM runs"); + + // Its stop terminates OpenVMM through its verified process identity, and says so. It opens no + // control session, whose protocol the guest might not speak. + let sessions = sessions(&root, "state"); + assert!(sessions > 0, "the fake OpenVMM recorded no session"); + assert_eq!( + transition(&root, "stop", "state", &[]), + (Some(0), terminated("kernel", pid)) + ); + assert!(process.has_exited().unwrap()); + assert_eq!(self::sessions(&root, "state"), sessions); + // The terminated OpenVMM published no outcome report, and its log stays. + assert_eq!( + state_entries(&root, "state"), + ["config.json", "openvmm.log", "sandbox.lock"] + ); + assert_eq!( + transition(&root, "stop", "state", &[]), + failed("sandbox is not running") + ); - // The artifacts that started it drive it again. + // The sandbox starts again, and stops gracefully under the identity that started it. fs::write(&kernel, provenance).unwrap(); + assert_eq!(transition(&root, "start", "state", &[]), succeeded()); assert_eq!(transition(&root, "stop", "state", &[]), succeeded()); + assert_eq!(transition(&root, "deprovision", "state", &[]), succeeded()); +} + +/// Returns build provenance that names another kernel than the fixture's. +fn other_kernel_provenance() -> String { + format!( + "{{\"format\": 1, \"kernel_sha256\": \"{}\"}}\n", + "0".repeat(64) + ) +} + +/// Returns the standard error of a stop that terminated OpenVMM process `pid`, which ran under +/// another runtime identity than the artifacts, one that differs in `parts`. +fn terminated(parts: &str, pid: u64) -> String { + format!( + "warning: sandbox ran under another runtime identity than these artifacts, which differ \ + in {parts}: its OpenVMM process {pid} was terminated without a guest shutdown\n" + ) +} + +/// Returns how many connections to its control endpoint the fake OpenVMM of the sandbox in +/// `state` below the root has accepted. +fn sessions(root: &Root, state: &str) -> usize { + fs::read_to_string(root.below(&format!("build/fake-openvmm-{state}-sessions.log"))) + .map_or(0, |log| log.lines().count()) +} + +#[test] +fn a_stop_that_cannot_identify_the_runtime_keeps_the_vm_for_the_next_one() { + let root = populated_root(); + provisioned(&root, "state"); + assert_eq!(transition(&root, "start", "state", &[]), succeeded()); + let record = runtime_record(&root, "state").unwrap(); + let pid = record["process"]["pid"].as_u64().unwrap(); + let process = recorded_process(&root, "state").expect("the VM runs"); + let sessions = sessions(&root, "state"); + + // Without the install metadata of the initramfs, the runtime identity is indeterminate, and so + // is whether the VM may be driven: the stop signals nothing, and keeps its record. + let initramfs = root.below("build/initramfs.provenance.json"); + fs::remove_file(&initramfs).unwrap(); + assert_eq!( + transition(&root, "stop", "state", &[]), + failed(&format!( + "the initramfs build provenance {} is missing, so the runtime cannot be identified: \ + build the artifact with nvx.py, or install a release with nvx.py download", + initramfs.display() + )) + ); + assert_eq!(runtime_record(&root, "state").unwrap(), record); + assert!(!process.has_exited().unwrap()); + + // The next stop, once the metadata names another initramfs, terminates the VM. + fs::write( + &initramfs, + format!( + "{{\"format\": 1, \"initramfs_sha256\": \"{}\"}}\n", + "0".repeat(64) + ), + ) + .unwrap(); + assert_eq!( + transition(&root, "stop", "state", &[]), + (Some(0), terminated("initramfs", pid)) + ); + assert!(process.has_exited().unwrap()); + assert_eq!(self::sessions(&root, "state"), sessions); assert_eq!(runtime_record(&root, "state"), None); assert_eq!(transition(&root, "deprovision", "state", &[]), succeeded()); } +#[test] +fn a_stop_under_another_identity_never_ends_a_process_that_its_record_does_not_name() { + let root = populated_root(); + provisioned(&root, "state"); + let kernel = root.below("build/vmlinux.provenance.json"); + let provenance = fs::read_to_string(&kernel).unwrap(); + let path = root.path.join("state").join("runtime.json"); + // The record names the VMM's ID with another start time, as after the VMM exited and another + // process reused the ID, or names another boot, every process of which has exited. + for field in ["startTime", "boot"] { + fs::write(&kernel, &provenance).unwrap(); + assert_eq!(transition(&root, "start", "state", &[]), succeeded()); + let process = recorded_process(&root, "state").expect("the VM runs"); + let mut record = runtime_record(&root, "state").unwrap(); + record["process"][field] = match &record["process"][field] { + Value::Number(start_time) => json!(start_time.as_u64().unwrap() + 1), + Value::String(boot) => { + let flipped = if boot.starts_with('0') { "1" } else { "0" }; + json!(format!("{flipped}{}", &boot[1..])) + } + other => panic!("unexpected {field}: {other}"), + }; + fs::write(&path, serde_json::to_vec(&record).unwrap()).unwrap(); + // Under another runtime identity, the record names a VMM that exited, so the stop clears + // it, and signals nothing. + fs::write(&kernel, other_kernel_provenance()).unwrap(); + assert_eq!( + transition(&root, "stop", "state", &[]), + failed(STALE), + "{field}" + ); + assert_eq!(runtime_record(&root, "state"), None); + assert!( + !process + .wait(Instant::now() + Duration::from_millis(200)) + .unwrap(), + "{field}" + ); + process.kill().unwrap(); + assert!( + process + .wait(Instant::now() + Duration::from_secs(10)) + .unwrap() + ); + } + assert_eq!(transition(&root, "deprovision", "state", &[]), succeeded()); +} + +#[test] +fn a_start_that_was_interrupted_is_ended_under_another_identity_too() { + let root = populated_root(); + // A guest that answers after a minute keeps the start waiting. + provisioned_with(&root, "state", "fake_boot_delay_ms=60000"); + let mut start = Command::new(NVX_RS) + .arg("--root") + .arg(&root.path) + .args(lifecycle("start", &root, "state")) + .current_dir(&root.path) + .env_remove("NVX_OPENVMM") + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn() + .unwrap(); + // The start recorded its OpenVMM in its launch journal right after it spawned it. + let journal = root.path.join("state").join("launch.json"); + let deadline = Instant::now() + Duration::from_secs(30); + let reference: ProcessRef = loop { + let recorded = fs::read_to_string(&journal) + .ok() + .and_then(|text| serde_json::from_str::(&text).ok()) + .and_then(|journal| serde_json::from_value(journal.get("process")?.clone()).ok()); + if let Some(reference) = recorded { + break reference; + } + assert!(Instant::now() < deadline, "the start recorded no OpenVMM"); + thread::sleep(Duration::from_millis(20)); + }; + // The CLI dies, as a crash would, and leaves its OpenVMM running. + start.kill().unwrap(); + start.wait().unwrap(); + let process = Process::open(&reference) + .unwrap() + .expect("the OpenVMM of the start runs"); + + // Under another runtime identity, the next transition ends the start, whose OpenVMM it + // verifies through the journal. + fs::write( + root.below("build/vmlinux.provenance.json"), + other_kernel_provenance(), + ) + .unwrap(); + assert_eq!( + transition(&root, "stop", "state", &[]), + failed("sandbox is not running") + ); + assert!(process.has_exited().unwrap()); + assert_eq!( + state_entries(&root, "state"), + ["config.json", "openvmm.log", "sandbox.lock"] + ); + assert_eq!(transition(&root, "deprovision", "state", &[]), succeeded()); +} + #[test] fn runtime_records_of_earlier_formats_fail_and_name_their_format() { let root = populated_root(); diff --git a/nvx-rs/tests/fake_openvmm.rs b/nvx-rs/tests/fake_openvmm.rs index 69c68822f..54980df34 100644 --- a/nvx-rs/tests/fake_openvmm.rs +++ b/nvx-rs/tests/fake_openvmm.rs @@ -16,10 +16,11 @@ use std::process::{Command, Stdio}; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use std::thread; -use std::time::Duration; +use std::time::{Duration, Instant}; use nvx::host::instance::{Found, Instance, Running, Started, Stopped, WorkloadOutcome}; use nvx::host::launch::{LaunchSpec, PROCESS_COMMAND_LINE_LIMIT}; +use nvx::host::process::{Process, ProcessRef}; use nvx::host::sandbox::mount::aggregate_child_name; use nvx::host::store::{ArtifactIdentity, CallerFiles, IdentityPart, RuntimeIdentity}; use nvx::protocol::{Workload, WorkloadEnvironment}; @@ -394,7 +395,7 @@ fn a_restarted_orchestrator_reattaches_to_its_vm() { assert_eq!(output.stdout, b"reattached\n"); // Under another runtime identity, as after an upgrade of OpenVMM, the VM is mismatched: it is - // reported, and neither driven nor stopped. + // reported, and not driven. { let mut locked = instance.lock(None).unwrap(); let Found::Mismatched(mismatched) = locked.find(|| Ok(runtime_with('9'))).unwrap() else { @@ -402,22 +403,141 @@ fn a_restarted_orchestrator_reattaches_to_its_vm() { }; assert_eq!(mismatched.differences(), [IdentityPart::OpenVmm]); let error = mismatched.error(); - assert!( - error.message().starts_with( - "sandbox test runs under another runtime identity, which differs in OpenVMM" - ), - "{error}" + assert_eq!( + error.message(), + format!( + "sandbox test runs under another runtime identity, which differs in OpenVMM, so \ + it is not driven: stop it to terminate its OpenVMM process {} without a guest \ + shutdown", + mismatched.vmm().record().process().pid + ) ); } assert_eq!( run(&instance, &workload(&["/bin/echo", "still"]), &idle).stdout, b"still\n" ); - let stopped = stop(&instance, TIMEOUT).unwrap(); - assert!(!stopped.forced); + + // Its stop terminates OpenVMM through its verified process identity, and opens no control + // session, whose protocol the guest might not speak. + let sessions = sessions(directory.path()); + assert!(sessions > 0, "the fake OpenVMM recorded no session"); + let mut locked = instance.lock(None).unwrap(); + let Found::Mismatched(mismatched) = locked.find(|| Ok(runtime_with('9'))).unwrap() else { + panic!("a VM of another runtime identity was not reported"); + }; + let process = Process::open(mismatched.vmm().record().process()) + .unwrap() + .expect("the VM runs"); + for timeout in [Duration::ZERO, Duration::MAX] { + let Found::Mismatched(mismatched) = locked.find(|| Ok(runtime_with('9'))).unwrap() else { + panic!("a VM of another runtime identity was not reported"); + }; + let error = locked.terminate(mismatched, timeout).unwrap_err(); + assert_eq!(error.kind(), ErrorKind::Unsupported, "{error}"); + } + assert!(!process.has_exited().unwrap()); + let stopped = locked.terminate(mismatched, TIMEOUT).unwrap(); + assert!(stopped.forced); + // A terminated OpenVMM reports no outcome. + assert!(stopped.report.is_none()); + assert!(process.has_exited().unwrap()); + assert_eq!(self::sessions(directory.path()), sessions); + drop(locked); + assert!(matches!(find(&instance), Found::Stopped)); assert!(records_nothing(&instance)); } +/// Returns how many connections to its control endpoint the fake OpenVMM of the instance `vm`, +/// whose guest artifacts are in `directory`, has accepted. +fn sessions(directory: &Path) -> usize { + fs::read_to_string(directory.join("fake-openvmm-vm-sessions.log")) + .map_or(0, |log| log.lines().count()) +} + +#[test] +fn outcome_reports_of_another_runtime_are_never_read() { + let directory = tempfile::tempdir().unwrap(); + let (spec, instance) = setup(directory.path()); + // A report beside a VM of another runtime identity is that runtime's, under its contracts, so + // its stop reads none: neither when it terminates OpenVMM nor when OpenVMM exited, and + // published its report, after the VM was found. + for exits_first in [false, true] { + start(&instance, &spec).unwrap(); + let mut locked = instance.lock(None).unwrap(); + let Found::Mismatched(mismatched) = locked.find(|| Ok(runtime_with('9'))).unwrap() else { + panic!("a VM of another runtime identity was not reported"); + }; + let process = Process::open(mismatched.vmm().record().process()) + .unwrap() + .expect("the VM runs"); + fs::write( + instance.report_path(), + r#"{"schema_version":1,"outcome":{"operation":"managed","category":"success", + "status_code":0},"teardown":{"workers":true}}"#, + ) + .unwrap(); + if exits_first { + process.kill().unwrap(); + assert!(process.wait(Instant::now() + TIMEOUT).unwrap()); + } + let stopped = locked.terminate(mismatched, TIMEOUT).unwrap(); + assert_eq!( + stopped, + Stopped { + forced: !exits_first, + report: None, + } + ); + assert!(process.has_exited().unwrap()); + drop(locked); + assert!(records_nothing(&instance)); + } +} + +#[test] +fn records_that_name_another_process_never_end_it() { + let directory = tempfile::tempdir().unwrap(); + let (spec, instance) = setup(directory.path()); + let path = instance.dir().join("runtime.json"); + // The record names the VMM's ID with another start time, as after the VMM exited and another + // process reused the ID, or names another boot, every process of which has exited. + let tampers: [fn(&mut serde_json::Value); 2] = [ + |record| { + let start_time = record["process"]["startTime"].as_u64().unwrap(); + record["process"]["startTime"] = (start_time + 1).into(); + }, + |record| { + let boot = record["process"]["boot"].as_str().unwrap(); + let flipped = if boot.starts_with('0') { "1" } else { "0" }; + record["process"]["boot"] = format!("{flipped}{}", &boot[1..]).into(); + }, + ]; + for tamper in tampers { + start(&instance, &spec).unwrap(); + let mut record: serde_json::Value = + serde_json::from_slice(&fs::read(&path).unwrap()).unwrap(); + let reference: ProcessRef = serde_json::from_value(record["process"].clone()).unwrap(); + let process = Process::open(&reference).unwrap().expect("the VM runs"); + tamper(&mut record); + fs::write(&path, serde_json::to_vec(&record).unwrap()).unwrap(); + // Under another runtime identity too, the VM is found stopped, and its record is cleared, + // but the process that its ID names is not signaled. + let mut locked = instance.lock(None).unwrap(); + let found = locked.find(|| Ok(runtime_with('9'))).unwrap(); + assert!(matches!(found, Found::Stopped), "{found:?}"); + drop(locked); + assert!(records_nothing(&instance)); + assert!( + !process + .wait(Instant::now() + Duration::from_millis(200)) + .unwrap() + ); + process.kill().unwrap(); + assert!(process.wait(Instant::now() + TIMEOUT).unwrap()); + } +} + /// Runs the fake in `directory` as `nvx.py run` runs OpenVMM on the terminal: with two /// processors and the backend of this host, and then `arguments`. fn run_microvm(directory: &Path, arguments: &[&str]) -> std::process::Output { diff --git a/nvx-rs/tests/supervisor.rs b/nvx-rs/tests/supervisor.rs index 0ee95ac47..c51226bda 100644 --- a/nvx-rs/tests/supervisor.rs +++ b/nvx-rs/tests/supervisor.rs @@ -28,6 +28,8 @@ use std::sync::{Mutex, MutexGuard, PoisonError, mpsc}; use std::thread; use std::time::{Duration, Instant}; +use nvx::ErrorKind; +use nvx::host::launch::MAX_TIMEOUT; use nvx::host::process::{BootId, Process, ProcessRef, WaitMethod}; #[cfg(windows)] use nvx::host::store::FORMAT; @@ -897,9 +899,10 @@ fn a_committed_vmm_outlives_its_orchestrator_and_stops_gracefully() { } #[test] -fn a_vmm_of_another_runtime_is_ended_only_by_a_requested_forced_step() { +fn a_vmm_of_another_runtime_is_ended_only_by_its_termination() { let _spawns = serialized(); let (_directory, store) = sandbox(); + let (_other_directory, other) = sandbox(); let mut vmm = VmmDirectory::new(); let mut locked = store.lock(None).unwrap(); // The orchestrator that launched the VMM restarts. @@ -923,20 +926,41 @@ fn a_vmm_of_another_runtime_is_ended_only_by_a_requested_forced_step() { .stop(&mut locked, Instant::now() + SHORT_WAIT, None, ignored) .unwrap(); assert_eq!(stopped.outcome, StopOutcome::TimedOut); + // A termination through another sandbox's store, or with a bound that is zero or too long, + // signals nothing. + let error = running + .terminate(&mut other.lock(None).unwrap(), TIMEOUT) + .unwrap_err(); + assert_eq!(error.kind(), ErrorKind::Other, "{error}"); + for bound in [Duration::ZERO, MAX_TIMEOUT + Duration::from_secs(1)] { + let error = running.terminate(&mut locked, bound).unwrap_err(); + assert_eq!(error.kind(), ErrorKind::Unsupported, "{bound:?}"); + } assert!(!running.has_exited().unwrap()); assert!(store.runtime().unwrap().is_some()); - // The forced step that the caller requests ends it through its verified handle. - let stopped = running - .stop( - &mut locked, - Instant::now() + SHORT_WAIT, - Some(TIMEOUT), - ignored, - ) - .unwrap(); - assert_eq!(stopped.outcome, StopOutcome::Forced); + + // The termination ends it through its verified handle, with no graceful step, and clears its + // runtime record. The log outlives it. + assert_eq!( + running.terminate(&mut locked, TIMEOUT).unwrap(), + StopOutcome::Forced + ); assert_ended(running.process()); assert!(store.runtime().unwrap().is_none()); + assert!(store.read_capability().is_err()); + assert!(store.log_path().exists()); + // A VMM that exited is not signaled again. + assert_eq!( + running.terminate(&mut locked, TIMEOUT).unwrap(), + StopOutcome::Graceful + ); + match supervisor::reattach(&mut locked, &upgraded).unwrap() { + Reattached::Exited { + record: None, + recovery: Recovery::Clean, + } => {} + other => panic!("unexpected reattach: {other:?}"), + } } #[test] @@ -950,9 +974,13 @@ fn records_of_reused_ids_and_earlier_boots_name_vmms_that_exited() { let path = store.dir().join(RUNTIME_NAME); let recorded: serde_json::Value = serde_json::from_slice(&fs::read(&path).unwrap()).unwrap(); // The recorded ID with another start time names another process, which reused the ID after - // the VMM exited, and a record of another boot names a VMM that exited with that boot. + // the VMM exited, and a record of another boot names a VMM that exited with that boot. Under + // another runtime identity too, neither is mismatched, which would end it: only a VMM that + // reattach verified is. let mut other_boot = *reference.boot.as_bytes(); other_boot[0] ^= 1; + let mut upgraded = runtime(); + upgraded.kernel = artifact('5'); for (field, value) in [ ("startTime", json!(reference.start_time + 1)), ("boot", json!(BootId::from_bytes(other_boot))), @@ -963,7 +991,7 @@ fn records_of_reused_ids_and_earlier_boots_name_vmms_that_exited() { let Reattached::Exited { record: Some(record), recovery: Recovery::Clean, - } = supervisor::reattach(&mut locked, &runtime()).unwrap() + } = supervisor::reattach(&mut locked, &upgraded).unwrap() else { panic!("a record with another {field} named a live VMM"); }; @@ -1469,6 +1497,55 @@ fn a_process_that_this_user_may_not_terminate_is_waited_for_but_never_signaled() assert_ended(&process); } +#[cfg(windows)] +#[test] +fn a_vmm_of_another_runtime_that_cannot_be_terminated_keeps_its_record() { + use windows_sys::Win32::System::Threading::{ + PROCESS_QUERY_LIMITED_INFORMATION, PROCESS_SYNCHRONIZE, PROCESS_TERMINATE, + }; + + let _spawns = serialized(); + let (mut child, reference) = + restricted::spawn(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_SYNCHRONIZE); + if restricted::may_open(&child.0, PROCESS_TERMINATE) { + eprintln!("skipping: this user's privileges bypass the security descriptors of processes"); + return; + } + // Another build of the orchestrator, which would launch another kernel, finds the VM. + let (_directory, store) = sandbox(); + write_record(&store, &reference); + let mut upgraded = runtime(); + upgraded.kernel = artifact('5'); + let mut locked = store.lock(None).unwrap(); + let Reattached::Mismatched { vmm, differences } = + supervisor::reattach(&mut locked, &upgraded).unwrap() + else { + panic!("a VMM of another runtime was not reported as mismatched"); + }; + assert_eq!(differences, [IdentityPart::Kernel]); + // The termination fails, and reports it: the VMM still runs, and keeps its record. + let error = vmm.terminate(&mut locked, TIMEOUT).unwrap_err(); + assert_eq!(error.kind(), ErrorKind::Io, "{error}"); + assert_eq!( + error.message(), + format!("cannot terminate VMM process {}", reference.pid) + ); + assert!(store.runtime().unwrap().is_some()); + assert!( + child.0.try_wait().unwrap().is_none(), + "the process was ended" + ); + + // Once the VMM has exited, the next termination finds it so, and clears the record. + child.0.kill().unwrap(); + assert!(vmm.wait(Instant::now() + TIMEOUT).unwrap()); + assert_eq!( + vmm.terminate(&mut locked, TIMEOUT).unwrap(), + StopOutcome::Graceful + ); + assert!(store.runtime().unwrap().is_none()); +} + /// Processes whose security descriptor restricts what this user may do with them. #[cfg(windows)] mod restricted { From a98800c6a37157b8f7ecb86ba349432d5fc42805 Mon Sep 17 00:00:00 2001 From: Enrique Saurez Date: Wed, 21 Oct 2026 22:36:05 -0700 Subject: [PATCH 2/4] scripts: check another runtime identity in sandbox-lifecycle The scenario now restarts the CLI under an artifact root whose build provenance names another initramfs, as after an upgrade, while the sandbox runs. That CLI must refuse to exec and start, and deprovision must find the sandbox running, while the CLI of the checkout still drives the VM. Its stop must then terminate OpenVMM without a guest shutdown, warn that it did, and leave no runtime record, capability, or control endpoint, after which the sandbox starts again. Part of #622 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 84d06582-33fd-47b2-954e-904c4ea1a084 --- doc/run.md | 9 + scripts/nvx_tools/sandbox_lifecycle_tests.py | 171 +++++++++++++++++-- scripts/test_microvm_tests.py | 129 ++++++++++++-- 3 files changed, 286 insertions(+), 23 deletions(-) diff --git a/doc/run.md b/doc/run.md index 2d28540e6..14f63abcc 100644 --- a/doc/run.md +++ b/doc/run.md @@ -1303,6 +1303,15 @@ named. It checks that: - two overlapping `start` calls then launch a single OpenVMM process: one succeeds, and the other fails with `sandbox is already running or has stale runtime state`; +- the `nvx-rs` CLI of an artifact root whose build provenance names another + initramfs, as after an upgrade, drives no VM that the checkout's artifacts + started: its `exec` and `start` fail, naming the initramfs and OpenVMM's + process ID, and its `deprovision` fails because the sandbox runs, without + changing the runtime record or OpenVMM process, while the checkout's CLI + still serves requests. Its `stop` then terminates OpenVMM without a guest + shutdown and warns that it did, and leaves only `config.json`, + `sandbox.lock`, and `openvmm.log`, without a control socket or pipe, after + which its `stop` finds the sandbox not running, and the sandbox starts again; - after OpenVMM exits without a `stop`, `exec` reports the stale runtime state once and clears it, after which `stop` finds the sandbox not running, and the state directory holds only `config.json`, `sandbox.lock`, and `openvmm.log`, diff --git a/scripts/nvx_tools/sandbox_lifecycle_tests.py b/scripts/nvx_tools/sandbox_lifecycle_tests.py index eea9b81da..aa151d0ab 100644 --- a/scripts/nvx_tools/sandbox_lifecycle_tests.py +++ b/scripts/nvx_tools/sandbox_lifecycle_tests.py @@ -5,9 +5,10 @@ checks identity admission, fail-closed lifecycle transitions, that overlapping starts launch one VM, warm-guest state across exec requests and restarts, the guest security profile and resource limits, bounded output and outcome reports, -and that stop, a crash, and deprovision leave no OpenVMM process, control -endpoint, capability, or runtime record behind while the supplied layer and -scratch artifacts stay intact. +that the CLI of artifacts of another runtime identity drives no VM that these +started and its stop terminates OpenVMM, and that stop, a crash, and +deprovision leave no OpenVMM process, control endpoint, capability, or runtime +record behind while the supplied layer and scratch artifacts stay intact. """ from __future__ import annotations @@ -28,7 +29,13 @@ from pathlib import Path from typing import Any, cast -from .build_constants import BuildConstants +from . import nvx_rs +from .build_constants import ( + BuildConstants, + InitramfsBuildConstants, + KernelBuildConstants, + OpenVMMBuildConstants, +) from .common import sha256_file from .managed_exec_tests import ( WorkloadArtifacts, @@ -91,6 +98,49 @@ CRASHED_ENTRIES = frozenset({CONFIG, LOCK, LOG}) ALREADY_RUNNING = b"sandbox is already running or has stale runtime state" STALE = b"sandbox runtime state is stale because the OpenVMM process is not running" +# nvx-rs reads the runtime identity of a checkout from the build provenance of +# its OpenVMM, kernel, and initramfs alone, without hashing an artifact. +PROVENANCE_NAMES = ( + OpenVMMBuildConstants.PROVENANCE_NAME, + KernelBuildConstants.PROVENANCE_NAME, + InitramfsBuildConstants.PROVENANCE_NAME, +) +INITRAMFS_DIGEST = "initramfs_sha256" + + +def other_runtime_refusal(pid: int) -> bytes: + """Returns the error of a start or exec of a VM that the artifacts of another + initramfs started, whose OpenVMM process is pid.""" + return ( + "sandbox runs under another runtime identity than these artifacts, " + "which differ in initramfs, so it is not driven: stop it to terminate " + f"its OpenVMM process {pid} without a guest shutdown" + ).encode() + + +def other_runtime_termination(pid: int) -> bytes: + """Returns the warning of a stop that terminated such a VM's OpenVMM.""" + return ( + "warning: sandbox ran under another runtime identity than these " + "artifacts, which differ in initramfs: its OpenVMM process " + f"{pid} was terminated without a guest shutdown\n" + ).encode() + + +def read_build_provenance() -> dict[str, dict[str, Any]]: + """Returns the build provenance from which nvx-rs reads the runtime identity + of the checkout, by file name.""" + provenance: dict[str, dict[str, Any]] = {} + for name in PROVENANCE_NAMES: + path = BuildConstants.BUILD_DIR / name + try: + value: object = json.loads(path.read_text(encoding="utf-8")) + except (OSError, UnicodeDecodeError, json.JSONDecodeError) as error: + raise RuntimeError(f"build provenance is unreadable: {path}") from error + if not isinstance(value, dict): + raise RuntimeError(f"build provenance is not an object: {path}") + provenance[name] = cast(dict[str, Any], value) + return provenance def openvmm_processes(marker: str) -> tuple[int, ...]: @@ -299,6 +349,8 @@ def __init__( self.state = root / "state" self.identity_state = root / "identity-state" self.scratch = root / "scratch.ext4" + # An artifact root whose runtime identity differs in the initramfs. + self.other_root = root / "other-runtime" self.checks: list[dict[str, object]] = [] def launch_options(self, scratch: Path) -> list[str]: @@ -314,14 +366,22 @@ def launch_options(self, scratch: Path) -> list[str]: ] def run_cli( - self, operation: str, *arguments: str, state: Path | None + self, + operation: str, + *arguments: str, + state: Path | None, + root: Path | None = None, ) -> subprocess.CompletedProcess[bytes]: - command = [ - sys.executable, - str(BuildConstants.REPO_ROOT / "scripts" / "nvx.py"), - "sandbox", - operation, - ] + """Runs one public operation with `nvx.py sandbox`, or, under the + artifact root `root`, with the nvx-rs that it runs.""" + if root is None: + command = [ + sys.executable, + str(BuildConstants.REPO_ROOT / "scripts" / "nvx.py"), + ] + else: + command = [str(nvx_rs.require_binary()), "--root", str(root)] + command.extend(("sandbox", operation)) if state is not None: command.extend(("--state-dir", str(state))) command.extend(("--timeout", str(self.timeout), *arguments)) @@ -359,13 +419,15 @@ def invoke( state: Path | None, expected: int | None = 0, diagnostic: bytes | None = None, + root: Path | None = None, ) -> subprocess.CompletedProcess[bytes]: """Runs one public operation and records only its bounded observations. It requires status `expected` unless that is None, and `diagnostic` in - standard error when given. + standard error when given. With `root`, the operation runs under that + artifact root. """ - result = self.run_cli(operation, *arguments, state=state) + result = self.run_cli(operation, *arguments, state=state, root=root) self.record(operation, result, state=state, expected=expected) if (expected is not None and result.returncode != expected) or ( diagnostic is not None and diagnostic not in result.stderr @@ -457,6 +519,8 @@ def run(self) -> None: restarted = self.start_overlapping() result = self.exec("/bin/cat", f"--arg={STATE_PATH}", expected=None) self.require_output(result, STATE_CONTENT, "the restarted sandbox's state") + self.check_other_runtime(restarted) + restarted = self.start(description="start after the termination") self.check_crash(restarted) self.check_deprovision() if not self.scratch.is_file(): @@ -772,6 +836,87 @@ def stop(self, runtime: dict[str, Any], layer_digest: str) -> None: self.state, STOPPED_ENTRIES, f"after {operation} after stop" ) + def write_other_runtime(self) -> None: + """Writes the checkout's build provenance into the other artifact root, + with another initramfs digest, so that nvx-rs reads a runtime identity + there that differs from the checkout's in the initramfs.""" + build = self.other_root / BuildConstants.BUILD_DIRECTORY_NAME + build.mkdir(parents=True) + for name, provenance in read_build_provenance().items(): + if name == InitramfsBuildConstants.PROVENANCE_NAME: + digest = provenance.get(INITRAMFS_DIGEST) + if not isinstance(digest, str): + raise RuntimeError(f"build provenance {name} names no initramfs") + provenance = { + **provenance, + INITRAMFS_DIGEST: hashlib.sha256(digest.encode()).hexdigest(), + } + (build / name).write_text(json.dumps(provenance), encoding="utf-8") + + def check_other_runtime(self, runtime: dict[str, Any]) -> None: + # The CLI of other artifacts, as after an upgrade, reattaches to the VM + # but drives it through no control session, since the VM may speak + # other contracts: it refuses to start or exec, and its stop terminates + # OpenVMM without a guest shutdown, so OpenVMM reports no outcome. + self.write_other_runtime() + pid = recorded_pid(runtime) + record = (self.state / RUNTIME).read_bytes() + for operation, arguments, diagnostic in ( + ("exec", ("--entrypoint", "/bin/true"), other_runtime_refusal(pid)), + ("start", (), other_runtime_refusal(pid)), + ("deprovision", (), b"sandbox must be stopped before deprovision"), + ): + self.invoke( + operation, + *arguments, + state=self.state, + expected=1, + diagnostic=diagnostic, + root=self.other_root, + ) + self.require_entries( + self.state, RUNNING_ENTRIES, "after the refusals of another runtime" + ) + if (self.state / RUNTIME).read_bytes() != record: + raise RuntimeError("another runtime changed the runtime record") + self.require_processes((pid,), "after the refusals of another runtime") + # The artifacts that started the VM still drive it. + result = self.exec("/bin/cat", f"--arg={STATE_PATH}", expected=None) + self.require_output( + result, STATE_CONTENT, "the state after the refusals of another runtime" + ) + + result = self.invoke("stop", state=self.state, root=self.other_root) + # The CLI ends its lines as the platform's text streams do. + stderr = result.stderr.replace(b"\r\n", b"\n") + if result.stdout or stderr != other_runtime_termination(pid): + raise RuntimeError( + "the stop of another runtime printed " + f"stdout={bounded_text(result.stdout)!r}, " + f"stderr={bounded_text(result.stderr)!r}, expected the warning " + f"{other_runtime_termination(pid).decode()!r}" + ) + self.require_entries( + self.state, CRASHED_ENTRIES, "after the stop of another runtime" + ) + if openvmm_running(runtime, self.root.name): + raise RuntimeError("OpenVMM still runs after the stop of another runtime") + if control_endpoint_present(runtime): + raise RuntimeError( + "the stop of another runtime left the control endpoint behind" + ) + self.require_processes((), "after the stop of another runtime") + self.invoke( + "stop", + state=self.state, + expected=1, + diagnostic=b"sandbox is not running", + root=self.other_root, + ) + self.require_entries( + self.state, CRASHED_ENTRIES, "after a repeated stop of another runtime" + ) + def check_crash(self, runtime: dict[str, Any]) -> None: # OpenVMM exits without a stop. The next transition finds that it # exited, reports it once, and clears its runtime record. diff --git a/scripts/test_microvm_tests.py b/scripts/test_microvm_tests.py index c0657dd66..7facaadc7 100644 --- a/scripts/test_microvm_tests.py +++ b/scripts/test_microvm_tests.py @@ -895,6 +895,13 @@ def test_failed_stop_attempts_guarded_deprovision(self): _LIFECYCLE_STATE_SCRIPT = 'printf \'%s\\n\' "$@" >"$0"' _CliResult = tuple[int, bytes, bytes] +# Each part of a runtime identity, as nvx-rs names it, its key in the runtime +# record, and the build provenance that names its digest, by its field. +_RUNTIME_PROVENANCE = ( + ("OpenVMM", "openvmm", "openvmm.provenance.json", "executable_sha256"), + ("kernel", "kernel", "vmlinux.provenance.json", "kernel_sha256"), + ("initramfs", "initramfs", "initramfs.provenance.json", "initramfs_sha256"), +) class _FakeSandboxCli: @@ -929,11 +936,17 @@ def __call__( return self._dispatch(command) def _dispatch(self, command: list[str]) -> subprocess.CompletedProcess[bytes]: - operation = command[3] + # nvx.py runs `sandbox OPERATION`, and the acceptance runs nvx-rs + # itself, as `--root ROOT sandbox OPERATION`, under another artifact + # root. + position = command.index("sandbox") + operation = command[position + 1] self.operations.append(operation) - values: dict[str, str] = {} + values: dict[str, str] = ( + {"--root": command[2]} if command[1] == "--root" else {} + ) arguments: list[str] = [] - index = 4 + index = position + 2 while index < len(command): if command[index].startswith("--arg="): arguments.append(command[index].removeprefix("--arg=")) @@ -987,6 +1000,33 @@ def _clear_runtime(state: Path) -> None: for name in ("control.capability", "control.sock", "runtime.json"): (state / name).unlink(missing_ok=True) + def _differences( + self, values: dict[str, str], runtime: dict[str, object] + ) -> list[str]: + """Returns the parts in which the runtime identity of the VM differs + from that of the artifacts of the command's root, which nvx-rs reads + from their build provenance.""" + if "--root" not in values or "other-runtime-driven" in self.faults: + return [] + recorded = cast(dict[str, str], runtime["runtime"]) + build = Path(values["--root"]) / "build" + return [ + part + for part, key, name, field in _RUNTIME_PROVENANCE + if recorded[key] + != "sha256:" + json.loads((build / name).read_text(encoding="utf-8"))[field] + ] + + def _other_runtime( + self, runtime: dict[str, object], parts: list[str] + ) -> _CliResult: + pid = cast(dict[str, object], runtime["process"])["pid"] + return self._error( + "sandbox runs under another runtime identity than these artifacts, " + f"which differ in {', '.join(parts)}, so it is not driven: stop it to " + f"terminate its OpenVMM process {pid} without a guest shutdown" + ) + def _run( self, state: Path | None, values: dict[str, str], _: list[str] ) -> _CliResult: @@ -1027,7 +1067,7 @@ def _provision( return 0, b"", b"" def _start( - self, state: Path | None, _: dict[str, str], __: list[str] + self, state: Path | None, values: dict[str, str], _: list[str] ) -> _CliResult: assert state is not None refusal = self._missing(state) @@ -1037,6 +1077,8 @@ def _start( if runtime_path.exists() and "duplicate-start" not in self.faults: runtime = json.loads(runtime_path.read_text(encoding="utf-8")) if self.running.get(runtime["process"]["pid"], False): + if parts := self._differences(values, runtime): + return self._other_runtime(runtime, parts) return self._error( "sandbox is already running or has stale runtime state" ) @@ -1126,9 +1168,11 @@ def _exec( self, state: Path | None, values: dict[str, str], arguments: list[str] ) -> _CliResult: assert state is not None - _, refusal = self._running(state) + runtime, refusal = self._running(state) if refusal is not None: return refusal + if parts := self._differences(values, runtime): + return self._other_runtime(runtime, parts) report = ( Path(values["--outcome-report"]) if "--outcome-report" in values else None ) @@ -1193,11 +1237,15 @@ def _exec( ) return returncode, stdout, stderr - def _stop(self, state: Path | None, _: dict[str, str], __: list[str]) -> _CliResult: + def _stop( + self, state: Path | None, values: dict[str, str], _: list[str] + ) -> _CliResult: assert state is not None runtime, refusal = self._running(state) if refusal is not None: return refusal + if parts := self._differences(values, runtime): + return self._terminate_other_runtime(state, runtime, parts) pid = cast(int, cast(dict[str, object], runtime["process"])["pid"]) if "stop-leaks-process" not in self.faults: self.terminate(pid) @@ -1237,6 +1285,28 @@ def _stop(self, state: Path | None, _: dict[str, str], __: list[str]) -> _CliRes ) return 0, b"", b"" + def _terminate_other_runtime( + self, state: Path, runtime: dict[str, object], parts: list[str] + ) -> _CliResult: + # A VM of another runtime identity is asked nothing: its OpenVMM is + # terminated, and publishes no outcome report. + if "other-runtime-stop-refused" in self.faults: + return self._other_runtime(runtime, parts) + pid = cast(int, cast(dict[str, object], runtime["process"])["pid"]) + if "other-runtime-stop-leaks-process" not in self.faults: + self.terminate(pid) + if "other-runtime-stop-keeps-record" not in self.faults: + self._clear_runtime(state) + if "other-runtime-stop-is-silent" in self.faults: + return 0, b"", b"" + return ( + 0, + b"", + "warning: sandbox ran under another runtime identity than these " + f"artifacts, which differ in {', '.join(parts)}: its OpenVMM process " + f"{pid} was terminated without a guest shutdown\n".encode(), + ) + def _deprovision( self, state: Path | None, _: dict[str, str], __: list[str] ) -> _CliResult: @@ -1320,11 +1390,20 @@ class PublicSandboxLifecycleTests(unittest.TestCase): "stop", "exec", "stop", - # Restart with overlapping starts, then a crash, which the next - # transition reports. + # Restart with overlapping starts. "start", "start", "exec", + # The CLI of another runtime identity refuses to drive the VM, which + # the CLI that started it still drives, and its stop terminates it. + "exec", + "start", + "deprovision", + "exec", + "stop", + "stop", + # Start again, then a crash, which the next transition reports. + "start", "exec", "stop", # Deprovision. @@ -1333,6 +1412,13 @@ class PublicSandboxLifecycleTests(unittest.TestCase): "exec", ] + # The checkout's build provenance, which names the identities that the + # fake CLI records for the VMs that it starts. + PROVENANCE = { + name: {"format": 1, field: digit * 64} + for (_, _, name, field), digit in zip(_RUNTIME_PROVENANCE, "123", strict=True) + } + def _run(self, root: Path, fake: _FakeSandboxCli) -> Path: distro = root / "ubuntu-distro.erofs" distro.write_bytes(b"distro") @@ -1357,6 +1443,16 @@ def fixture(prefix: str) -> str: sandbox_lifecycle_tests.tempfile, "mkdtemp", side_effect=fixture ), patch.object(sandbox_lifecycle_tests.subprocess, "run", side_effect=fake), + patch.object( + sandbox_lifecycle_tests, + "read_build_provenance", + return_value=self.PROVENANCE, + ), + patch.object( + sandbox_lifecycle_tests.nvx_rs, + "require_binary", + return_value=Path("nvx-rs"), + ), patch.object( sandbox_lifecycle_tests, "openvmm_processes", @@ -1484,6 +1580,17 @@ def test_acceptance_detects_lifecycle_regressions(self): ), "restart-loses-state": "the restarted sandbox's state returned status 1", "unserialized-starts": "overlapping public starts returned status 0", + "other-runtime-driven": "exec returned 0, expected 1", + "other-runtime-stop-refused": "stop returned 1, expected 0", + "other-runtime-stop-is-silent": ( + "the stop of another runtime printed stdout='', stderr=''" + ), + "other-runtime-stop-leaks-process": ( + "OpenVMM still runs after the stop of another runtime" + ), + "other-runtime-stop-keeps-record": ( + "after the stop of another runtime: the state directory holds" + ), "crash-keeps-runtime": ( "after exec of a crashed sandbox: the state directory holds" ), @@ -1768,8 +1875,10 @@ def _probe( pass return denied if hidden else 0 - def _stop(self, state: Path | None, _: dict[str, str], __: list[str]) -> _CliResult: - result = super()._stop(state, _, __) + def _stop( + self, state: Path | None, values: dict[str, str], _: list[str] + ) -> _CliResult: + result = super()._stop(state, values, _) if result[0] == 0: assert state is not None network = self._network(state) From f97a1c2eb4a6b713bae03790cb044b52f38562ab Mon Sep 17 00:00:00 2001 From: Enrique Saurez Date: Wed, 21 Oct 2026 23:31:02 -0700 Subject: [PATCH 3/4] nvx-rs: version the boot contract apart from the microVM ABI The runtime identity recorded the microVM ABI version as its boot contract, so the version stayed 2 when the boot tokens of a layered root began to name the image's format and could keep the root's upper in RAM (#676). A VM booted with the earlier tokens kept the runtime identity of one booted with the new ones whenever the identities of its artifacts were unchanged. nvx::contract::BOOT_CONTRACT_VERSION now versions the boot contract: the microVM ABI, the kernel command-line tokens that configure the guest, and the root that the guest assembles from them. It is 3, for the image format token and the RAM upper. The module documents when each contract version must change, and a test pins the version beside every token form of a layered root, whose exhaustive matches stop compiling when a format or upper is added. The store's fixtures and the CLI's goldens record boot contract 3. Part of #622 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 84d06582-33fd-47b2-954e-904c4ea1a084 --- aci_edge_sandboxes/README.md | 5 +- nvx-rs/README.md | 10 ++-- nvx-rs/src/contract.rs | 34 ++++++++++++- nvx-rs/src/host/store/identity.rs | 9 ++-- nvx-rs/src/host/store/tests.rs | 4 +- nvx-rs/src/protocol/root.rs | 4 ++ nvx-rs/src/protocol/root/tests.rs | 51 +++++++++++++++++++ nvx-rs/tests/fixtures/cli.json | 26 +++++----- .../store/invalid/launch-without-log.json | 2 +- .../store/invalid/runtime-unknown-field.json | 2 +- .../tests/fixtures/store/launch-prepared.json | 2 +- .../tests/fixtures/store/launch-spawned.json | 2 +- nvx-rs/tests/fixtures/store/runtime.json | 2 +- nvx-rs/tests/store.rs | 6 +++ scripts/test_microvm_tests.py | 2 +- 15 files changed, 129 insertions(+), 32 deletions(-) diff --git a/aci_edge_sandboxes/README.md b/aci_edge_sandboxes/README.md index 6a36322bb..839a14201 100644 --- a/aci_edge_sandboxes/README.md +++ b/aci_edge_sandboxes/README.md @@ -641,8 +641,9 @@ Windows and `$XDG_STATE_HOME/nvx/sandboxes` (default Each sandbox's state directory is the `nvx::host::store` of its VM, which records the runtime identity of the VM's start: the identities of its -OpenVMM, kernel, and initramfs, and the boot and control contract versions of -the build that started it. Every operation finds the sandbox's VM under the +OpenVMM, kernel, and initramfs, and the boot contract, control contract, and +control session versions of the build that started it, which `nvx::contract` +defines. Every operation finds the sandbox's VM under the backend's runtime identity, so a backend never drives a VM that another NVX build, or other artifacts, started. diff --git a/nvx-rs/README.md b/nvx-rs/README.md index 4865679fd..d5e3a4e00 100644 --- a/nvx-rs/README.md +++ b/nvx-rs/README.md @@ -67,7 +67,7 @@ nvx-rs/ | `nvx::protocol::nvxs` | The NVXS session, independent of `NVXC` and of any other application protocol: `RecordType`, `Record`, `encode_record`, and `RecordParser`, which parses records incrementally across partial reads with buffers bounded by one record; `HostSession` and `GuestSession`, the state machines of the host's and the guest's roles, which validate every record's type, identity, and sequence number, and the guest's receive window and credits, without I/O. An application message may span DATA records, and the application's own framing reassembles it | | `nvx::protocol::root` | The boot tokens of a layered root, which the host renders and guests parse by the same rules: a `RootLayout` is a `RootImage` on the `distro` block device, an EROFS filesystem or a GPT disk with the `nvx::uuid::Uuid` that the guest expects of it, if any, over a `RootUpper`, the ext4 scratch disk or RAM. `RootLayout::tokens` renders `nvx_layer=distro,0xd0003000,FORMAT[:IDENTITY]` and `nvx_scratch=0xd0006000,ext4` or `nvx_overlay_upper=ramfs`, and `RootLayout::parse` reads them from a kernel command line, and refuses malformed, repeated, and conflicting tokens and the earlier form without a format, with no fallback that probes the devices. It reads the virtio-mmio devices of the command line with `nvx::protocol::cmdline`, to refuse a RAM upper beside one at the scratch base. `tests/fixtures/root-tokens.json` holds its cases, which the tests of the guest's shell init replay too | | `nvx::protocol::share` | The guest targets that a sandbox's live shares may not take, which the host's `sandbox::mount` and the guest's `root` both refuse: `RESERVED_MOUNT_TARGETS`, the trees where the container runtime mounts or binds, `RESERVED_EXACT_MOUNT_TARGETS`, the directories that it creates, `RESERVED_TARGET_CHARACTERS`, and `reservation`, which tells why a target is reserved | -| `nvx::contract` | The OpenVMM microVM ABI, broker protocol, and control-contract revision that the crate speaks, and `manifest_is_compatible` for a release's `SOURCE-MANIFEST.json` | +| `nvx::contract` | The OpenVMM microVM ABI, boot contract, broker protocol, and control-contract revision that the crate speaks, and when each changes, and `manifest_is_compatible` for a release's `SOURCE-MANIFEST.json` | | `nvx::net` | `Cidr`: IPv4 and IPv6 networks and their subtraction, which `Cidr::parse` reads without host bits and `Cidr::parse_masked` as OpenVMM reads the destination of an egress rule; `is_valid_hostname` and `is_valid_guest_network`, the forms of a VM's hostname and guest address, and `guest_gateway`, the gateway of a guest address | | `nvx::gpt` | `Disk::read`: the protective MBR, primary header, and primary partition entry array of a GPT disk, read through a `ReadAt` source that the caller gives and checked strictly, as UEFI specifies them and as Linux requires them, without ever reading the backup: 128-byte entries, at most 1 MiB of them, used entries first and without holes, a first partition and 1 to 254 layers, extents in the usable blocks without overlap, and unique GUIDs, with checked arithmetic in the disk's logical blocks. `Expected` adds the disk GUID and the partitions' unique GUIDs and sizes that a caller knows, and `Disk::read_first_partition` returns the first partition's opaque bytes, up to a bound and without trailing NUL bytes and whitespace. GUIDs are `nvx::uuid::Uuid`s. It has no dependencies, so the guest and the host's checks of the images that it stages share it | | `nvx::uuid` | `Uuid`: a UUID, such as the GUID of a GPT disk or partition or the UUID of a filesystem, in the order of its canonical text, the one text that it displays and parses: 32 lowercase hexadecimal digits in groups of 8, 4, 4, 4, and 12, joined by hyphens. `from_bytes_le` and `to_bytes_le` convert the layout in which GPT and other EFI GUIDs store their first three groups little-endian. It has no dependencies, so the host and the guest share it | @@ -584,8 +584,12 @@ keeps running: it never ends OpenVMM otherwise, except one of another `start` records the runtime identity of its artifacts in the runtime record: the SHA-256 digests of OpenVMM, the kernel, and the Alpine initramfs, and the -boot and control contract versions of this build. The digests come from the -root's install metadata, and no artifact is hashed: +boot contract, control contract, and control session versions of this build, +which `nvx::contract` defines with the changes that make each one change. The +boot contract covers the microVM ABI, the kernel command-line tokens that +configure the guest, such as those of `nvx::protocol::root`, and the root that +the guest assembles from them. The digests come from the root's install +metadata, and no artifact is hashed: - A release lists them in its `SHA256SUMS`, under `bin/openvmm[.exe]`, `guest/vmlinux`, and `guest/initramfs.cpio.gz`. diff --git a/nvx-rs/src/contract.rs b/nvx-rs/src/contract.rs index b54d44f8f..db5c57538 100644 --- a/nvx-rs/src/contract.rs +++ b/nvx-rs/src/contract.rs @@ -1,11 +1,41 @@ -//! Versions of the OpenVMM control contract that this crate speaks, and the compatibility of NVX -//! releases with it. +//! Versions of the contracts that this crate speaks with OpenVMM and the NVX guest, and the +//! compatibility of NVX releases with them. +//! +//! The store records the boot contract, control contract, and control session versions of the +//! build that started a VM in the VM's runtime identity, `nvx::host::store::RuntimeIdentity`, and a +//! build drives only the VMs whose runtime identity is its own. So each version changes whenever a +//! guest that a build of the earlier version started could not be driven as one that a build of +//! the later version starts: +//! +//! - [`MICROVM_ABI_VERSION`] is the microVM ABI of the pinned OpenVMM: the machine, its devices, +//! and their addresses, through which OpenVMM boots the guest and saves its state. It changes +//! only with an OpenVMM that changes that ABI, and the boot contract changes with it. +//! - [`BOOT_CONTRACT_VERSION`] is the contract between the host and the guests that it boots: the +//! microVM ABI, the kernel command-line tokens through which the host configures the guest, such +//! as the boot tokens of a layered root in [`protocol::root`](crate::protocol::root), and the +//! root that the guest assembles from them. It changes with any of them, such as a token that +//! is added, removed, or read another way, an image format or upper of a layered root, or a +//! change to how the guest assembles or mounts that root. +//! - [`CONTROL_SESSION_PROTOCOL_VERSION`] is the version of the control session, through which the +//! host reaches the guest agent over OpenVMM's control console. It changes with the session's +//! framing, records, credits, or authentication. +//! - [`CONTROL_CONTRACT_REVISION`] is the revision of the control contract that the session +//! carries: the requests, responses, and features of the guest agent. It changes with them. +//! +//! A release declares the microVM ABI version, the control session version, and the control +//! contract revision of its artifacts in its `SOURCE-MANIFEST.json`. //! //! The build script includes this file to check bundled artifacts, so it must not depend on the //! rest of the crate. /// OpenVMM microVM ABI version this crate drives. pub const MICROVM_ABI_VERSION: u64 = 2; +/// Version of the boot contract this crate speaks; see the [module](self) for when it changes. +/// +/// Until version 3, the runtime identity recorded the microVM ABI version, 2, as the boot +/// contract. Version 3 names the format of a layered root's image, `erofs` or `gpt`, in its boot +/// token, and keeps the root's upper in RAM if asked. +pub const BOOT_CONTRACT_VERSION: u64 = 3; /// Control-console broker protocol version this crate speaks. pub const CONTROL_SESSION_PROTOCOL_VERSION: u64 = 1; /// Control contract revision this crate speaks. diff --git a/nvx-rs/src/host/store/identity.rs b/nvx-rs/src/host/store/identity.rs index 7d5288370..d0b3f715c 100644 --- a/nvx-rs/src/host/store/identity.rs +++ b/nvx-rs/src/host/store/identity.rs @@ -172,9 +172,10 @@ pub struct RuntimeIdentity { pub kernel: ArtifactIdentity, /// The guest initramfs. pub initramfs: ArtifactIdentity, - /// The boot contract: the version of the microVM ABI through which OpenVMM boots and - /// configures the guest, [`MICROVM_ABI_VERSION`](contract::MICROVM_ABI_VERSION) in this - /// crate. + /// The boot contract between the host, OpenVMM, and the guest: the microVM ABI, the kernel + /// command-line tokens that configure the guest, and the root that the guest assembles from + /// them, [`BOOT_CONTRACT_VERSION`](contract::BOOT_CONTRACT_VERSION) in this crate. See + /// [`contract`] for when each contract version changes. pub boot_contract: u64, /// The revision of the control contract, /// [`CONTROL_CONTRACT_REVISION`](contract::CONTROL_CONTRACT_REVISION) in this crate: 1 to @@ -198,7 +199,7 @@ impl RuntimeIdentity { openvmm, kernel, initramfs, - boot_contract: contract::MICROVM_ABI_VERSION, + boot_contract: contract::BOOT_CONTRACT_VERSION, control_contract: contract::CONTROL_CONTRACT_REVISION.to_owned(), control_session: contract::CONTROL_SESSION_PROTOCOL_VERSION, } diff --git a/nvx-rs/src/host/store/tests.rs b/nvx-rs/src/host/store/tests.rs index 9459c2343..a0d7abc1b 100644 --- a/nvx-rs/src/host/store/tests.rs +++ b/nvx-rs/src/host/store/tests.rs @@ -83,7 +83,7 @@ fn artifact_identities_are_printable_tokens() { #[test] fn runtime_identities_bind_this_crates_contracts() { let identity = runtime(); - assert_eq!(identity.boot_contract, contract::MICROVM_ABI_VERSION); + assert_eq!(identity.boot_contract, contract::BOOT_CONTRACT_VERSION); assert_eq!( identity.control_contract, contract::CONTROL_CONTRACT_REVISION @@ -149,7 +149,7 @@ fn records_keep_their_json_form() { "openvmm": format!("sha256:{}", "a".repeat(64)), "kernel": format!("sha256:{}", "b".repeat(64)), "initramfs": format!("sha256:{}", "c".repeat(64)), - "bootContract": contract::MICROVM_ABI_VERSION, + "bootContract": contract::BOOT_CONTRACT_VERSION, "controlContract": contract::CONTROL_CONTRACT_REVISION, "controlSession": contract::CONTROL_SESSION_PROTOCOL_VERSION, }); diff --git a/nvx-rs/src/protocol/root.rs b/nvx-rs/src/protocol/root.rs index 12ddba808..a2aea358d 100644 --- a/nvx-rs/src/protocol/root.rs +++ b/nvx-rs/src/protocol/root.rs @@ -19,6 +19,10 @@ //! refuses every other, with no fallback that probes the image or the devices. NVX's shell init //! reads them with the same rules, and refuses the GPT image and the RAM upper, which it cannot //! assemble. +//! +//! The tokens belong to the boot contract that +//! [`BOOT_CONTRACT_VERSION`](crate::contract::BOOT_CONTRACT_VERSION) versions, so a change to +//! them changes that version too. use std::fmt; diff --git a/nvx-rs/src/protocol/root/tests.rs b/nvx-rs/src/protocol/root/tests.rs index 115418ca7..cec40b26e 100644 --- a/nvx-rs/src/protocol/root/tests.rs +++ b/nvx-rs/src/protocol/root/tests.rs @@ -5,6 +5,7 @@ use serde_json::Value; use super::*; +use crate::contract; /// The command lines that every reader of the boot tokens agrees on. const FIXTURE: &str = include_str!("../../../tests/fixtures/root-tokens.json"); @@ -207,3 +208,53 @@ fn parsing_reports_bytes_that_are_not_text() { Some(layout(RootImage::erofs(None), RootUpper::Scratch)) ); } + +/// Returns the name of `format` in the image's token, as the boot contract pins it. A new format +/// stops this match from compiling until the boot contract names it. +fn contracted_format(format: ImageFormat) -> &'static str { + match format { + ImageFormat::Erofs => "erofs", + ImageFormat::Gpt => "gpt", + } +} + +/// Returns the token of `upper`, as the boot contract pins it. A new upper stops this match from +/// compiling until the boot contract names it. +fn contracted_upper(upper: RootUpper) -> &'static str { + match upper { + RootUpper::Scratch => "nvx_scratch=0xd0006000,ext4", + RootUpper::Ram => "nvx_overlay_upper=ramfs", + } +} + +#[test] +fn the_boot_contract_version_names_these_tokens() { + // Runtime identities record the boot contract version, and a build stops, rather than + // drives, a VM that a build of another version started. A change to these tokens, a new image + // format or upper, or another way for the guest to assemble the root from them changes the + // boot contract, and so its version, before the pins here change with it; see `contract`. + assert_eq!( + ( + contract::BOOT_CONTRACT_VERSION, + contract::MICROVM_ABI_VERSION + ), + (3, 2), + "a change to the boot tokens of a layered root or to the microVM ABI changes the boot \ + contract: increment BOOT_CONTRACT_VERSION, and update this test with it" + ); + for format in ImageFormat::ALL { + let image = format!("nvx_layer=distro,0xd0003000,{}", contracted_format(format)); + for identity in [None, Some(uuid(GPT_GUID))] { + let image = match identity { + Some(identity) => format!("{image}:{identity}"), + None => image.clone(), + }; + for upper in [RootUpper::Scratch, RootUpper::Ram] { + assert_eq!( + layout(RootImage { format, identity }, upper).tokens(), + [image.clone(), contracted_upper(upper).to_owned()] + ); + } + } + } +} diff --git a/nvx-rs/tests/fixtures/cli.json b/nvx-rs/tests/fixtures/cli.json index 2e969cb3b..67ea81642 100644 --- a/nvx-rs/tests/fixtures/cli.json +++ b/nvx-rs/tests/fixtures/cli.json @@ -148,13 +148,13 @@ {"name":"run: missing OpenVMM","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"remove":["openvmm/target/release/openvmm{exe}"],"status":1,"stdout":"","stderr":"error: OpenVMM release binary not found: {root}/openvmm/target/release/openvmm\n"}]}, {"name":"run: missing kernel","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"remove":["build/vmlinux"],"status":1,"stdout":"","stderr":"error: Linux direct kernel not found: {root}/build/vmlinux\n"}]}, {"name":"run: missing initramfs","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"remove":["build/initramfs.cpio.gz"],"status":1,"stdout":"","stderr":"error: initramfs not found: {root}/build/initramfs.cpio.gz\n"}]}, -{"name":"lifecycle: minimal","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": null,\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": null,\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"65534:65534\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"256M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/echo","--arg","hello","--arg","world"],"status":0,"stdout":"hello world\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/pwd","--cwd","/tmp"],"status":0,"stdout":"/tmp\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/sh","--arg=-c","--arg","echo out; echoerr err; exit 3","--outcome-report","{root}/reports/exec.json"],"check":["reports/exec.json"],"status":3,"stdout":"out\n","stderr":"err\n","files":{"reports/exec.json":{"text":"{\n \"operation_id\": \"{hex32}\",\n \"outcome\": {\n \"category\": \"exit\",\n \"operation\": \"exec\",\n \"status_code\": 3\n },\n \"schema_version\": 1\n}\n","mode":384}}},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/usr/bin/env","--environment","A=1","--environment","B=two"],"status":0,"stdout":"A=1\nB=two\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/usr/bin/printenv","--arg","PATH","--inherit-default-environment","--environment","A=1"],"status":0,"stdout":"/usr/sbin:/usr/bin:/sbin:/bin\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/usr/bin/env","--environment-file","{root}/env.json"],"write":{"env.json":"[\"X=1\", \"Y=two words\"]"},"status":0,"stdout":"X=1\nY=two words\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/usr/bin/env","--environment-file","{root}/empty.json"],"write":{"empty.json":"[]"},"status":0,"stdout":"","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/sh","--arg=-c","--arg","sleep 5000","--exec-timeout-ms","50","--outcome-report","{root}/reports/exec-timeout.json"],"check":["reports/exec-timeout.json"],"status":124,"stdout":"","stderr":"","files":{"reports/exec-timeout.json":{"text":"{\n \"operation_id\": \"{hex32}\",\n \"outcome\": {\n \"category\": \"timeout\",\n \"operation\": \"exec\",\n \"status_code\": 124\n },\n \"schema_version\": 1\n}\n","mode":384}}},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/sh","--arg=-c","--arg","signal 9"],"status":137,"stdout":"","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/missing"],"status":127,"stdout":"","stderr":"openvmm: /bin/missing: not found\n"},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/pwd","--cwd","/missing"],"status":1,"stdout":"","stderr":"error: managed guest rejected exec (status=2, category=cwd-failed)\n"},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/pwd","--cwd","relative"],"status":1,"stdout":"","stderr":"error: managed exec working directory must be an absolute path of at most 4096 bytes\n"},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/echo","--outcome-report","{root}/reports/exec.json"],"status":1,"stdout":"","stderr":"error: outcome report already exists: {root}/reports/exec.json\n"},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/echo","--outcome-report","{root}/missing/exec.json"],"status":1,"stdout":"","stderr":"error: outcome report parent is not a plain directory: {root}/missing\n"},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": null,\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": null,\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": null,\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"lifecycle: one share","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 2,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 2,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount\",\"/data,{root}/share,ro\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"256M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/pwd","--cwd","/data"],"status":0,"stdout":"/data\n","stderr":""},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 2,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 2,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 2,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"lifecycle: caller-owned share","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share,rw","--mount-owner","caller"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 3,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"caller\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 3,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"caller\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount\",\"/data,{root}/share,rw\",\"--mount-owner\",\"caller\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"256M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 3,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"caller\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 3,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"caller\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 3,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"caller\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"lifecycle: several shares","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share","--mount","/other,{root}/share2,rw"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 4,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/other\",\n \"host_path\": \"{root}/share2\",\n \"owner\": \"vmm\"\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 4,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/other\",\n \"host_path\": \"{root}/share2\",\n \"owner\": \"vmm\"\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount-aggregate\",\"/run/nvx/shares\",\"--mount-child\",\"0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}/share,ro\",\"--mount-child\",\"1-bf2faee2596026620b5cbc997c2d7d45,{root}/share2,rw\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"256M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox nvx_share=0-bd47413b5c03dfc6e4b5b8143fe205ea,/data,ro nvx_share=1-bf2faee2596026620b5cbc997c2d7d45,/other,rw\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/pwd","--cwd","/other"],"status":0,"stdout":"/other\n","stderr":""},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 4,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/other\",\n \"host_path\": \"{root}/share2\",\n \"owner\": \"vmm\"\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 4,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/other\",\n \"host_path\": \"{root}/share2\",\n \"owner\": \"vmm\"\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 4,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/other\",\n \"host_path\": \"{root}/share2\",\n \"owner\": \"vmm\"\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"lifecycle: share policies","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share,rw","--mount-deny","{root}/share/hidden","--mount-allow","{root}/share/hidden/shown","--mount-write","{root}/share/writable"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 5,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"rw\",\n \"allowed_paths\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied_paths\": [\n \"{root}/share/hidden\"\n ],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\",\n \"writable_paths\": [\n \"{root}/share/writable\"\n ]\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 5,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"rw\",\n \"allowed_paths\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied_paths\": [\n \"{root}/share/hidden\"\n ],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\",\n \"writable_paths\": [\n \"{root}/share/writable\"\n ]\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount\",\"/data,{root}/share,rw\",\"--mount-deny\",\"{root}/share/hidden\",\"--mount-allow\",\"{root}/share/hidden/shown\",\"--mount-write\",\"{root}/share/writable\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"256M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 5,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"rw\",\n \"allowed_paths\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied_paths\": [\n \"{root}/share/hidden\"\n ],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\",\n \"writable_paths\": [\n \"{root}/share/writable\"\n ]\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 5,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"rw\",\n \"allowed_paths\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied_paths\": [\n \"{root}/share/hidden\"\n ],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\",\n \"writable_paths\": [\n \"{root}/share/writable\"\n ]\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 5,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"rw\",\n \"allowed_paths\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied_paths\": [\n \"{root}/share/hidden\"\n ],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\",\n \"writable_paths\": [\n \"{root}/share/writable\"\n ]\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"lifecycle: file share","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/etc/single.txt,{root}/single.txt,ro"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 6,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"allowed_paths\": [],\n \"denied_paths\": [],\n \"guest_target\": \"/etc/single.txt\",\n \"host_path\": \"{root}/single.txt\",\n \"kind\": \"file\",\n \"owner\": \"vmm\",\n \"writable_paths\": []\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 6,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"allowed_paths\": [],\n \"denied_paths\": [],\n \"guest_target\": \"/etc/single.txt\",\n \"host_path\": \"{root}/single.txt\",\n \"kind\": \"file\",\n \"owner\": \"vmm\",\n \"writable_paths\": []\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount-aggregate\",\"/run/nvx/shares\",\"--mount-child\",\"0-a80a05e9cb129bc27b7ba103bf2f5ac0,{root}/single.txt,ro,file\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"256M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox nvx_share=0-a80a05e9cb129bc27b7ba103bf2f5ac0,/etc/single.txt,ro,file\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 6,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"allowed_paths\": [],\n \"denied_paths\": [],\n \"guest_target\": \"/etc/single.txt\",\n \"host_path\": \"{root}/single.txt\",\n \"kind\": \"file\",\n \"owner\": \"vmm\",\n \"writable_paths\": []\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 6,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"allowed_paths\": [],\n \"denied_paths\": [],\n \"guest_target\": \"/etc/single.txt\",\n \"host_path\": \"{root}/single.txt\",\n \"kind\": \"file\",\n \"owner\": \"vmm\",\n \"writable_paths\": []\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 6,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"allowed_paths\": [],\n \"denied_paths\": [],\n \"guest_target\": \"/etc/single.txt\",\n \"host_path\": \"{root}/single.txt\",\n \"kind\": \"file\",\n \"owner\": \"vmm\",\n \"writable_paths\": []\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"lifecycle: network and launch options","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--entrypoint","/bin/server","--arg=--serve","--hostname","worker","--workload-user","1000:1000","--memory-max","268435456","--pids-max","64","--memory-mib","384","--hypervisor","auto","--cmdline","quiet","--net","10.0.0.2/24","--network-profile","portable","--network-egress","allow","--network-ingress","deny","--network-egress-policy-file","{root}/policy.json","--host-loopback","allow","--host-loopback-forward","tcp:18080:8080","--host-loopback-forward","udp:19090:9090"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"192.0.2.128/25\"}]}"},"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"],"mode":448},"state/config.json":{"mode":384,"text":"{\n \"cmdline\": \"quiet\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"worker\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": 268435456,\n \"memory_mib\": 384,\n \"mount\": null,\n \"network\": {\n \"allow\": {\n \"name\": \"--network-egress-allow\",\n \"rules\": [\n {\n \"ports\": [\n {\n \"endPort\": null,\n \"port\": 443,\n \"protocol\": \"tcp\"\n }\n ],\n \"to\": [\n {\n \"cidr\": \"192.0.2.0/24\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"deny\": {\n \"name\": \"--network-egress-deny\",\n \"rules\": [\n {\n \"ports\": [],\n \"to\": [\n {\n \"cidr\": \"192.0.2.128/25\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"egress\": \"allow\",\n \"guestNetwork\": \"10.0.0.2/24\",\n \"hostLoopback\": \"allow\",\n \"hostLoopbackForwards\": [\n {\n \"guestPort\": 8080,\n \"hostPort\": 18080,\n \"protocol\": \"tcp\"\n },\n {\n \"guestPort\": 9090,\n \"hostPort\": 19090,\n \"protocol\": \"udp\"\n }\n ],\n \"ingress\": \"deny\",\n \"proxy\": null\n },\n \"pids_max\": 64,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 1000,\n \"workload_uid\": 1000\n}\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"mode":384,"text":"{\n \"cmdline\": \"quiet\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"worker\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": 268435456,\n \"memory_mib\": 384,\n \"mount\": null,\n \"network\": {\n \"allow\": {\n \"name\": \"--network-egress-allow\",\n \"rules\": [\n {\n \"ports\": [\n {\n \"endPort\": null,\n \"port\": 443,\n \"protocol\": \"tcp\"\n }\n ],\n \"to\": [\n {\n \"cidr\": \"192.0.2.0/24\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"deny\": {\n \"name\": \"--network-egress-deny\",\n \"rules\": [\n {\n \"ports\": [],\n \"to\": [\n {\n \"cidr\": \"192.0.2.128/25\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"egress\": \"allow\",\n \"guestNetwork\": \"10.0.0.2/24\",\n \"hostLoopback\": \"allow\",\n \"hostLoopbackForwards\": [\n {\n \"guestPort\": 8080,\n \"hostPort\": 18080,\n \"protocol\": \"tcp\"\n },\n {\n \"guestPort\": 9090,\n \"hostPort\": 19090,\n \"protocol\": \"udp\"\n }\n ],\n \"ingress\": \"deny\",\n \"proxy\": null\n },\n \"pids_max\": 64,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 1000,\n \"workload_uid\": 1000\n}\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"1000:1000\",\"--net\",\"10.0.0.2/24\",\"--network-profile\",\"portable\",\"--network-egress\",\"allow\",\"--network-ingress\",\"deny\",\"--host-loopback\",\"allow\",\"--network-egress-allow\",\"192.0.2.0/24:tcp:443\",\"--network-egress-deny\",\"192.0.2.128/25\",\"--host-loopback-forward\",\"tcp:18080:8080\",\"--host-loopback-forward\",\"udp:19090:9090\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"384M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"quiet nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=worker nvx_memory_max=268435456 nvx_pids_max=65\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"mode":384,"text":"{\n \"cmdline\": \"quiet\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"worker\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": 268435456,\n \"memory_mib\": 384,\n \"mount\": null,\n \"network\": {\n \"allow\": {\n \"name\": \"--network-egress-allow\",\n \"rules\": [\n {\n \"ports\": [\n {\n \"endPort\": null,\n \"port\": 443,\n \"protocol\": \"tcp\"\n }\n ],\n \"to\": [\n {\n \"cidr\": \"192.0.2.0/24\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"deny\": {\n \"name\": \"--network-egress-deny\",\n \"rules\": [\n {\n \"ports\": [],\n \"to\": [\n {\n \"cidr\": \"192.0.2.128/25\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"egress\": \"allow\",\n \"guestNetwork\": \"10.0.0.2/24\",\n \"hostLoopback\": \"allow\",\n \"hostLoopbackForwards\": [\n {\n \"guestPort\": 8080,\n \"hostPort\": 18080,\n \"protocol\": \"tcp\"\n },\n {\n \"guestPort\": 9090,\n \"hostPort\": 19090,\n \"protocol\": \"udp\"\n }\n ],\n \"ingress\": \"deny\",\n \"proxy\": null\n },\n \"pids_max\": 64,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 1000,\n \"workload_uid\": 1000\n}\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 1,\n \"deny_rule_count\": 1,\n \"host_loopback\": \"allow\",\n \"mode\": \"rules\",\n \"status\": \"applied\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"mode":384,"text":"{\n \"cmdline\": \"quiet\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"worker\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": 268435456,\n \"memory_mib\": 384,\n \"mount\": null,\n \"network\": {\n \"allow\": {\n \"name\": \"--network-egress-allow\",\n \"rules\": [\n {\n \"ports\": [\n {\n \"endPort\": null,\n \"port\": 443,\n \"protocol\": \"tcp\"\n }\n ],\n \"to\": [\n {\n \"cidr\": \"192.0.2.0/24\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"deny\": {\n \"name\": \"--network-egress-deny\",\n \"rules\": [\n {\n \"ports\": [],\n \"to\": [\n {\n \"cidr\": \"192.0.2.128/25\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"egress\": \"allow\",\n \"guestNetwork\": \"10.0.0.2/24\",\n \"hostLoopback\": \"allow\",\n \"hostLoopbackForwards\": [\n {\n \"guestPort\": 8080,\n \"hostPort\": 18080,\n \"protocol\": \"tcp\"\n },\n {\n \"guestPort\": 9090,\n \"hostPort\": 19090,\n \"protocol\": \"udp\"\n }\n ],\n \"ingress\": \"deny\",\n \"proxy\": null\n },\n \"pids_max\": 64,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 1000,\n \"workload_uid\": 1000\n}\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"mode":384,"text":"{\n \"cmdline\": \"quiet\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"worker\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": 268435456,\n \"memory_mib\": 384,\n \"mount\": null,\n \"network\": {\n \"allow\": {\n \"name\": \"--network-egress-allow\",\n \"rules\": [\n {\n \"ports\": [\n {\n \"endPort\": null,\n \"port\": 443,\n \"protocol\": \"tcp\"\n }\n ],\n \"to\": [\n {\n \"cidr\": \"192.0.2.0/24\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"deny\": {\n \"name\": \"--network-egress-deny\",\n \"rules\": [\n {\n \"ports\": [],\n \"to\": [\n {\n \"cidr\": \"192.0.2.128/25\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"egress\": \"allow\",\n \"guestNetwork\": \"10.0.0.2/24\",\n \"hostLoopback\": \"allow\",\n \"hostLoopbackForwards\": [\n {\n \"guestPort\": 8080,\n \"hostPort\": 18080,\n \"protocol\": \"tcp\"\n },\n {\n \"guestPort\": 9090,\n \"hostPort\": 19090,\n \"protocol\": \"udp\"\n }\n ],\n \"ingress\": \"deny\",\n \"proxy\": null\n },\n \"pids_max\": 64,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 1000,\n \"workload_uid\": 1000\n}\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 1,\n \"deny_rule_count\": 1,\n \"host_loopback\": \"allow\",\n \"mode\": \"rules\",\n \"status\": \"applied\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, +{"name":"lifecycle: minimal","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": null,\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": null,\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"65534:65534\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"256M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/echo","--arg","hello","--arg","world"],"status":0,"stdout":"hello world\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/pwd","--cwd","/tmp"],"status":0,"stdout":"/tmp\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/sh","--arg=-c","--arg","echo out; echoerr err; exit 3","--outcome-report","{root}/reports/exec.json"],"check":["reports/exec.json"],"status":3,"stdout":"out\n","stderr":"err\n","files":{"reports/exec.json":{"text":"{\n \"operation_id\": \"{hex32}\",\n \"outcome\": {\n \"category\": \"exit\",\n \"operation\": \"exec\",\n \"status_code\": 3\n },\n \"schema_version\": 1\n}\n","mode":384}}},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/usr/bin/env","--environment","A=1","--environment","B=two"],"status":0,"stdout":"A=1\nB=two\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/usr/bin/printenv","--arg","PATH","--inherit-default-environment","--environment","A=1"],"status":0,"stdout":"/usr/sbin:/usr/bin:/sbin:/bin\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/usr/bin/env","--environment-file","{root}/env.json"],"write":{"env.json":"[\"X=1\", \"Y=two words\"]"},"status":0,"stdout":"X=1\nY=two words\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/usr/bin/env","--environment-file","{root}/empty.json"],"write":{"empty.json":"[]"},"status":0,"stdout":"","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/sh","--arg=-c","--arg","sleep 5000","--exec-timeout-ms","50","--outcome-report","{root}/reports/exec-timeout.json"],"check":["reports/exec-timeout.json"],"status":124,"stdout":"","stderr":"","files":{"reports/exec-timeout.json":{"text":"{\n \"operation_id\": \"{hex32}\",\n \"outcome\": {\n \"category\": \"timeout\",\n \"operation\": \"exec\",\n \"status_code\": 124\n },\n \"schema_version\": 1\n}\n","mode":384}}},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/sh","--arg=-c","--arg","signal 9"],"status":137,"stdout":"","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/missing"],"status":127,"stdout":"","stderr":"openvmm: /bin/missing: not found\n"},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/pwd","--cwd","/missing"],"status":1,"stdout":"","stderr":"error: managed guest rejected exec (status=2, category=cwd-failed)\n"},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/pwd","--cwd","relative"],"status":1,"stdout":"","stderr":"error: managed exec working directory must be an absolute path of at most 4096 bytes\n"},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/echo","--outcome-report","{root}/reports/exec.json"],"status":1,"stdout":"","stderr":"error: outcome report already exists: {root}/reports/exec.json\n"},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/echo","--outcome-report","{root}/missing/exec.json"],"status":1,"stdout":"","stderr":"error: outcome report parent is not a plain directory: {root}/missing\n"},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": null,\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": null,\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": null,\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, +{"name":"lifecycle: one share","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 2,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 2,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount\",\"/data,{root}/share,ro\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"256M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/pwd","--cwd","/data"],"status":0,"stdout":"/data\n","stderr":""},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 2,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 2,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 2,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, +{"name":"lifecycle: caller-owned share","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share,rw","--mount-owner","caller"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 3,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"caller\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 3,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"caller\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount\",\"/data,{root}/share,rw\",\"--mount-owner\",\"caller\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"256M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 3,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"caller\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 3,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"caller\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 3,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"caller\"\n },\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, +{"name":"lifecycle: several shares","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share","--mount","/other,{root}/share2,rw"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 4,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/other\",\n \"host_path\": \"{root}/share2\",\n \"owner\": \"vmm\"\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 4,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/other\",\n \"host_path\": \"{root}/share2\",\n \"owner\": \"vmm\"\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount-aggregate\",\"/run/nvx/shares\",\"--mount-child\",\"0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}/share,ro\",\"--mount-child\",\"1-bf2faee2596026620b5cbc997c2d7d45,{root}/share2,rw\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"256M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox nvx_share=0-bd47413b5c03dfc6e4b5b8143fe205ea,/data,ro nvx_share=1-bf2faee2596026620b5cbc997c2d7d45,/other,rw\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","exec","--state-dir","{root}/state","--entrypoint","/bin/pwd","--cwd","/other"],"status":0,"stdout":"/other\n","stderr":""},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 4,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/other\",\n \"host_path\": \"{root}/share2\",\n \"owner\": \"vmm\"\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 4,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/other\",\n \"host_path\": \"{root}/share2\",\n \"owner\": \"vmm\"\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 4,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"denied_paths\": [],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\"\n },\n {\n \"access\": \"rw\",\n \"denied_paths\": [],\n \"guest_target\": \"/other\",\n \"host_path\": \"{root}/share2\",\n \"owner\": \"vmm\"\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, +{"name":"lifecycle: share policies","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share,rw","--mount-deny","{root}/share/hidden","--mount-allow","{root}/share/hidden/shown","--mount-write","{root}/share/writable"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 5,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"rw\",\n \"allowed_paths\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied_paths\": [\n \"{root}/share/hidden\"\n ],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\",\n \"writable_paths\": [\n \"{root}/share/writable\"\n ]\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 5,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"rw\",\n \"allowed_paths\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied_paths\": [\n \"{root}/share/hidden\"\n ],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\",\n \"writable_paths\": [\n \"{root}/share/writable\"\n ]\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount\",\"/data,{root}/share,rw\",\"--mount-deny\",\"{root}/share/hidden\",\"--mount-allow\",\"{root}/share/hidden/shown\",\"--mount-write\",\"{root}/share/writable\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"256M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 5,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"rw\",\n \"allowed_paths\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied_paths\": [\n \"{root}/share/hidden\"\n ],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\",\n \"writable_paths\": [\n \"{root}/share/writable\"\n ]\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 5,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"rw\",\n \"allowed_paths\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied_paths\": [\n \"{root}/share/hidden\"\n ],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\",\n \"writable_paths\": [\n \"{root}/share/writable\"\n ]\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 5,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"rw\",\n \"allowed_paths\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied_paths\": [\n \"{root}/share/hidden\"\n ],\n \"guest_target\": \"/data\",\n \"host_path\": \"{root}/share\",\n \"owner\": \"vmm\",\n \"writable_paths\": [\n \"{root}/share/writable\"\n ]\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, +{"name":"lifecycle: file share","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/etc/single.txt,{root}/single.txt,ro"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 6,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"allowed_paths\": [],\n \"denied_paths\": [],\n \"guest_target\": \"/etc/single.txt\",\n \"host_path\": \"{root}/single.txt\",\n \"kind\": \"file\",\n \"owner\": \"vmm\",\n \"writable_paths\": []\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 6,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"allowed_paths\": [],\n \"denied_paths\": [],\n \"guest_target\": \"/etc/single.txt\",\n \"host_path\": \"{root}/single.txt\",\n \"kind\": \"file\",\n \"owner\": \"vmm\",\n \"writable_paths\": []\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount-aggregate\",\"/run/nvx/shares\",\"--mount-child\",\"0-a80a05e9cb129bc27b7ba103bf2f5ac0,{root}/single.txt,ro,file\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"256M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox nvx_share=0-a80a05e9cb129bc27b7ba103bf2f5ac0,/etc/single.txt,ro,file\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 6,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"allowed_paths\": [],\n \"denied_paths\": [],\n \"guest_target\": \"/etc/single.txt\",\n \"host_path\": \"{root}/single.txt\",\n \"kind\": \"file\",\n \"owner\": \"vmm\",\n \"writable_paths\": []\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 6,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"allowed_paths\": [],\n \"denied_paths\": [],\n \"guest_target\": \"/etc/single.txt\",\n \"host_path\": \"{root}/single.txt\",\n \"kind\": \"file\",\n \"owner\": \"vmm\",\n \"writable_paths\": []\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 6,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mounts\": [\n {\n \"access\": \"ro\",\n \"allowed_paths\": [],\n \"denied_paths\": [],\n \"guest_target\": \"/etc/single.txt\",\n \"host_path\": \"{root}/single.txt\",\n \"kind\": \"file\",\n \"owner\": \"vmm\",\n \"writable_paths\": []\n }\n ],\n \"network\": null,\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n","mode":384},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, +{"name":"lifecycle: network and launch options","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--entrypoint","/bin/server","--arg=--serve","--hostname","worker","--workload-user","1000:1000","--memory-max","268435456","--pids-max","64","--memory-mib","384","--hypervisor","auto","--cmdline","quiet","--net","10.0.0.2/24","--network-profile","portable","--network-egress","allow","--network-ingress","deny","--network-egress-policy-file","{root}/policy.json","--host-loopback","allow","--host-loopback-forward","tcp:18080:8080","--host-loopback-forward","udp:19090:9090"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"192.0.2.128/25\"}]}"},"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"],"mode":448},"state/config.json":{"mode":384,"text":"{\n \"cmdline\": \"quiet\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"worker\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": 268435456,\n \"memory_mib\": 384,\n \"mount\": null,\n \"network\": {\n \"allow\": {\n \"name\": \"--network-egress-allow\",\n \"rules\": [\n {\n \"ports\": [\n {\n \"endPort\": null,\n \"port\": 443,\n \"protocol\": \"tcp\"\n }\n ],\n \"to\": [\n {\n \"cidr\": \"192.0.2.0/24\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"deny\": {\n \"name\": \"--network-egress-deny\",\n \"rules\": [\n {\n \"ports\": [],\n \"to\": [\n {\n \"cidr\": \"192.0.2.128/25\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"egress\": \"allow\",\n \"guestNetwork\": \"10.0.0.2/24\",\n \"hostLoopback\": \"allow\",\n \"hostLoopbackForwards\": [\n {\n \"guestPort\": 8080,\n \"hostPort\": 18080,\n \"protocol\": \"tcp\"\n },\n {\n \"guestPort\": 9090,\n \"hostPort\": 19090,\n \"protocol\": \"udp\"\n }\n ],\n \"ingress\": \"deny\",\n \"proxy\": null\n },\n \"pids_max\": 64,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 1000,\n \"workload_uid\": 1000\n}\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"mode":384,"text":"{\n \"cmdline\": \"quiet\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"worker\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": 268435456,\n \"memory_mib\": 384,\n \"mount\": null,\n \"network\": {\n \"allow\": {\n \"name\": \"--network-egress-allow\",\n \"rules\": [\n {\n \"ports\": [\n {\n \"endPort\": null,\n \"port\": 443,\n \"protocol\": \"tcp\"\n }\n ],\n \"to\": [\n {\n \"cidr\": \"192.0.2.0/24\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"deny\": {\n \"name\": \"--network-egress-deny\",\n \"rules\": [\n {\n \"ports\": [],\n \"to\": [\n {\n \"cidr\": \"192.0.2.128/25\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"egress\": \"allow\",\n \"guestNetwork\": \"10.0.0.2/24\",\n \"hostLoopback\": \"allow\",\n \"hostLoopbackForwards\": [\n {\n \"guestPort\": 8080,\n \"hostPort\": 18080,\n \"protocol\": \"tcp\"\n },\n {\n \"guestPort\": 9090,\n \"hostPort\": 19090,\n \"protocol\": \"udp\"\n }\n ],\n \"ingress\": \"deny\",\n \"proxy\": null\n },\n \"pids_max\": 64,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 1000,\n \"workload_uid\": 1000\n}\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"1000:1000\",\"--net\",\"10.0.0.2/24\",\"--network-profile\",\"portable\",\"--network-egress\",\"allow\",\"--network-ingress\",\"deny\",\"--host-loopback\",\"allow\",\"--network-egress-allow\",\"192.0.2.0/24:tcp:443\",\"--network-egress-deny\",\"192.0.2.128/25\",\"--host-loopback-forward\",\"tcp:18080:8080\",\"--host-loopback-forward\",\"udp:19090:9090\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"384M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"quiet nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=worker nvx_memory_max=268435456 nvx_pids_max=65\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"mode":384,"text":"{\n \"cmdline\": \"quiet\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"worker\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": 268435456,\n \"memory_mib\": 384,\n \"mount\": null,\n \"network\": {\n \"allow\": {\n \"name\": \"--network-egress-allow\",\n \"rules\": [\n {\n \"ports\": [\n {\n \"endPort\": null,\n \"port\": 443,\n \"protocol\": \"tcp\"\n }\n ],\n \"to\": [\n {\n \"cidr\": \"192.0.2.0/24\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"deny\": {\n \"name\": \"--network-egress-deny\",\n \"rules\": [\n {\n \"ports\": [],\n \"to\": [\n {\n \"cidr\": \"192.0.2.128/25\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"egress\": \"allow\",\n \"guestNetwork\": \"10.0.0.2/24\",\n \"hostLoopback\": \"allow\",\n \"hostLoopbackForwards\": [\n {\n \"guestPort\": 8080,\n \"hostPort\": 18080,\n \"protocol\": \"tcp\"\n },\n {\n \"guestPort\": 9090,\n \"hostPort\": 19090,\n \"protocol\": \"udp\"\n }\n ],\n \"ingress\": \"deny\",\n \"proxy\": null\n },\n \"pids_max\": 64,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 1000,\n \"workload_uid\": 1000\n}\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 1,\n \"deny_rule_count\": 1,\n \"host_loopback\": \"allow\",\n \"mode\": \"rules\",\n \"status\": \"applied\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","control.sock","openvmm.log","runtime.json","sandbox.lock"],"mode":448},"state/config.json":{"mode":384,"text":"{\n \"cmdline\": \"quiet\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"worker\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": 268435456,\n \"memory_mib\": 384,\n \"mount\": null,\n \"network\": {\n \"allow\": {\n \"name\": \"--network-egress-allow\",\n \"rules\": [\n {\n \"ports\": [\n {\n \"endPort\": null,\n \"port\": 443,\n \"protocol\": \"tcp\"\n }\n ],\n \"to\": [\n {\n \"cidr\": \"192.0.2.0/24\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"deny\": {\n \"name\": \"--network-egress-deny\",\n \"rules\": [\n {\n \"ports\": [],\n \"to\": [\n {\n \"cidr\": \"192.0.2.128/25\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"egress\": \"allow\",\n \"guestNetwork\": \"10.0.0.2/24\",\n \"hostLoopback\": \"allow\",\n \"hostLoopbackForwards\": [\n {\n \"guestPort\": 8080,\n \"hostPort\": 18080,\n \"protocol\": \"tcp\"\n },\n {\n \"guestPort\": 9090,\n \"hostPort\": 19090,\n \"protocol\": \"udp\"\n }\n ],\n \"ingress\": \"deny\",\n \"proxy\": null\n },\n \"pids_max\": 64,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 1000,\n \"workload_uid\": 1000\n}\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"{root}/state/control.sock\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n","mode":384},"state/control.capability":{"size":32,"mode":384},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"],"mode":448},"state/config.json":{"mode":384,"text":"{\n \"cmdline\": \"quiet\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"worker\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": 268435456,\n \"memory_mib\": 384,\n \"mount\": null,\n \"network\": {\n \"allow\": {\n \"name\": \"--network-egress-allow\",\n \"rules\": [\n {\n \"ports\": [\n {\n \"endPort\": null,\n \"port\": 443,\n \"protocol\": \"tcp\"\n }\n ],\n \"to\": [\n {\n \"cidr\": \"192.0.2.0/24\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"deny\": {\n \"name\": \"--network-egress-deny\",\n \"rules\": [\n {\n \"ports\": [],\n \"to\": [\n {\n \"cidr\": \"192.0.2.128/25\",\n \"except\": []\n }\n ]\n }\n ]\n },\n \"egress\": \"allow\",\n \"guestNetwork\": \"10.0.0.2/24\",\n \"hostLoopback\": \"allow\",\n \"hostLoopbackForwards\": [\n {\n \"guestPort\": 8080,\n \"hostPort\": 18080,\n \"protocol\": \"tcp\"\n },\n {\n \"guestPort\": 9090,\n \"hostPort\": 19090,\n \"protocol\": \"udp\"\n }\n ],\n \"ingress\": \"deny\",\n \"proxy\": null\n },\n \"pids_max\": 64,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 1000,\n \"workload_uid\": 1000\n}\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 1,\n \"deny_rule_count\": 1,\n \"host_loopback\": \"allow\",\n \"mode\": \"rules\",\n \"status\": \"applied\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, {"name":"lifecycle: proxy-only network","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--net","10.0.0.2/24","--network-profile","portable","--network-egress","deny","--host-loopback","deny","--network-proxy","10.0.0.1:3128"],"check":["state/config.json"],"status":0,"stdout":"","stderr":"","files":{"state/config.json":{"mode":384,"text":"{\n \"cmdline\": \"\",\n \"distro_binding\": {\n \"format\": \"erofs\",\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\n \"image\": {\n \"changed\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 7,\n \"modified\": {\n \"nanoseconds\": {int},\n \"seconds\": {int}\n },\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"manifest\": null,\n \"policy\": {\n \"result\": \"accepted\",\n \"revision\": 1\n },\n \"version\": 1\n },\n \"format\": 1,\n \"hostname\": \"nvx-sandbox\",\n \"hypervisor\": \"kvm\",\n \"layers\": [\n {\n \"path\": \"{root}/distro.erofs\",\n \"role\": \"distro\",\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\n }\n ],\n \"memory_max\": null,\n \"memory_mib\": 256,\n \"mount\": null,\n \"network\": {\n \"allow\": {\n \"name\": \"--network-egress-allow\",\n \"rules\": []\n },\n \"deny\": {\n \"name\": \"--network-egress-deny\",\n \"rules\": []\n },\n \"egress\": \"deny\",\n \"guestNetwork\": \"10.0.0.2/24\",\n \"hostLoopback\": \"deny\",\n \"hostLoopbackForwards\": [],\n \"ingress\": \"deny\",\n \"proxy\": {\n \"port\": 3128,\n \"scheme\": null\n }\n },\n \"pids_max\": null,\n \"scratch\": \"{root}/scratch.ext4\",\n \"scratch_binding\": {\n \"device\": {int},\n \"fileId\": \"{hex32}\",\n \"kind\": \"regular\",\n \"length\": 8,\n \"scheme\": \"linux\",\n \"version\": 1\n },\n \"workload_gid\": 65534,\n \"workload_uid\": 65534\n}\n"}}},{"argv":["sandbox","start","--state-dir","{root}/state"],"check":["build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:/proc/self/fd/{int},ro\",\"--microvm-sandbox-block\",\"scratch:file:/proc/self/fd/{int}\",\"--microvm-workload-identity\",\"65534:65534\",\"--net\",\"10.0.0.2/24\",\"--network-profile\",\"portable\",\"--network-egress\",\"deny\",\"--network-ingress\",\"deny\",\"--host-loopback\",\"deny\",\"--network-proxy\",\"10.0.0.1:3128\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"kvm\",\"--memory\",\"256M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}/state"],"status":0,"stdout":"","stderr":""},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}]}, {"name":"state: operations without a sandbox","steps":[{"argv":["sandbox","start","--state-dir","{root}/state"],"status":1,"stdout":"","stderr":"error: sandbox state path is not a plain directory: {root}/state\n"},{"argv":["sandbox","exec","--state-dir","{root}/state"],"status":1,"stdout":"","stderr":"error: sandbox state path is not a plain directory: {root}/state\n"},{"argv":["sandbox","stop","--state-dir","{root}/state"],"status":1,"stdout":"","stderr":"error: sandbox state path is not a plain directory: {root}/state\n"},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"status":1,"stdout":"","stderr":"error: sandbox state path is not a plain directory: {root}/state\n"}]}, {"name":"state: refusals of a running sandbox","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"status":0,"stdout":"","stderr":""},{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"status":1,"stdout":"","stderr":"error: sandbox is already provisioned\n"},{"argv":["sandbox","start","--state-dir","{root}/state"],"status":0,"stdout":"","stderr":""},{"argv":["sandbox","start","--state-dir","{root}/state"],"status":1,"stdout":"","stderr":"error: sandbox is already running or has stale runtime state\n"},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"status":1,"stdout":"","stderr":"error: sandbox must be stopped before deprovision\n"},{"argv":["sandbox","stop","--state-dir","{root}/state"],"status":0,"stdout":"","stderr":""},{"argv":["sandbox","stop","--state-dir","{root}/state"],"status":1,"stdout":"","stderr":"error: sandbox is not running\n"},{"argv":["sandbox","exec","--state-dir","{root}/state"],"status":1,"stdout":"","stderr":"error: sandbox is not running\n"},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, @@ -463,12 +463,12 @@ {"name":"run: missing OpenVMM","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"remove":["openvmm/target/release/openvmm{exe}"],"status":1,"stdout":"","stderr":"error: OpenVMM release binary not found: {root}\\openvmm\\target\\release\\openvmm.exe\r\n"}]}, {"name":"run: missing kernel","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"remove":["build/vmlinux"],"status":1,"stdout":"","stderr":"error: Linux direct kernel not found: {root}\\build\\vmlinux\r\n"}]}, {"name":"run: missing initramfs","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"remove":["build/initramfs.cpio.gz"],"status":1,"stdout":"","stderr":"error: initramfs not found: {root}\\build\\initramfs.cpio.gz\r\n"}]}, -{"name":"lifecycle: minimal","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": null,\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": null,\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:\\\\\\\\?\\\\{root_json}\\\\distro.erofs,ro\",\"--microvm-sandbox-block\",\"scratch:file:\\\\\\\\?\\\\{root_json}\\\\scratch.ext4\",\"--microvm-workload-identity\",\"65534:65534\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"whp\",\"--memory\",\"256M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"}}},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/echo","--arg","hello","--arg","world"],"status":0,"stdout":"hello world\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/pwd","--cwd","/tmp"],"status":0,"stdout":"/tmp\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/sh","--arg=-c","--arg","echo out; echoerr err; exit 3","--outcome-report","{root}\\reports\\exec.json"],"check":["reports/exec.json"],"status":3,"stdout":"out\n","stderr":"err\n","files":{"reports/exec.json":{"text":"{\n \"operation_id\": \"{hex32}\",\n \"outcome\": {\n \"category\": \"exit\",\n \"operation\": \"exec\",\n \"status_code\": 3\n },\n \"schema_version\": 1\n}\n"}}},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/usr/bin/env","--environment","A=1","--environment","B=two"],"status":0,"stdout":"A=1\nB=two\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/usr/bin/printenv","--arg","PATH","--inherit-default-environment","--environment","A=1"],"status":0,"stdout":"/usr/sbin:/usr/bin:/sbin:/bin\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/usr/bin/env","--environment-file","{root}\\env.json"],"write":{"env.json":"[\"X=1\", \"Y=two words\"]"},"status":0,"stdout":"X=1\nY=two words\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/usr/bin/env","--environment-file","{root}\\empty.json"],"write":{"empty.json":"[]"},"status":0,"stdout":"","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/sh","--arg=-c","--arg","sleep 5000","--exec-timeout-ms","50","--outcome-report","{root}\\reports\\exec-timeout.json"],"check":["reports/exec-timeout.json"],"status":124,"stdout":"","stderr":"","files":{"reports/exec-timeout.json":{"text":"{\n \"operation_id\": \"{hex32}\",\n \"outcome\": {\n \"category\": \"timeout\",\n \"operation\": \"exec\",\n \"status_code\": 124\n },\n \"schema_version\": 1\n}\n"}}},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/sh","--arg=-c","--arg","signal 9"],"status":137,"stdout":"","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/missing"],"status":127,"stdout":"","stderr":"openvmm: /bin/missing: not found\n"},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/pwd","--cwd","/missing"],"status":1,"stdout":"","stderr":"error: managed guest rejected exec (status=2, category=cwd-failed)\r\n"},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/pwd","--cwd","relative"],"status":1,"stdout":"","stderr":"error: managed exec working directory must be an absolute path of at most 4096 bytes\r\n"},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/echo","--outcome-report","{root}\\reports\\exec.json"],"status":1,"stdout":"","stderr":"error: outcome report already exists: {root}\\reports\\exec.json\r\n"},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/echo","--outcome-report","{root}\\missing\\exec.json"],"status":1,"stdout":"","stderr":"error: outcome report parent is not a plain directory: {root}\\missing\r\n"},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": null,\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": null,\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": null,\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"lifecycle: one share","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/data,{root}\\share"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 2,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 2,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:\\\\\\\\?\\\\{root_json}\\\\distro.erofs,ro\",\"--microvm-sandbox-block\",\"scratch:file:\\\\\\\\?\\\\{root_json}\\\\scratch.ext4\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount\",\"/data,{root_json}\\\\share,ro\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"whp\",\"--memory\",\"256M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"}}},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/pwd","--cwd","/data"],"status":0,"stdout":"/data\n","stderr":""},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 2,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 2,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 2,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"lifecycle: several shares","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/data,{root}\\share","--mount","/other,{root}\\share2,rw"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 4,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n {\r\n \"access\": \"rw\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/other\",\r\n \"host_path\": \"{root_json}\\\\share2\",\r\n \"owner\": \"vmm\"\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 4,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n {\r\n \"access\": \"rw\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/other\",\r\n \"host_path\": \"{root_json}\\\\share2\",\r\n \"owner\": \"vmm\"\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:\\\\\\\\?\\\\{root_json}\\\\distro.erofs,ro\",\"--microvm-sandbox-block\",\"scratch:file:\\\\\\\\?\\\\{root_json}\\\\scratch.ext4\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount-aggregate\",\"/run/nvx/shares\",\"--mount-child\",\"0-bd47413b5c03dfc6e4b5b8143fe205ea,{root_json}\\\\share,ro\",\"--mount-child\",\"1-bf2faee2596026620b5cbc997c2d7d45,{root_json}\\\\share2,rw\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"whp\",\"--memory\",\"256M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox nvx_share=0-bd47413b5c03dfc6e4b5b8143fe205ea,/data,ro nvx_share=1-bf2faee2596026620b5cbc997c2d7d45,/other,rw\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"}}},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/pwd","--cwd","/other"],"status":0,"stdout":"/other\n","stderr":""},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 4,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n {\r\n \"access\": \"rw\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/other\",\r\n \"host_path\": \"{root_json}\\\\share2\",\r\n \"owner\": \"vmm\"\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 4,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n {\r\n \"access\": \"rw\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/other\",\r\n \"host_path\": \"{root_json}\\\\share2\",\r\n \"owner\": \"vmm\"\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 4,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n {\r\n \"access\": \"rw\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/other\",\r\n \"host_path\": \"{root_json}\\\\share2\",\r\n \"owner\": \"vmm\"\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"lifecycle: share policies","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/data,{root}\\share,rw","--mount-deny","{root}\\share\\hidden","--mount-allow","{root}\\share\\hidden\\shown","--mount-write","{root}\\share\\writable"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 5,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"rw\",\r\n \"allowed_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 5,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"rw\",\r\n \"allowed_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:\\\\\\\\?\\\\{root_json}\\\\distro.erofs,ro\",\"--microvm-sandbox-block\",\"scratch:file:\\\\\\\\?\\\\{root_json}\\\\scratch.ext4\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount\",\"/data,{root_json}\\\\share,rw\",\"--mount-deny\",\"{root_json}\\\\share\\\\hidden\",\"--mount-allow\",\"{root_json}\\\\share\\\\hidden\\\\shown\",\"--mount-write\",\"{root_json}\\\\share\\\\writable\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"whp\",\"--memory\",\"256M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 5,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"rw\",\r\n \"allowed_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 5,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"rw\",\r\n \"allowed_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 5,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"rw\",\r\n \"allowed_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"lifecycle: file share","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/etc/single.txt,{root}\\single.txt,ro"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 6,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"allowed_paths\": [],\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/etc/single.txt\",\r\n \"host_path\": \"{root_json}\\\\single.txt\",\r\n \"kind\": \"file\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": []\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 6,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"allowed_paths\": [],\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/etc/single.txt\",\r\n \"host_path\": \"{root_json}\\\\single.txt\",\r\n \"kind\": \"file\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": []\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:\\\\\\\\?\\\\{root_json}\\\\distro.erofs,ro\",\"--microvm-sandbox-block\",\"scratch:file:\\\\\\\\?\\\\{root_json}\\\\scratch.ext4\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount-aggregate\",\"/run/nvx/shares\",\"--mount-child\",\"0-a80a05e9cb129bc27b7ba103bf2f5ac0,{root_json}\\\\single.txt,ro,file\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"whp\",\"--memory\",\"256M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox nvx_share=0-a80a05e9cb129bc27b7ba103bf2f5ac0,/etc/single.txt,ro,file\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 6,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"allowed_paths\": [],\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/etc/single.txt\",\r\n \"host_path\": \"{root_json}\\\\single.txt\",\r\n \"kind\": \"file\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": []\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 6,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"allowed_paths\": [],\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/etc/single.txt\",\r\n \"host_path\": \"{root_json}\\\\single.txt\",\r\n \"kind\": \"file\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": []\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 6,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"allowed_paths\": [],\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/etc/single.txt\",\r\n \"host_path\": \"{root_json}\\\\single.txt\",\r\n \"kind\": \"file\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": []\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"lifecycle: network and launch options","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--entrypoint","/bin/server","--arg=--serve","--hostname","worker","--workload-user","1000:1000","--memory-max","268435456","--pids-max","64","--memory-mib","384","--hypervisor","auto","--cmdline","quiet","--net","10.0.0.2/24","--network-profile","portable","--network-egress","allow","--network-ingress","deny","--network-egress-policy-file","{root}\\policy.json","--host-loopback","allow","--host-loopback-forward","tcp:18080:8080","--host-loopback-forward","udp:19090:9090"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"192.0.2.128/25\"}]}"},"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"quiet\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"worker\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": 268435456,\r\n \"memory_mib\": 384,\r\n \"mount\": null,\r\n \"network\": {\r\n \"allow\": {\r\n \"name\": \"--network-egress-allow\",\r\n \"rules\": [\r\n {\r\n \"ports\": [\r\n {\r\n \"endPort\": null,\r\n \"port\": 443,\r\n \"protocol\": \"tcp\"\r\n }\r\n ],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.0/24\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"deny\": {\r\n \"name\": \"--network-egress-deny\",\r\n \"rules\": [\r\n {\r\n \"ports\": [],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.128/25\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"egress\": \"allow\",\r\n \"guestNetwork\": \"10.0.0.2/24\",\r\n \"hostLoopback\": \"allow\",\r\n \"hostLoopbackForwards\": [\r\n {\r\n \"guestPort\": 8080,\r\n \"hostPort\": 18080,\r\n \"protocol\": \"tcp\"\r\n },\r\n {\r\n \"guestPort\": 9090,\r\n \"hostPort\": 19090,\r\n \"protocol\": \"udp\"\r\n }\r\n ],\r\n \"ingress\": \"deny\",\r\n \"proxy\": null\r\n },\r\n \"pids_max\": 64,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 1000,\r\n \"workload_uid\": 1000\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"quiet\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"worker\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": 268435456,\r\n \"memory_mib\": 384,\r\n \"mount\": null,\r\n \"network\": {\r\n \"allow\": {\r\n \"name\": \"--network-egress-allow\",\r\n \"rules\": [\r\n {\r\n \"ports\": [\r\n {\r\n \"endPort\": null,\r\n \"port\": 443,\r\n \"protocol\": \"tcp\"\r\n }\r\n ],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.0/24\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"deny\": {\r\n \"name\": \"--network-egress-deny\",\r\n \"rules\": [\r\n {\r\n \"ports\": [],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.128/25\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"egress\": \"allow\",\r\n \"guestNetwork\": \"10.0.0.2/24\",\r\n \"hostLoopback\": \"allow\",\r\n \"hostLoopbackForwards\": [\r\n {\r\n \"guestPort\": 8080,\r\n \"hostPort\": 18080,\r\n \"protocol\": \"tcp\"\r\n },\r\n {\r\n \"guestPort\": 9090,\r\n \"hostPort\": 19090,\r\n \"protocol\": \"udp\"\r\n }\r\n ],\r\n \"ingress\": \"deny\",\r\n \"proxy\": null\r\n },\r\n \"pids_max\": 64,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 1000,\r\n \"workload_uid\": 1000\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:\\\\\\\\?\\\\{root_json}\\\\distro.erofs,ro\",\"--microvm-sandbox-block\",\"scratch:file:\\\\\\\\?\\\\{root_json}\\\\scratch.ext4\",\"--microvm-workload-identity\",\"1000:1000\",\"--net\",\"10.0.0.2/24\",\"--network-profile\",\"portable\",\"--network-egress\",\"allow\",\"--network-ingress\",\"deny\",\"--host-loopback\",\"allow\",\"--network-egress-allow\",\"192.0.2.0/24:tcp:443\",\"--network-egress-deny\",\"192.0.2.128/25\",\"--host-loopback-forward\",\"tcp:18080:8080\",\"--host-loopback-forward\",\"udp:19090:9090\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"whp\",\"--memory\",\"384M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--cmdline\",\"quiet nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=worker nvx_memory_max=268435456 nvx_pids_max=65\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"quiet\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"worker\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": 268435456,\r\n \"memory_mib\": 384,\r\n \"mount\": null,\r\n \"network\": {\r\n \"allow\": {\r\n \"name\": \"--network-egress-allow\",\r\n \"rules\": [\r\n {\r\n \"ports\": [\r\n {\r\n \"endPort\": null,\r\n \"port\": 443,\r\n \"protocol\": \"tcp\"\r\n }\r\n ],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.0/24\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"deny\": {\r\n \"name\": \"--network-egress-deny\",\r\n \"rules\": [\r\n {\r\n \"ports\": [],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.128/25\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"egress\": \"allow\",\r\n \"guestNetwork\": \"10.0.0.2/24\",\r\n \"hostLoopback\": \"allow\",\r\n \"hostLoopbackForwards\": [\r\n {\r\n \"guestPort\": 8080,\r\n \"hostPort\": 18080,\r\n \"protocol\": \"tcp\"\r\n },\r\n {\r\n \"guestPort\": 9090,\r\n \"hostPort\": 19090,\r\n \"protocol\": \"udp\"\r\n }\r\n ],\r\n \"ingress\": \"deny\",\r\n \"proxy\": null\r\n },\r\n \"pids_max\": 64,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 1000,\r\n \"workload_uid\": 1000\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 1,\n \"deny_rule_count\": 1,\n \"host_loopback\": \"allow\",\n \"mode\": \"rules\",\n \"status\": \"applied\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"quiet\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"worker\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": 268435456,\r\n \"memory_mib\": 384,\r\n \"mount\": null,\r\n \"network\": {\r\n \"allow\": {\r\n \"name\": \"--network-egress-allow\",\r\n \"rules\": [\r\n {\r\n \"ports\": [\r\n {\r\n \"endPort\": null,\r\n \"port\": 443,\r\n \"protocol\": \"tcp\"\r\n }\r\n ],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.0/24\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"deny\": {\r\n \"name\": \"--network-egress-deny\",\r\n \"rules\": [\r\n {\r\n \"ports\": [],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.128/25\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"egress\": \"allow\",\r\n \"guestNetwork\": \"10.0.0.2/24\",\r\n \"hostLoopback\": \"allow\",\r\n \"hostLoopbackForwards\": [\r\n {\r\n \"guestPort\": 8080,\r\n \"hostPort\": 18080,\r\n \"protocol\": \"tcp\"\r\n },\r\n {\r\n \"guestPort\": 9090,\r\n \"hostPort\": 19090,\r\n \"protocol\": \"udp\"\r\n }\r\n ],\r\n \"ingress\": \"deny\",\r\n \"proxy\": null\r\n },\r\n \"pids_max\": 64,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 1000,\r\n \"workload_uid\": 1000\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 2,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"quiet\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"worker\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": 268435456,\r\n \"memory_mib\": 384,\r\n \"mount\": null,\r\n \"network\": {\r\n \"allow\": {\r\n \"name\": \"--network-egress-allow\",\r\n \"rules\": [\r\n {\r\n \"ports\": [\r\n {\r\n \"endPort\": null,\r\n \"port\": 443,\r\n \"protocol\": \"tcp\"\r\n }\r\n ],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.0/24\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"deny\": {\r\n \"name\": \"--network-egress-deny\",\r\n \"rules\": [\r\n {\r\n \"ports\": [],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.128/25\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"egress\": \"allow\",\r\n \"guestNetwork\": \"10.0.0.2/24\",\r\n \"hostLoopback\": \"allow\",\r\n \"hostLoopbackForwards\": [\r\n {\r\n \"guestPort\": 8080,\r\n \"hostPort\": 18080,\r\n \"protocol\": \"tcp\"\r\n },\r\n {\r\n \"guestPort\": 9090,\r\n \"hostPort\": 19090,\r\n \"protocol\": \"udp\"\r\n }\r\n ],\r\n \"ingress\": \"deny\",\r\n \"proxy\": null\r\n },\r\n \"pids_max\": 64,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 1000,\r\n \"workload_uid\": 1000\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 1,\n \"deny_rule_count\": 1,\n \"host_loopback\": \"allow\",\n \"mode\": \"rules\",\n \"status\": \"applied\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, +{"name":"lifecycle: minimal","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": null,\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": null,\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:\\\\\\\\?\\\\{root_json}\\\\distro.erofs,ro\",\"--microvm-sandbox-block\",\"scratch:file:\\\\\\\\?\\\\{root_json}\\\\scratch.ext4\",\"--microvm-workload-identity\",\"65534:65534\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"whp\",\"--memory\",\"256M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"}}},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/echo","--arg","hello","--arg","world"],"status":0,"stdout":"hello world\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/pwd","--cwd","/tmp"],"status":0,"stdout":"/tmp\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/sh","--arg=-c","--arg","echo out; echoerr err; exit 3","--outcome-report","{root}\\reports\\exec.json"],"check":["reports/exec.json"],"status":3,"stdout":"out\n","stderr":"err\n","files":{"reports/exec.json":{"text":"{\n \"operation_id\": \"{hex32}\",\n \"outcome\": {\n \"category\": \"exit\",\n \"operation\": \"exec\",\n \"status_code\": 3\n },\n \"schema_version\": 1\n}\n"}}},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/usr/bin/env","--environment","A=1","--environment","B=two"],"status":0,"stdout":"A=1\nB=two\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/usr/bin/printenv","--arg","PATH","--inherit-default-environment","--environment","A=1"],"status":0,"stdout":"/usr/sbin:/usr/bin:/sbin:/bin\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/usr/bin/env","--environment-file","{root}\\env.json"],"write":{"env.json":"[\"X=1\", \"Y=two words\"]"},"status":0,"stdout":"X=1\nY=two words\n","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/usr/bin/env","--environment-file","{root}\\empty.json"],"write":{"empty.json":"[]"},"status":0,"stdout":"","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/sh","--arg=-c","--arg","sleep 5000","--exec-timeout-ms","50","--outcome-report","{root}\\reports\\exec-timeout.json"],"check":["reports/exec-timeout.json"],"status":124,"stdout":"","stderr":"","files":{"reports/exec-timeout.json":{"text":"{\n \"operation_id\": \"{hex32}\",\n \"outcome\": {\n \"category\": \"timeout\",\n \"operation\": \"exec\",\n \"status_code\": 124\n },\n \"schema_version\": 1\n}\n"}}},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/sh","--arg=-c","--arg","signal 9"],"status":137,"stdout":"","stderr":""},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/missing"],"status":127,"stdout":"","stderr":"openvmm: /bin/missing: not found\n"},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/pwd","--cwd","/missing"],"status":1,"stdout":"","stderr":"error: managed guest rejected exec (status=2, category=cwd-failed)\r\n"},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/pwd","--cwd","relative"],"status":1,"stdout":"","stderr":"error: managed exec working directory must be an absolute path of at most 4096 bytes\r\n"},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/echo","--outcome-report","{root}\\reports\\exec.json"],"status":1,"stdout":"","stderr":"error: outcome report already exists: {root}\\reports\\exec.json\r\n"},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/echo","--outcome-report","{root}\\missing\\exec.json"],"status":1,"stdout":"","stderr":"error: outcome report parent is not a plain directory: {root}\\missing\r\n"},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": null,\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": null,\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": null,\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, +{"name":"lifecycle: one share","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/data,{root}\\share"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 2,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 2,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:\\\\\\\\?\\\\{root_json}\\\\distro.erofs,ro\",\"--microvm-sandbox-block\",\"scratch:file:\\\\\\\\?\\\\{root_json}\\\\scratch.ext4\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount\",\"/data,{root_json}\\\\share,ro\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"whp\",\"--memory\",\"256M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"}}},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/pwd","--cwd","/data"],"status":0,"stdout":"/data\n","stderr":""},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 2,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 2,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 2,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, +{"name":"lifecycle: several shares","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/data,{root}\\share","--mount","/other,{root}\\share2,rw"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 4,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n {\r\n \"access\": \"rw\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/other\",\r\n \"host_path\": \"{root_json}\\\\share2\",\r\n \"owner\": \"vmm\"\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 4,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n {\r\n \"access\": \"rw\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/other\",\r\n \"host_path\": \"{root_json}\\\\share2\",\r\n \"owner\": \"vmm\"\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:\\\\\\\\?\\\\{root_json}\\\\distro.erofs,ro\",\"--microvm-sandbox-block\",\"scratch:file:\\\\\\\\?\\\\{root_json}\\\\scratch.ext4\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount-aggregate\",\"/run/nvx/shares\",\"--mount-child\",\"0-bd47413b5c03dfc6e4b5b8143fe205ea,{root_json}\\\\share,ro\",\"--mount-child\",\"1-bf2faee2596026620b5cbc997c2d7d45,{root_json}\\\\share2,rw\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"whp\",\"--memory\",\"256M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox nvx_share=0-bd47413b5c03dfc6e4b5b8143fe205ea,/data,ro nvx_share=1-bf2faee2596026620b5cbc997c2d7d45,/other,rw\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"}}},{"argv":["sandbox","exec","--state-dir","{root}\\state","--entrypoint","/bin/pwd","--cwd","/other"],"status":0,"stdout":"/other\n","stderr":""},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 4,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n {\r\n \"access\": \"rw\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/other\",\r\n \"host_path\": \"{root_json}\\\\share2\",\r\n \"owner\": \"vmm\"\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 4,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n {\r\n \"access\": \"rw\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/other\",\r\n \"host_path\": \"{root_json}\\\\share2\",\r\n \"owner\": \"vmm\"\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 4,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\"\r\n },\r\n {\r\n \"access\": \"rw\",\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/other\",\r\n \"host_path\": \"{root_json}\\\\share2\",\r\n \"owner\": \"vmm\"\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, +{"name":"lifecycle: share policies","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/data,{root}\\share,rw","--mount-deny","{root}\\share\\hidden","--mount-allow","{root}\\share\\hidden\\shown","--mount-write","{root}\\share\\writable"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 5,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"rw\",\r\n \"allowed_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 5,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"rw\",\r\n \"allowed_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:\\\\\\\\?\\\\{root_json}\\\\distro.erofs,ro\",\"--microvm-sandbox-block\",\"scratch:file:\\\\\\\\?\\\\{root_json}\\\\scratch.ext4\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount\",\"/data,{root_json}\\\\share,rw\",\"--mount-deny\",\"{root_json}\\\\share\\\\hidden\",\"--mount-allow\",\"{root_json}\\\\share\\\\hidden\\\\shown\",\"--mount-write\",\"{root_json}\\\\share\\\\writable\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"whp\",\"--memory\",\"256M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 5,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"rw\",\r\n \"allowed_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 5,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"rw\",\r\n \"allowed_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 5,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"rw\",\r\n \"allowed_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied_paths\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"guest_target\": \"/data\",\r\n \"host_path\": \"{root_json}\\\\share\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, +{"name":"lifecycle: file share","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/etc/single.txt,{root}\\single.txt,ro"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 6,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"allowed_paths\": [],\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/etc/single.txt\",\r\n \"host_path\": \"{root_json}\\\\single.txt\",\r\n \"kind\": \"file\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": []\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 6,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"allowed_paths\": [],\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/etc/single.txt\",\r\n \"host_path\": \"{root_json}\\\\single.txt\",\r\n \"kind\": \"file\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": []\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:\\\\\\\\?\\\\{root_json}\\\\distro.erofs,ro\",\"--microvm-sandbox-block\",\"scratch:file:\\\\\\\\?\\\\{root_json}\\\\scratch.ext4\",\"--microvm-workload-identity\",\"65534:65534\",\"--mount-aggregate\",\"/run/nvx/shares\",\"--mount-child\",\"0-a80a05e9cb129bc27b7ba103bf2f5ac0,{root_json}\\\\single.txt,ro,file\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"whp\",\"--memory\",\"256M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox nvx_share=0-a80a05e9cb129bc27b7ba103bf2f5ac0,/etc/single.txt,ro,file\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 6,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"allowed_paths\": [],\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/etc/single.txt\",\r\n \"host_path\": \"{root_json}\\\\single.txt\",\r\n \"kind\": \"file\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": []\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 6,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"allowed_paths\": [],\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/etc/single.txt\",\r\n \"host_path\": \"{root_json}\\\\single.txt\",\r\n \"kind\": \"file\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": []\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 6,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mounts\": [\r\n {\r\n \"access\": \"ro\",\r\n \"allowed_paths\": [],\r\n \"denied_paths\": [],\r\n \"guest_target\": \"/etc/single.txt\",\r\n \"host_path\": \"{root_json}\\\\single.txt\",\r\n \"kind\": \"file\",\r\n \"owner\": \"vmm\",\r\n \"writable_paths\": []\r\n }\r\n ],\r\n \"network\": null,\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 0,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"none\",\n \"mode\": \"none\",\n \"status\": \"not-requested\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, +{"name":"lifecycle: network and launch options","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--entrypoint","/bin/server","--arg=--serve","--hostname","worker","--workload-user","1000:1000","--memory-max","268435456","--pids-max","64","--memory-mib","384","--hypervisor","auto","--cmdline","quiet","--net","10.0.0.2/24","--network-profile","portable","--network-egress","allow","--network-ingress","deny","--network-egress-policy-file","{root}\\policy.json","--host-loopback","allow","--host-loopback-forward","tcp:18080:8080","--host-loopback-forward","udp:19090:9090"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"192.0.2.128/25\"}]}"},"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"quiet\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"worker\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": 268435456,\r\n \"memory_mib\": 384,\r\n \"mount\": null,\r\n \"network\": {\r\n \"allow\": {\r\n \"name\": \"--network-egress-allow\",\r\n \"rules\": [\r\n {\r\n \"ports\": [\r\n {\r\n \"endPort\": null,\r\n \"port\": 443,\r\n \"protocol\": \"tcp\"\r\n }\r\n ],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.0/24\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"deny\": {\r\n \"name\": \"--network-egress-deny\",\r\n \"rules\": [\r\n {\r\n \"ports\": [],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.128/25\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"egress\": \"allow\",\r\n \"guestNetwork\": \"10.0.0.2/24\",\r\n \"hostLoopback\": \"allow\",\r\n \"hostLoopbackForwards\": [\r\n {\r\n \"guestPort\": 8080,\r\n \"hostPort\": 18080,\r\n \"protocol\": \"tcp\"\r\n },\r\n {\r\n \"guestPort\": 9090,\r\n \"hostPort\": 19090,\r\n \"protocol\": \"udp\"\r\n }\r\n ],\r\n \"ingress\": \"deny\",\r\n \"proxy\": null\r\n },\r\n \"pids_max\": 64,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 1000,\r\n \"workload_uid\": 1000\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":null,"state/openvmm.log":null}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log","build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"quiet\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"worker\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": 268435456,\r\n \"memory_mib\": 384,\r\n \"mount\": null,\r\n \"network\": {\r\n \"allow\": {\r\n \"name\": \"--network-egress-allow\",\r\n \"rules\": [\r\n {\r\n \"ports\": [\r\n {\r\n \"endPort\": null,\r\n \"port\": 443,\r\n \"protocol\": \"tcp\"\r\n }\r\n ],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.0/24\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"deny\": {\r\n \"name\": \"--network-egress-deny\",\r\n \"rules\": [\r\n {\r\n \"ports\": [],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.128/25\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"egress\": \"allow\",\r\n \"guestNetwork\": \"10.0.0.2/24\",\r\n \"hostLoopback\": \"allow\",\r\n \"hostLoopbackForwards\": [\r\n {\r\n \"guestPort\": 8080,\r\n \"hostPort\": 18080,\r\n \"protocol\": \"tcp\"\r\n },\r\n {\r\n \"guestPort\": 9090,\r\n \"hostPort\": 19090,\r\n \"protocol\": \"udp\"\r\n }\r\n ],\r\n \"ingress\": \"deny\",\r\n \"proxy\": null\r\n },\r\n \"pids_max\": 64,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 1000,\r\n \"workload_uid\": 1000\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""},"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:\\\\\\\\?\\\\{root_json}\\\\distro.erofs,ro\",\"--microvm-sandbox-block\",\"scratch:file:\\\\\\\\?\\\\{root_json}\\\\scratch.ext4\",\"--microvm-workload-identity\",\"1000:1000\",\"--net\",\"10.0.0.2/24\",\"--network-profile\",\"portable\",\"--network-egress\",\"allow\",\"--network-ingress\",\"deny\",\"--host-loopback\",\"allow\",\"--network-egress-allow\",\"192.0.2.0/24:tcp:443\",\"--network-egress-deny\",\"192.0.2.128/25\",\"--host-loopback-forward\",\"tcp:18080:8080\",\"--host-loopback-forward\",\"udp:19090:9090\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"whp\",\"--memory\",\"384M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--cmdline\",\"quiet nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=worker nvx_memory_max=268435456 nvx_pids_max=65\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"quiet\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"worker\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": 268435456,\r\n \"memory_mib\": 384,\r\n \"mount\": null,\r\n \"network\": {\r\n \"allow\": {\r\n \"name\": \"--network-egress-allow\",\r\n \"rules\": [\r\n {\r\n \"ports\": [\r\n {\r\n \"endPort\": null,\r\n \"port\": 443,\r\n \"protocol\": \"tcp\"\r\n }\r\n ],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.0/24\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"deny\": {\r\n \"name\": \"--network-egress-deny\",\r\n \"rules\": [\r\n {\r\n \"ports\": [],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.128/25\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"egress\": \"allow\",\r\n \"guestNetwork\": \"10.0.0.2/24\",\r\n \"hostLoopback\": \"allow\",\r\n \"hostLoopbackForwards\": [\r\n {\r\n \"guestPort\": 8080,\r\n \"hostPort\": 18080,\r\n \"protocol\": \"tcp\"\r\n },\r\n {\r\n \"guestPort\": 9090,\r\n \"hostPort\": 19090,\r\n \"protocol\": \"udp\"\r\n }\r\n ],\r\n \"ingress\": \"deny\",\r\n \"proxy\": null\r\n },\r\n \"pids_max\": 64,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 1000,\r\n \"workload_uid\": 1000\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 1,\n \"deny_rule_count\": 1,\n \"host_loopback\": \"allow\",\n \"mode\": \"rules\",\n \"status\": \"applied\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","control.capability","openvmm.log","runtime.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"quiet\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"worker\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": 268435456,\r\n \"memory_mib\": 384,\r\n \"mount\": null,\r\n \"network\": {\r\n \"allow\": {\r\n \"name\": \"--network-egress-allow\",\r\n \"rules\": [\r\n {\r\n \"ports\": [\r\n {\r\n \"endPort\": null,\r\n \"port\": 443,\r\n \"protocol\": \"tcp\"\r\n }\r\n ],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.0/24\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"deny\": {\r\n \"name\": \"--network-egress-deny\",\r\n \"rules\": [\r\n {\r\n \"ports\": [],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.128/25\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"egress\": \"allow\",\r\n \"guestNetwork\": \"10.0.0.2/24\",\r\n \"hostLoopback\": \"allow\",\r\n \"hostLoopbackForwards\": [\r\n {\r\n \"guestPort\": 8080,\r\n \"hostPort\": 18080,\r\n \"protocol\": \"tcp\"\r\n },\r\n {\r\n \"guestPort\": 9090,\r\n \"hostPort\": 19090,\r\n \"protocol\": \"udp\"\r\n }\r\n ],\r\n \"ingress\": \"deny\",\r\n \"proxy\": null\r\n },\r\n \"pids_max\": 64,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 1000,\r\n \"workload_uid\": 1000\r\n}\r\n"},"state/runtime.json":{"text":"{\n \"format\": 4,\n \"launch\": \"{hex32}\",\n \"process\": {\n \"pid\": {int},\n \"startTime\": {int},\n \"boot\": \"{hex32}\"\n },\n \"endpoint\": \"//./pipe/openvmm-microvm-{hex32}\",\n \"runtime\": {\n \"openvmm\": \"sha256:1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\",\n \"kernel\": \"sha256:a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\",\n \"initramfs\": \"sha256:2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\",\n \"bootContract\": 3,\n \"controlContract\": \"nvx-microvm-v2-control-v2\",\n \"controlSession\": 1\n }\n}\n"},"state/control.capability":{"size":32},"state/outcome.json":null,"state/openvmm.log":{"text":""}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":0,"stdout":"","stderr":"","files":{"state":{"entries":["config.json","openvmm.log","outcome.json","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"quiet\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"worker\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": 268435456,\r\n \"memory_mib\": 384,\r\n \"mount\": null,\r\n \"network\": {\r\n \"allow\": {\r\n \"name\": \"--network-egress-allow\",\r\n \"rules\": [\r\n {\r\n \"ports\": [\r\n {\r\n \"endPort\": null,\r\n \"port\": 443,\r\n \"protocol\": \"tcp\"\r\n }\r\n ],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.0/24\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"deny\": {\r\n \"name\": \"--network-egress-deny\",\r\n \"rules\": [\r\n {\r\n \"ports\": [],\r\n \"to\": [\r\n {\r\n \"cidr\": \"192.0.2.128/25\",\r\n \"except\": []\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n \"egress\": \"allow\",\r\n \"guestNetwork\": \"10.0.0.2/24\",\r\n \"hostLoopback\": \"allow\",\r\n \"hostLoopbackForwards\": [\r\n {\r\n \"guestPort\": 8080,\r\n \"hostPort\": 18080,\r\n \"protocol\": \"tcp\"\r\n },\r\n {\r\n \"guestPort\": 9090,\r\n \"hostPort\": 19090,\r\n \"protocol\": \"udp\"\r\n }\r\n ],\r\n \"ingress\": \"deny\",\r\n \"proxy\": null\r\n },\r\n \"pids_max\": 64,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 1000,\r\n \"workload_uid\": 1000\r\n}\r\n"},"state/runtime.json":null,"state/control.capability":null,"state/outcome.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 1,\n \"deny_rule_count\": 1,\n \"host_loopback\": \"allow\",\n \"mode\": \"rules\",\n \"status\": \"applied\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"managed\",\n \"status_code\": 0\n },\n \"schema_version\": 1,\n \"teardown\": {\n \"control_channels_closed\": true,\n \"guest_workload_stopped\": true,\n \"network_released\": true,\n \"openvmm_process_terminated\": true,\n \"temporary_storage_removed\": true,\n \"virtiofs_released\": true,\n \"vm_stopped\": true\n }\n}\n"},"state/openvmm.log":{"text":""}}},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, {"name":"lifecycle: proxy-only network","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--net","10.0.0.2/24","--network-profile","portable","--network-egress","deny","--host-loopback","deny","--network-proxy","10.0.0.1:3128"],"check":["state/config.json"],"status":0,"stdout":"","stderr":"","files":{"state/config.json":{"text":"{\r\n \"cmdline\": \"\",\r\n \"distro_binding\": {\r\n \"format\": \"erofs\",\r\n \"identity\": \"11111111-1111-1111-1111-111111111111\",\r\n \"image\": {\r\n \"changed\": null,\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 7,\r\n \"modified\": {\r\n \"nanoseconds\": {int},\r\n \"seconds\": {int}\r\n },\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"manifest\": null,\r\n \"policy\": {\r\n \"result\": \"accepted\",\r\n \"revision\": 1\r\n },\r\n \"version\": 1\r\n },\r\n \"format\": 1,\r\n \"hostname\": \"nvx-sandbox\",\r\n \"hypervisor\": \"whp\",\r\n \"layers\": [\r\n {\r\n \"path\": \"{root_json}\\\\distro.erofs\",\r\n \"role\": \"distro\",\r\n \"uuid\": \"11111111-1111-1111-1111-111111111111\"\r\n }\r\n ],\r\n \"memory_max\": null,\r\n \"memory_mib\": 256,\r\n \"mount\": null,\r\n \"network\": {\r\n \"allow\": {\r\n \"name\": \"--network-egress-allow\",\r\n \"rules\": []\r\n },\r\n \"deny\": {\r\n \"name\": \"--network-egress-deny\",\r\n \"rules\": []\r\n },\r\n \"egress\": \"deny\",\r\n \"guestNetwork\": \"10.0.0.2/24\",\r\n \"hostLoopback\": \"deny\",\r\n \"hostLoopbackForwards\": [],\r\n \"ingress\": \"deny\",\r\n \"proxy\": {\r\n \"port\": 3128,\r\n \"scheme\": null\r\n }\r\n },\r\n \"pids_max\": null,\r\n \"scratch\": \"{root_json}\\\\scratch.ext4\",\r\n \"scratch_binding\": {\r\n \"device\": {int},\r\n \"fileId\": \"{hex32}\",\r\n \"kind\": \"regular\",\r\n \"length\": 8,\r\n \"scheme\": \"windows\",\r\n \"version\": 1\r\n },\r\n \"workload_gid\": 65534,\r\n \"workload_uid\": 65534\r\n}\r\n"}}},{"argv":["sandbox","start","--state-dir","{root}\\state"],"check":["build/fake-openvmm-state.json"],"status":0,"stdout":"","stderr":"","files":{"build/fake-openvmm-state.json":{"text":"[\"--machine\",\"microvm\",\"--microvm-sandbox-block\",\"distro:file:\\\\\\\\?\\\\{root_json}\\\\distro.erofs,ro\",\"--microvm-sandbox-block\",\"scratch:file:\\\\\\\\?\\\\{root_json}\\\\scratch.ext4\",\"--microvm-workload-identity\",\"65534:65534\",\"--net\",\"10.0.0.2/24\",\"--network-profile\",\"portable\",\"--network-egress\",\"deny\",\"--network-ingress\",\"deny\",\"--host-loopback\",\"deny\",\"--network-proxy\",\"10.0.0.1:3128\",\"--microvm-lifecycle\",\"managed\",\"--single-process\",\"--hypervisor\",\"whp\",\"--memory\",\"256M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--cmdline\",\"nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/sh nvx_hostname=nvx-sandbox\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"}}},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"status":0,"stdout":"","stderr":""},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}]}, {"name":"state: operations without a sandbox","steps":[{"argv":["sandbox","start","--state-dir","{root}\\state"],"status":1,"stdout":"","stderr":"error: sandbox state path is not a plain directory: {root}\\state\r\n"},{"argv":["sandbox","exec","--state-dir","{root}\\state"],"status":1,"stdout":"","stderr":"error: sandbox state path is not a plain directory: {root}\\state\r\n"},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"status":1,"stdout":"","stderr":"error: sandbox state path is not a plain directory: {root}\\state\r\n"},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"status":1,"stdout":"","stderr":"error: sandbox state path is not a plain directory: {root}\\state\r\n"}]}, {"name":"state: refusals of a running sandbox","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"status":0,"stdout":"","stderr":""},{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"status":1,"stdout":"","stderr":"error: sandbox is already provisioned\r\n"},{"argv":["sandbox","start","--state-dir","{root}\\state"],"status":0,"stdout":"","stderr":""},{"argv":["sandbox","start","--state-dir","{root}\\state"],"status":1,"stdout":"","stderr":"error: sandbox is already running or has stale runtime state\r\n"},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"status":1,"stdout":"","stderr":"error: sandbox must be stopped before deprovision\r\n"},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"status":0,"stdout":"","stderr":""},{"argv":["sandbox","stop","--state-dir","{root}\\state"],"status":1,"stdout":"","stderr":"error: sandbox is not running\r\n"},{"argv":["sandbox","exec","--state-dir","{root}\\state"],"status":1,"stdout":"","stderr":"error: sandbox is not running\r\n"},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, diff --git a/nvx-rs/tests/fixtures/store/invalid/launch-without-log.json b/nvx-rs/tests/fixtures/store/invalid/launch-without-log.json index e60a1c370..870f613b5 100644 --- a/nvx-rs/tests/fixtures/store/invalid/launch-without-log.json +++ b/nvx-rs/tests/fixtures/store/invalid/launch-without-log.json @@ -6,7 +6,7 @@ "openvmm": "sha256:1111111111111111111111111111111111111111111111111111111111111111", "kernel": "sha256:2222222222222222222222222222222222222222222222222222222222222222", "initramfs": "sha256:3333333333333333333333333333333333333333333333333333333333333333", - "bootContract": 2, + "bootContract": 3, "controlContract": "nvx-microvm-v2-control-v2", "controlSession": 1 } diff --git a/nvx-rs/tests/fixtures/store/invalid/runtime-unknown-field.json b/nvx-rs/tests/fixtures/store/invalid/runtime-unknown-field.json index 61fd448ba..1ec857d35 100644 --- a/nvx-rs/tests/fixtures/store/invalid/runtime-unknown-field.json +++ b/nvx-rs/tests/fixtures/store/invalid/runtime-unknown-field.json @@ -11,7 +11,7 @@ "openvmm": "sha256:1111111111111111111111111111111111111111111111111111111111111111", "kernel": "sha256:2222222222222222222222222222222222222222222222222222222222222222", "initramfs": "sha256:3333333333333333333333333333333333333333333333333333333333333333", - "bootContract": 2, + "bootContract": 3, "controlContract": "nvx-microvm-v2-control-v2", "controlSession": 1 }, diff --git a/nvx-rs/tests/fixtures/store/launch-prepared.json b/nvx-rs/tests/fixtures/store/launch-prepared.json index d98e78192..41f8fcdc4 100644 --- a/nvx-rs/tests/fixtures/store/launch-prepared.json +++ b/nvx-rs/tests/fixtures/store/launch-prepared.json @@ -6,7 +6,7 @@ "openvmm": "sha256:1111111111111111111111111111111111111111111111111111111111111111", "kernel": "sha256:2222222222222222222222222222222222222222222222222222222222222222", "initramfs": "sha256:3333333333333333333333333333333333333333333333333333333333333333", - "bootContract": 2, + "bootContract": 3, "controlContract": "nvx-microvm-v2-control-v2", "controlSession": 1 }, diff --git a/nvx-rs/tests/fixtures/store/launch-spawned.json b/nvx-rs/tests/fixtures/store/launch-spawned.json index 29277cc35..8a3b22174 100644 --- a/nvx-rs/tests/fixtures/store/launch-spawned.json +++ b/nvx-rs/tests/fixtures/store/launch-spawned.json @@ -6,7 +6,7 @@ "openvmm": "sha256:1111111111111111111111111111111111111111111111111111111111111111", "kernel": "sha256:2222222222222222222222222222222222222222222222222222222222222222", "initramfs": "sha256:3333333333333333333333333333333333333333333333333333333333333333", - "bootContract": 2, + "bootContract": 3, "controlContract": "nvx-microvm-v2-control-v2", "controlSession": 1 }, diff --git a/nvx-rs/tests/fixtures/store/runtime.json b/nvx-rs/tests/fixtures/store/runtime.json index 34effe43e..fa9b82b21 100644 --- a/nvx-rs/tests/fixtures/store/runtime.json +++ b/nvx-rs/tests/fixtures/store/runtime.json @@ -11,7 +11,7 @@ "openvmm": "sha256:1111111111111111111111111111111111111111111111111111111111111111", "kernel": "sha256:2222222222222222222222222222222222222222222222222222222222222222", "initramfs": "sha256:3333333333333333333333333333333333333333333333333333333333333333", - "bootContract": 2, + "bootContract": 3, "controlContract": "nvx-microvm-v2-control-v2", "controlSession": 1 } diff --git a/nvx-rs/tests/store.rs b/nvx-rs/tests/store.rs index ad9587fd3..83088580a 100644 --- a/nvx-rs/tests/store.rs +++ b/nvx-rs/tests/store.rs @@ -665,6 +665,12 @@ fn another_runtime_identity_is_mismatched() { |runtime| runtime.boot_contract += 1, IdentityPart::BootContract, ); + // Builds before boot contract 3 recorded the microVM ABI version, 2, as the boot contract, + // and booted guests that read a layered root's image token without a format. + mismatched( + |runtime| runtime.boot_contract = 2, + IdentityPart::BootContract, + ); mismatched( |runtime| runtime.control_contract.push_str("-next"), IdentityPart::ControlContract, diff --git a/scripts/test_microvm_tests.py b/scripts/test_microvm_tests.py index 7facaadc7..3e48b1c2b 100644 --- a/scripts/test_microvm_tests.py +++ b/scripts/test_microvm_tests.py @@ -1152,7 +1152,7 @@ def _launch(self, state: Path) -> _CliResult: "openvmm": "sha256:" + "1" * 64, "kernel": "sha256:" + "2" * 64, "initramfs": "sha256:" + "3" * 64, - "bootContract": 2, + "bootContract": 3, "controlContract": "nvx-microvm-v2-control-v2", "controlSession": 1, }, From b8fbce679542791e69b7546bf03afdf5dd2f6f3d Mon Sep 17 00:00:00 2001 From: Enrique Saurez Date: Thu, 22 Oct 2026 22:53:30 -0700 Subject: [PATCH 4/4] nvx-rs: let Ctrl-C end the wait for a terminated OpenVMM The CLI's stop of a VM of another runtime identity waited inside Vmm::terminate for up to --timeout seconds, a wait that does not see Ctrl-C. An OpenVMM that outlived its termination, as one in uninterruptible I/O, therefore held the stop until the timeout passed. The termination now waits one retry interval at most, and the stop's own wait, which Ctrl-C ends, waits for the rest. Once OpenVMM has exited, a second termination finds it exited, signals nothing, and clears its runtime record, and the stop reports the forced termination as before. A stop that Ctrl-C ends keeps the record, so that the next stop retries. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 84d06582-33fd-47b2-954e-904c4ea1a084 --- doc/run.md | 5 +- nvx-rs/README.md | 4 +- nvx-rs/src/host/cli/sandbox/lifecycle.rs | 181 +++++++++++++++++++++-- 3 files changed, 172 insertions(+), 18 deletions(-) diff --git a/doc/run.md b/doc/run.md index 14f63abcc..03bc4c3bd 100644 --- a/doc/run.md +++ b/doc/run.md @@ -1171,8 +1171,9 @@ replaced, may speak other contracts, so `start` and `exec` refuse it, naming the parts that differ, `deprovision` refuses it as running, and `stop` terminates its OpenVMM without a guest shutdown, waits up to `--timeout` seconds for it to exit, and warns that it did. A `stop` that cannot determine -the OpenVMM process, or whose terminated OpenVMM does not exit in time, keeps -the sandbox's runtime record, and the next `stop` retries. The store reads +the OpenVMM process, whose terminated OpenVMM does not exit in time, or whose +wait Ctrl-C ends, keeps the sandbox's runtime record, and the next `stop` +retries. The store reads runtime records of its own format only, so stop every running sandbox with the NVX version that started it before you switch versions: a version with another format fails every transition of such diff --git a/nvx-rs/README.md b/nvx-rs/README.md index d5e3a4e00..a1b99e54a 100644 --- a/nvx-rs/README.md +++ b/nvx-rs/README.md @@ -611,8 +611,8 @@ session to it: `start` and `exec` refuse it, naming the parts that differ, its verified process identity, waits up to `--timeout` seconds for it to exit, and warns on standard error that it did. The guest does not shut down, so OpenVMM publishes no outcome report. An OpenVMM that does not exit in time, or -whose identity the stop cannot determine, keeps the runtime record, and the -next `stop` retries. +whose identity the stop cannot determine, keeps the runtime record, as does a +stop whose wait Ctrl-C ends, and the next `stop` retries. The store reads runtime records of its format alone. A sandbox that a build with another format started, such as one whose `runtime.json` has format 1, diff --git a/nvx-rs/src/host/cli/sandbox/lifecycle.rs b/nvx-rs/src/host/cli/sandbox/lifecycle.rs index 133159f9b..f210192f7 100644 --- a/nvx-rs/src/host/cli/sandbox/lifecycle.rs +++ b/nvx-rs/src/host/cli/sandbox/lifecycle.rs @@ -63,7 +63,6 @@ use crate::ErrorKind; use crate::host::cli::deadline::{Deadline, RETRY_INTERVAL}; use crate::host::cli::session::{EXIT_CATEGORIES, ExecRequest, ExecResult, Session}; use crate::host::cli::{Exit, Result, check_interrupt, output}; -use crate::host::launch::MAX_TIMEOUT; use crate::host::python::builtins::{Int, repr}; use crate::host::python::dumps::{self, Value, dict}; use crate::host::python::fs::{self, os_error_message}; @@ -780,7 +779,7 @@ pub(crate) fn stop( let mut session = connect(vmm, &capability, timeout)?; session.stop(timeout)?; } - wait_for_exit(vmm, Deadline::after(timeout)) + wait_for_exit(vmm, Deadline::after(timeout)).map(drop) }) .map_err(error_with_cause)?; if let Some(error) = stopped.graceful_error { @@ -798,22 +797,23 @@ pub(crate) fn stop( /// /// Its guest is not asked to shut down, and no control session is opened to it: its OpenVMM is /// terminated through its verified process identity, as [`Vmm::terminate`] does, and the stop -/// waits up to `timeout` seconds for it to exit. One that does not exit then, or whose exit cannot -/// be determined, fails the stop, and keeps its runtime record, so that a later stop retries. +/// waits up to `timeout` seconds for it to exit, as [`terminate_within`] does, so that Ctrl-C ends +/// the wait. One that does not exit then, whose exit cannot be determined, or whose wait Ctrl-C +/// ends, keeps its runtime record, so that a later stop retries. fn terminate_mismatched( locked: &mut LockedStore, vmm: &Vmm, differences: &[IdentityPart], timeout: f64, ) -> Result { - // `--timeout` is positive and finite, but may be shorter than a nanosecond or longer than a - // termination may wait. - let bound = Duration::try_from_secs_f64(timeout) - .unwrap_or(MAX_TIMEOUT) - .clamp(Duration::from_nanos(1), MAX_TIMEOUT); let pid = vmm.record().process().pid; let parts = differing_parts(differences); - let ended = match vmm.terminate(locked, bound).map_err(error_with_cause)? { + let outcome = terminate_within( + Deadline::after(timeout), + |bound| vmm.terminate(locked, bound).map_err(error_with_cause), + |deadline| wait_for_exit(vmm, deadline), + )?; + let ended = match outcome { StopOutcome::Forced => "was terminated without a guest shutdown", StopOutcome::Graceful => "had exited", StopOutcome::TimedOut => { @@ -830,8 +830,40 @@ fn terminate_mismatched( Ok(()) } -/// Waits until the OpenVMM of `vmm` exits or `deadline` passes, failing if Ctrl-C arrives first. -fn wait_for_exit(vmm: &Vmm, deadline: Deadline) -> Result { +/// Ends an OpenVMM by identity-verified forced termination, and waits until `deadline` for it to +/// exit: `terminate` terminates it unless it has exited, waits up to the bound that it takes for +/// it to exit, and clears its runtime record once it has, as [`Vmm::terminate`] does, and `wait` +/// waits for its exit until a deadline, fails if Ctrl-C arrives first, and returns whether it +/// exited, as [`wait_for_exit`] does. +/// +/// The termination waits for one retry interval at most, and `wait` for the rest, so that Ctrl-C +/// ends the wait for an OpenVMM that does not exit at once, as one in uninterruptible I/O. Once +/// that one has exited, a second termination finds it exited, signals nothing, and clears its +/// record, and the result is [`StopOutcome::Forced`] all the same. One that still runs at the +/// deadline is [`StopOutcome::TimedOut`], and Ctrl-C fails the termination: both keep the record. +fn terminate_within( + deadline: Deadline, + mut terminate: impl FnMut(Duration) -> Result, + wait: impl FnOnce(Deadline) -> Result, +) -> Result { + check_interrupt()?; + // A termination's bound is positive, though the deadline may have passed. + let bound = deadline + .remaining() + .map_or(RETRY_INTERVAL, |left| left.min(RETRY_INTERVAL)) + .max(Duration::from_nanos(1)); + match terminate(bound)? { + StopOutcome::TimedOut if wait(deadline)? => match terminate(bound)? { + StopOutcome::TimedOut => Ok(StopOutcome::TimedOut), + StopOutcome::Graceful | StopOutcome::Forced => Ok(StopOutcome::Forced), + }, + outcome => Ok(outcome), + } +} + +/// Waits until the OpenVMM of `vmm` exits or `deadline` passes, and returns whether it exited, +/// failing if Ctrl-C arrives first. +fn wait_for_exit(vmm: &Vmm, deadline: Deadline) -> Result { loop { check_interrupt()?; let slice = deadline @@ -840,9 +872,11 @@ fn wait_for_exit(vmm: &Vmm, deadline: Deadline) -> Result { if vmm .wait(Instant::now() + slice) .map_err(Exit::from_os_error)? - || deadline.passed() { - return Ok(()); + return Ok(true); + } + if deadline.passed() { + return Ok(false); } } } @@ -863,3 +897,122 @@ pub(crate) fn deprovision(state_path: &str, artifacts: &Artifacts<'_>, timeout: // directory. lock.remove(timeout) } + +#[cfg(test)] +mod tests { + use std::cell::{Cell, RefCell}; + + use super::*; + + /// An OpenVMM of another runtime identity whose termination a test scripts, without a process. + struct Scripted { + /// Whether OpenVMM has exited. + exited: Cell, + /// Whether a termination ends OpenVMM within its bound, which one in uninterruptible I/O + /// outlives. + dies_when_terminated: bool, + /// Whether the runtime record of its launch remains. + recorded: Cell, + /// The bounds of its terminations, in order. + bounds: RefCell>, + } + + impl Scripted { + /// Returns an OpenVMM that runs, which a termination ends if `dies_when_terminated`. + fn running(dies_when_terminated: bool) -> Self { + Self { + exited: Cell::new(false), + dies_when_terminated, + recorded: Cell::new(true), + bounds: RefCell::new(Vec::new()), + } + } + + /// Terminates OpenVMM within `bound`, as [`Vmm::terminate`] does: one that has exited is + /// not signaled, and the runtime record goes once it has exited. + fn terminate(&self, bound: Duration) -> Result { + self.bounds.borrow_mut().push(bound); + let outcome = if self.exited.get() { + StopOutcome::Graceful + } else if self.dies_when_terminated { + self.exited.set(true); + StopOutcome::Forced + } else { + StopOutcome::TimedOut + }; + if self.exited.get() { + self.recorded.set(false); + } + Ok(outcome) + } + + /// Ends OpenVMM, as a stop with an hour's timeout does, and ends the stop's wait for its + /// exit with `waited`: OpenVMM exits during the wait if that is `Ok(true)`. + fn stop(&self, waited: Result) -> Result { + terminate_within( + Deadline::after(3600.0), + |bound| self.terminate(bound), + |_| { + if matches!(waited, Ok(true)) { + self.exited.set(true); + } + waited + }, + ) + } + + /// Returns the bounds of its terminations. + fn bounds(&self) -> Vec { + self.bounds.borrow().clone() + } + } + + #[test] + fn ctrl_c_ends_the_wait_for_a_terminated_openvmm_that_has_not_exited() { + // OpenVMM outlives its termination, so the termination waits one retry interval at most, + // whatever the timeout, and the stop's own wait, which Ctrl-C ends, waits for the rest. + let openvmm = Scripted::running(false); + let stopped = openvmm.stop(Err(Exit::Interrupted)); + assert!(matches!(stopped, Err(Exit::Interrupted)), "{stopped:?}"); + let bounds = openvmm.bounds(); + assert_eq!(bounds.len(), 1, "{bounds:?}"); + assert!(bounds[0] <= RETRY_INTERVAL, "{bounds:?}"); + // Its exit was not seen, so its runtime record remains for the next stop. + assert!(openvmm.recorded.get()); + } + + #[test] + fn a_terminated_openvmm_that_exits_during_the_wait_was_forced() { + // Once it has exited, a second termination finds it exited, signals nothing, and clears + // its runtime record. + let openvmm = Scripted::running(false); + let stopped = openvmm.stop(Ok(true)); + assert!(matches!(stopped, Ok(StopOutcome::Forced)), "{stopped:?}"); + assert_eq!(openvmm.bounds().len(), 2); + assert!(!openvmm.recorded.get()); + + // One that still runs at the deadline keeps its record. + let survivor = Scripted::running(false); + let stopped = survivor.stop(Ok(false)); + assert!(matches!(stopped, Ok(StopOutcome::TimedOut)), "{stopped:?}"); + assert_eq!(survivor.bounds().len(), 1); + assert!(survivor.recorded.get()); + } + + #[test] + fn an_openvmm_that_its_termination_ends_or_that_exited_is_not_waited_for() { + // The stop's wait, which would fail here, does not run. + let openvmm = Scripted::running(true); + let stopped = openvmm.stop(Err(Exit::Interrupted)); + assert!(matches!(stopped, Ok(StopOutcome::Forced)), "{stopped:?}"); + assert_eq!(openvmm.bounds().len(), 1); + assert!(!openvmm.recorded.get()); + + let exited = Scripted::running(true); + exited.exited.set(true); + let stopped = exited.stop(Err(Exit::Interrupted)); + assert!(matches!(stopped, Ok(StopOutcome::Graceful)), "{stopped:?}"); + assert_eq!(exited.bounds().len(), 1); + assert!(!exited.recorded.get()); + } +}