diff --git a/.gitattributes b/.gitattributes index 1568bbb1f..a4efe04f5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -22,14 +22,11 @@ scripts/setup/tool-versions.conf text eol=lf nvx-rs/** text=auto eol=lf .github/workflows/*.lock.yml linguist-generated=true -# Recorded from the Python code that nvx-rs replaced, by scripts/nvx_rs_fixtures.py -# and, for the scenarios of nvx.py run in cli.json, scripts/nvx_rs_run_fixtures.py, -# which microsoft/nvx#359 and microsoft/nvx#638 retired with that code, so nothing -# regenerates them: they are the reference of that behavior, and a deliberate change -# of behavior updates them by hand, in the same change (nvx-rs/README.md, Python -# parity). +# Recorded from the Python code that nvx-rs replaced, by scripts/nvx_rs_fixtures.py, +# which microsoft/nvx#359 retired with that code, so nothing regenerates them: they +# are the reference of that behavior, and a deliberate change of behavior updates them +# by hand, in the same change (nvx-rs/README.md, Python parity). nvx-rs/src/host/python/unicode.rs linguist-generated=true -nvx-rs/tests/fixtures/cli.json linguist-generated=true nvx-rs/tests/fixtures/python.json linguist-generated=true nvx-rs/tests/fixtures/sandbox.json linguist-generated=true nvx-rs/tests/fixtures/sandbox_options.json linguist-generated=true \ No newline at end of file diff --git a/doc/ci.md b/doc/ci.md index ad792d28a..e2484c7d9 100644 --- a/doc/ci.md +++ b/doc/ci.md @@ -1691,7 +1691,9 @@ family alone, every test but each family, and every test outside the families. | --- | --- | | Python semantics | `host::python::golden::` | | Launch profile and options | `host::sandbox::golden::` | -| CLI scenarios | `nvx_rs_reproduces_the_recorded_scenarios`, in `tests/cli.rs` | + +The family of the CLI, the scenarios that `tests/cli.rs` replayed, retired +with them in [microsoft/nvx#728](https://github.com/microsoft/nvx/issues/728). One build serves every selection, so every report instruments the same lines and branches, and the script fails before it measures when a family's test diff --git a/nvx-rs/README.md b/nvx-rs/README.md index 5b073020d..27d62c954 100644 --- a/nvx-rs/README.md +++ b/nvx-rs/README.md @@ -351,20 +351,17 @@ surrogates: paths print as Python prints them, and the filesystem queries refuse them. `tests/fixtures` holds what the Python code did with fixed inputs and seeded -random corpora: `python.json` for the Python semantics, `sandbox.json` and +random corpora: `python.json` for the Python semantics, and `sandbox.json` and `sandbox_options.json` for the launch profile and the sandbox options, for -POSIX and Windows paths alike, and `cli.json` for `nvx.py sandbox` and -`nvx.py run` as commands; see [Golden scenarios](#golden-scenarios). -`scripts/nvx_rs_fixtures.py` recorded them with CPython 3.14, except the -scenarios of `nvx.py run`, and generated -the Unicode tables of `src/host/python/unicode.rs`, until `nvx.py` delegated to -`nvx-rs` and [microsoft/nvx#359](https://github.com/microsoft/nvx/issues/359) -retired the script with the Python code that it recorded; -`scripts/nvx_rs_run_fixtures.py` recorded those of `nvx.py run`, until -[microsoft/nvx#638](https://github.com/microsoft/nvx/issues/638) retired it in -turn. The golden tests compare the ports with these records and need no -Python. The records are now the reference of that behavior: a deliberate change -of behavior updates the records that it changes by hand, in the same change. +POSIX and Windows paths alike. `scripts/nvx_rs_fixtures.py` recorded them with +CPython 3.14, and generated the Unicode tables of `src/host/python/unicode.rs`, +until `nvx.py` delegated to `nvx-rs` and +[microsoft/nvx#359](https://github.com/microsoft/nvx/issues/359) retired the +script with the Python code that it recorded. The golden tests compare the +ports with these records and need no Python. The records are now the reference +of that behavior: a deliberate change of behavior updates the records that it +changes by hand, in the same change. The commands themselves have +[scenario tests](#scenario-tests). ## The nvx-rs CLI @@ -585,7 +582,7 @@ earlier `nvx-rs` provisioned, which has no bindings or no typed network: | File | Contents | | --- | --- | -| `config.json` | The provisioned sandbox, in format 1 without shares and in format 7 with the export plan of its shares under `export`, with the binding of its distro layer under `distro_binding`, that of its scratch image under `scratch_binding`, and its network under `network`, `null` for none, written as `json.dumps(value, indent=2, sort_keys=True)` writes it, with mode 0600, through a temporary file | +| `config.json` | The provisioned sandbox, in format 7, with the export plan of its shares under `export`, `null` for none, the binding of its distro layer under `distro_binding`, that of its scratch image under `scratch_binding`, and its network under `network`, `null` for none, written as `json.dumps(value, indent=2, sort_keys=True)` writes it, with mode 0600, through a temporary file. `start` also reads the format 1 that earlier builds wrote for a sandbox without shares, with `mount` `null` and no `export` | | `sandbox.lock` | The store's lock, which serializes the lifecycle transitions | | `launch.json` | The store's journal of a start in progress, or of one that was interrupted | | `runtime.json` | The store's runtime record of the running VM, in its format 4: the OpenVMM process, by its ID, its start time, and the host's boot, its control endpoint, `STATE/control.sock` or `//./pipe/openvmm-microvm-HEX` on Windows, and the [runtime identity](#runtime-identity) of its start | @@ -768,66 +765,34 @@ NVX_OPENVMM=target/debug/nvx-fake-openvmm \ --scratch SCRATCH --entrypoint /bin/echo --arg hello ``` -### Golden scenarios - -`tests/fixtures/cli.json` holds scenarios that the fixture script recorded from -the Python implementation of `nvx.py sandbox`, run as a command with the root's -OpenVMM a copy of `nvx-fake-openvmm`, and from the Python functions behind -`egress compile` and `artifacts`: the option and usage errors, dry runs, -one-shot runs, the lifecycles of sandboxes in every configuration format, and -the refusals of the lifecycle operations. Each step records the exit status, -standard output and error, and the state files, with the root, process IDs, and -random identifiers as placeholders, and the devices, file IDs, and times of the -distro and scratch bindings, which `config.json` has recorded since the -recording, and on Linux the descriptor numbers of `/proc/self/fd/N`, with -which launches have named their checked files since then, as well; on -Windows, launches have named them by their final paths, `\\?\` and the path, -since then. -Their kernel command lines name the image format of the distro layer, which -the launch profile has rendered since the recording too, and their network -options render through the typed policy, which `config.json` records under -`network`: the scenarios whose options OpenVMM refused, or that combined a -proxy with other access, now show the planner's refusals or valid policies. -The configurations of sandboxes with shares have since held the shares' export -plan, in format 7, and a policy path outside the host directory of a sandbox's -only share now fails before OpenVMM starts. -Its `posix` and `windows` sections were -recorded on each kind of host, where the script also played every scenario with -`nvx-rs`, and each lifecycle with the Python implementation and `nvx-rs` taking -turns both ways, and found no difference. `tests/cli.rs` replays the section of -its host with `nvx-rs`, without Python; since `nvx.py sandbox` runs `nvx-rs`, -these scenarios are its reference. Their state files have since followed the -sandbox store: its lock file, its runtime record, the log that each start -replaces, and the build provenance in the root from which `start` reads the -runtime identity. Their errors have since carried the -[error codes](#error-codes), as `error[CODE]: MESSAGE` and -`PROG: error[CODE]: MESSAGE`, which were added to the records by hand. - -The scenarios whose names start with `run, ` come from the Python -implementation of `nvx.py run`, which `scripts/nvx_rs_run_fixtures.py` -recorded the same way, without the CPU-profile guidance, which depends on the -host's CPU: the usage errors and help of its parser, the refusals of its -checks, dry runs of every guest, of cold boots and restores, of shares, shared -files, and their policy paths and owners, of the network options and egress -policy files, of CPU profiles and outcome reports, and of the 1024-byte budget -of the kernel command line, and runs of the fake OpenVMM, also without the -artifacts that they need. The script recorded the section of each kind of host -there, played its run scenarios with `nvx-rs run`, and found no difference, -before [microsoft/nvx#638](https://github.com/microsoft/nvx/issues/638) retired -it with the Python implementation of `nvx.py run`; since `nvx.py run` runs -`nvx-rs`, these scenarios are its reference too. - -The scenario tests of `tests/cli/` replace these transcripts with checks of -what callers rely on; see [Testing](#testing). -[microsoft/nvx#728](https://github.com/microsoft/nvx/issues/728) retires the -scenarios and their replay, and until then `tests/cli/scenarios.rs` maps each -scenario of either section, and the regressions of -[microsoft/nvx#369](https://github.com/microsoft/nvx/issues/369), -[#373](https://github.com/microsoft/nvx/issues/373), -[#462](https://github.com/microsoft/nvx/issues/462), -[#464](https://github.com/microsoft/nvx/issues/464), and -[#513](https://github.com/microsoft/nvx/issues/513), to the tests that check -what it checked, and fails for a scenario that maps to none. +### Scenario tests + +The scenario tests of `tests/cli/` run `nvx-rs` with `nvx-fake-openvmm` as +OpenVMM, in a fresh artifact root for each case, and check from tables of cases +what callers rely on: exit statuses; errors, by their [codes](#error-codes) and +by stable fragments of their messages, such as option names, values, and paths; +the entries of state directories, their records, parsed, and their POSIX modes; +and the arguments that OpenVMM receives, which the fake OpenVMM records, and +into which the `>> ` line of a run splits back, with `CommandLineToArgvW` on +Windows and a shell-word splitter on POSIX, as a property test checks for +arbitrary kernel command lines too. The tables cover usage errors and help, the +checks that refuse a command line before anything changes, dry runs, one-shot +runs, the lifecycles of sandboxes of every configuration, their executions, the +refusals of lifecycle operations, configurations of every format, from the +hand-written `config.json` files of `tests/fixtures/state/`, `egress compile`, +and `artifacts`. `tests/fixtures/run-help.txt` holds the help of `nvx-rs run`, +which `nvx.py run` prints too, since it parses the options of `nvx-rs run` +before it runs it: a test of each program checks its help against it. + +They replaced the scenarios that `scripts/nvx_rs_fixtures.py` and +`scripts/nvx_rs_run_fixtures.py` recorded from the Python implementations of +`nvx.py sandbox` and `nvx.py run`, which the CLI test replayed byte for byte +until [microsoft/nvx#728](https://github.com/microsoft/nvx/issues/728) retired +them, once every recorded scenario, and every regression that +[microsoft/nvx#722](https://github.com/microsoft/nvx/issues/722) traces, mapped +to the scenario tests, which reached every line and branch of production code +that the replay reached, and caught every mutant of the CLI that the replay +caught. ## Features @@ -1068,22 +1033,9 @@ NVX_BUNDLE=skip cargo test --all-features # unit, conformance-vector, property ``` The tests need no hypervisor. The fake-OpenVMM test drives `Instance` end to end -against `nvx-fake-openvmm`. The CLI test runs `nvx-rs` with `nvx-fake-openvmm` -as OpenVMM, in a fresh artifact root for each scenario, and its scenario tests, -in `tests/cli/`, check from tables of cases what callers rely on: exit -statuses; errors, by their [codes](#error-codes) and by stable fragments of -their messages, such as option names, values, and paths; the entries of state -directories, their records, parsed, and their POSIX modes; and the arguments -that OpenVMM receives, which the fake OpenVMM records, and into which the `>> ` -line of a run splits back, with `CommandLineToArgvW` on Windows and a -shell-word splitter on POSIX, as a property test checks for arbitrary kernel -command lines too. The tables cover usage errors and help, the checks that -refuse a command line before anything changes, dry runs, one-shot runs, the -lifecycles of sandboxes of every configuration, their executions, the refusals -of lifecycle operations, configurations of every format, from the hand-written -`config.json` files of `tests/fixtures/state/`, `egress compile`, and -`artifacts`. The CLI test also replays the [golden scenarios](#golden-scenarios) -and checks the guest-feature requirement and, on Linux, Ctrl-C. The +against `nvx-fake-openvmm`. The CLI test runs the +[scenario tests](#scenario-tests) of `nvx-rs`, and checks the guest-feature +requirement and, on Linux, Ctrl-C. The [conformance vectors](tests/vectors/README.md) of the wire formats cover both sides of every record, frame, and payload: the codec decodes each vector of `tests/vectors/nvxc-v1.txt` to its values and encodes them to its bytes, it diff --git a/nvx-rs/src/host/artifacts.rs b/nvx-rs/src/host/artifacts.rs index 8a4e404b4..89d2af315 100644 --- a/nvx-rs/src/host/artifacts.rs +++ b/nvx-rs/src/host/artifacts.rs @@ -453,8 +453,8 @@ impl Guest { /// Returns the RAM, in MiB, with which `nvx.py run` boots the guest without `--memory-mib`: /// the `default_memory_mib` of its descriptor in `scripts/nvx_tools/guests.py`, which - /// `nvx.py test-microvm` also uses, and which a test of `nvx.py` pins to the golden scenarios - /// of `nvx-rs run`. + /// `nvx.py test-microvm` also uses, and which a test of `nvx.py` pins to the help of + /// `nvx-rs run` in `tests/fixtures/run-help.txt`. pub const fn default_memory_mib(self) -> u32 { match self { Self::Alpine => 128, diff --git a/nvx-rs/src/host/cli/sandbox/lifecycle.rs b/nvx-rs/src/host/cli/sandbox/lifecycle.rs index c3047d832..b3f6d13d4 100644 --- a/nvx-rs/src/host/cli/sandbox/lifecycle.rs +++ b/nvx-rs/src/host/cli/sandbox/lifecycle.rs @@ -7,9 +7,9 @@ //! //! ```text //! / -//! config.json the launch that provision records, in format 1 without shares and in -//! format 7 with the export plan of its shares, with the bindings of its -//! distro layer and of its scratch image, and its network +//! config.json the launch that provision records, in format 7, with the export plan of +//! its shares or `null` without shares, the bindings of its distro layer +//! and of its scratch image, and its network //! sandbox.lock the store's lock, which serializes the lifecycle transitions //! launch.json the store's journal of a start in progress, or of an interrupted one //! runtime.json the store's runtime record of the running VM, in its format 4 diff --git a/nvx-rs/src/host/cli/sandbox/state.rs b/nvx-rs/src/host/cli/sandbox/state.rs index 645a7ddcb..7da5848b9 100644 --- a/nvx-rs/src/host/cli/sandbox/state.rs +++ b/nvx-rs/src/host/cli/sandbox/state.rs @@ -1,5 +1,6 @@ -//! The CLI's own record in a state directory, `config.json` in formats 1 and 7, and the JSON -//! reading and writing of the former `sandbox_lifecycle.py`. +//! The CLI's own record in a state directory, `config.json`, which `provision` writes in format 7 +//! and `start` also reads in format 1, and the JSON reading and writing of the former +//! `sandbox_lifecycle.py`. //! //! - [`write_json`] writes `json.dumps(value, indent=2, sort_keys=True) + "\n"` as //! `Path.write_text` does, with the `\n`s turned into `os.linesep`, into a temporary file of @@ -7,11 +8,12 @@ //! - [`read_json`] reads a file as `json.loads(path.read_text(encoding="utf-8"))` does, and //! accepts only an object whose version field equals, as `==` compares, one of the given //! versions. -//! - [`serialize_launch`] writes a provisioned launch, in format 1 without shares and in format 7 -//! with the export plan of its shares, and [`deserialize_launch`] reads it back with the -//! conversions, defaults, and checks of `_deserialize_launch`. Formats 2 to 6 recorded the shares -//! as they were requested; `start` no longer reads them, and such a sandbox is provisioned -//! again. +//! - [`serialize_launch`] writes a provisioned launch in format 7, with the export plan of its +//! shares under `export`, `null` without shares, and [`deserialize_launch`] reads it back with +//! the conversions, defaults, and checks of `_deserialize_launch`. It also reads format 1, which +//! earlier builds wrote for a sandbox without shares, with `mount` `null` and no `export`. +//! Formats 2 to 6 recorded the shares as they were requested; `start` no longer reads them, and +//! such a sandbox is provisioned again. //! - Every configuration also records the [`DistroBinding`] of the sandbox's distro layer, under //! `distro_binding` in its serde form, which [`deserialize_binding`] reads back for `start` to //! check. `nvx.py` never wrote one, and `start` refuses a configuration without one. The @@ -46,10 +48,11 @@ use crate::host::sandbox::layer::{LayerRole, SandboxLayer}; use crate::host::sandbox::scratch::ScratchBinding; use crate::host::sandbox::{SandboxLaunch, SandboxNetwork, SandboxSettings}; -/// The configuration of a sandbox without shares, whose `mount` is `null`. +/// The configuration that earlier builds wrote for a sandbox without shares, whose `mount` is +/// `null`, which `start` still reads. pub(crate) const CONFIG_FORMAT: u64 = 1; -/// The configuration of a sandbox with shares, which records their export plan under `export`, -/// in its serde form. +/// The configuration that `provision` writes, which records the export plan of the sandbox's +/// shares under `export`, in its serde form, or `null` for a sandbox without shares. pub(crate) const EXPORT_CONFIG_FORMAT: u64 = 7; /// Every configuration format that `start` reads. pub(crate) const CONFIG_FORMATS: [u64; 2] = [CONFIG_FORMAT, EXPORT_CONFIG_FORMAT]; @@ -235,15 +238,6 @@ pub(crate) fn read_json( Ok(document) } -/// Returns the format of the configuration of a sandbox with `export`, the export plan of its -/// shares, if any. -pub(crate) fn config_format(export: Option<&ExportPlan>) -> u64 { - match export { - Some(_) => EXPORT_CONFIG_FORMAT, - None => CONFIG_FORMAT, - } -} - /// Returns `path.resolve()` as text. fn resolved(path: &std::path::Path) -> Result { let text = crate::host::cli::sandbox::path_string(path)?; @@ -324,7 +318,6 @@ pub(crate) fn serialize_launch( scratch: &RecordedScratch, config: &ProvisionConfig<'_>, ) -> Result { - let format = config_format(launch.export()); // The distro layer is the one layer that a launch holds. let layer = &distro.layer; let layers = vec![dict([ @@ -343,7 +336,7 @@ pub(crate) fn serialize_launch( None => Value::Null, }; let mut value = dict([ - ("format", Value::from(format)), + ("format", Value::from(EXPORT_CONFIG_FORMAT)), ("layers", Value::List(layers)), ("scratch", Value::from(scratch.path.as_str())), ("hostname", Value::from(settings.hostname.as_str())), @@ -371,24 +364,20 @@ pub(crate) fn serialize_launch( .and_then(python_value) .ok_or_else(|| Exit::error(ErrorCode::Other, "cannot record the scratch binding"))?; members.insert(SCRATCH_BINDING.to_owned(), binding); - match launch.export() { - Some(export) => { - let export = serde_json::to_value(export) - .ok() - .as_ref() - .and_then(python_value) - .ok_or_else(|| { - Exit::error( - ErrorCode::Other, - "cannot record the export plan of the shares", - ) - })?; - members.insert(EXPORT.to_owned(), export); - } - None => { - members.insert("mount".to_owned(), Value::Null); - } - } + let export = match launch.export() { + Some(export) => serde_json::to_value(export) + .ok() + .as_ref() + .and_then(python_value) + .ok_or_else(|| { + Exit::error( + ErrorCode::Other, + "cannot record the export plan of the shares", + ) + })?, + None => Value::Null, + }; + members.insert(EXPORT.to_owned(), export); Ok(value) } @@ -567,24 +556,49 @@ fn iterate(document: &Document, id: NodeId) -> std::result::Result, +} + +/// Reads the shares that a configuration records: in format 7, the export plan under `export`, in +/// its serde form, or `null` for a sandbox without shares, and in format 1, none, with `mount` +/// `null` or missing. /// /// A configuration with a share under `mount`, which only formats that `start` no longer reads /// recorded, reads as one with shares but no plan, which [`deserialize_launch`] refuses. fn deserialize_export( document: &Document, root: NodeId, -) -> std::result::Result<(bool, Option), Malformed> { +) -> std::result::Result { if let Some(export) = member(document, root, EXPORT) { - let export = json_value(document, export, MAX_EXPORT_DEPTH) - .and_then(|value| serde_json::from_value(value).ok()) - .ok_or(Malformed::Malformed)?; - return Ok((true, Some(export))); + let plan = if matches!(document.node(export), Node::Null) { + None + } else { + Some( + json_value(document, export, MAX_EXPORT_DEPTH) + .and_then(|value| serde_json::from_value(value).ok()) + .ok_or(Malformed::Malformed)?, + ) + }; + return Ok(RecordedShares { + exported: true, + any: plan.is_some(), + plan, + }); } - let shares = member(document, root, "mount") + let any = member(document, root, "mount") .is_some_and(|mount| !matches!(document.node(mount), Node::Null)); - Ok((shares, None)) + Ok(RecordedShares { + exported: false, + any, + plan: None, + }) } /// Reads the launch that a configuration records, as `_deserialize_launch` does, and checks it @@ -592,12 +606,13 @@ fn deserialize_export( /// /// A missing field, or a value of the wrong type, fails as `sandbox configuration is malformed`, /// as does a layer whose role is not `distro` or an export plan that is not of its serde form. A -/// configuration whose format is not the one that its shares need fails as `sandbox configuration -/// format does not match its mounts`. The export plan must then pass the checks of +/// configuration whose format is not the one that its shares need, format 7 for one that records +/// `export` and format 1 for one that does not, fails as `sandbox configuration format does not +/// match its mounts`. The export plan must then pass the checks of /// [`SandboxLaunch::with_export`], and the launch those of [`SandboxLaunch::validated`], which /// checks again the host objects that the plan recorded. pub(crate) fn deserialize_launch(document: &Document) -> Result { - let (launch, shares, export) = (|| -> std::result::Result<_, Malformed> { + let (launch, shares) = (|| -> std::result::Result<_, Malformed> { let root = document.root(); let layers_value = member(document, root, "layers").ok_or(Malformed::Malformed)?; let mut layers = Vec::new(); @@ -632,7 +647,7 @@ pub(crate) fn deserialize_launch(document: &Document) -> Result { }; let memory_max = limit("memory_max")?; let pids_max = limit("pids_max")?; - let (shares, export) = deserialize_export(document, root)?; + let shares = deserialize_export(document, root)?; let launch = SandboxLaunch::new( layers, &scratch, @@ -644,19 +659,19 @@ pub(crate) fn deserialize_launch(document: &Document) -> Result { ..SandboxSettings::default() }, )?; - Ok((launch, shares, export)) + Ok((launch, shares)) })() .map_err(|error| match error { Malformed::Malformed => malformed(), Malformed::Exit(exit) => exit, })?; let format = member(document, document.root(), "format"); - let expected = if shares { + let expected = if shares.exported { EXPORT_CONFIG_FORMAT } else { CONFIG_FORMAT }; - if (shares && export.is_none()) + if (shares.any && shares.plan.is_none()) || !format.is_some_and(|format| equals_int(document, format, expected)) { return Err(Exit::error( @@ -664,7 +679,7 @@ pub(crate) fn deserialize_launch(document: &Document) -> Result { "sandbox configuration format does not match its mounts", )); } - let launch = launch.with_export(export)?; + let launch = launch.with_export(shares.plan)?; launch.validated()?; Ok(launch) } diff --git a/nvx-rs/tests/cli.rs b/nvx-rs/tests/cli.rs index 39852aebb..412df3f9d 100644 --- a/nvx-rs/tests/cli.rs +++ b/nvx-rs/tests/cli.rs @@ -8,23 +8,9 @@ //! line before anything changes ([`validation`]), dry runs and the splitting of their `>> ` lines //! ([`dry_run`]), one-shot runs ([`one_shot`]), the lifecycles of managed sandboxes, their //! executions, and the refusals of their operations ([`lifecycle`]), the configurations of every -//! format ([`formats`]), `egress compile` ([`egress`]), and `artifacts` ([`artifacts`]). -//! -//! `nvx_rs_reproduces_the_recorded_scenarios` replays the scenarios of `tests/fixtures/cli.json` -//! with the `nvx-rs` binary, until the scenario tests retire it (microsoft/nvx#728), and -//! [`scenarios`] maps each scenario to the tests that replace it. The retired -//! `scripts/nvx_rs_fixtures.py` recorded the scenarios from the Python implementation of -//! `nvx.py sandbox`, which `nvx-rs` replaced, and from the Python functions behind -//! `nvx-rs egress compile` and `nvx-rs artifacts`, and the retired -//! `scripts/nvx_rs_run_fixtures.py` recorded those whose names start with `run, ` from the -//! Python implementation of `nvx.py run`, with `nvx-fake-openvmm` as OpenVMM, in a section for -//! POSIX hosts and one for Windows. Each scenario runs here in a fresh root, with -//! `nvx-rs --root ROOT`, and every step must exit with the recorded status, print the recorded -//! output, and leave the recorded files, after the root, process IDs, and random identifiers are -//! replaced with the placeholders that the scripts used, and the devices, file IDs, and times -//! that the bindings of `config.json` record, the file identities that its export plan records, -//! and the numbers of the descriptors that name a launch's checked files, with `{int}` and -//! `{hex32}` as well. A deliberate change of behavior updates the recordings by hand. +//! format ([`formats`]), `egress compile` ([`egress`]), and `artifacts` ([`artifacts`]). They +//! replaced the scenarios that scripts recorded from the Python implementations of `nvx.py sandbox` +//! and `nvx.py run`, and that this test replayed until microsoft/nvx#728 retired them. //! //! The other tests check what `nvx-rs` adds to `nvx.py`. #![cfg(all( @@ -49,8 +35,6 @@ mod lifecycle; mod one_shot; #[path = "cli/openvmm.rs"] mod openvmm; -#[path = "cli/scenarios.rs"] -mod scenarios; #[path = "cli/usage.rs"] mod usage; #[path = "cli/validation.rs"] @@ -68,332 +52,12 @@ use serde_json::{Value, json}; use self::harness::{FAKE_OPENVMM, NVX_RS, Root, canonical}; -/// The recorded scenarios. -const FIXTURE: &str = include_str!("fixtures/cli.json"); -/// The section of the fixture for this host. -const PLATFORM: &str = if cfg!(windows) { "windows" } else { "posix" }; -/// The files whose permissions the CLI sets, which the fixture records on POSIX hosts. -#[cfg(unix)] -const MODE_NAMES: [&str; 5] = [ - "state", - "config.json", - "runtime.json", - "control.capability", - "sandbox.lock", -]; -/// How many scenarios run at once. -const PARALLELISM: usize = 4; - -/// Replaces the root and the volatile values of an output with the fixture's placeholders. -fn normalize(root: &Root, text: &str) -> String { - let raw = root.text(); - let escaped = python_json_escape(raw); - let mut text = text.to_owned(); - if escaped != raw { - text = text.replace(&escaped, "{root_json}"); - } - text = text.replace(raw, "{root}"); - // The seals of a distro binding hold the device, file ID, and times of the layer, and an - // export plan the device and index of the objects that a workload could move. - for prefix in [ - "\"pid\": ", - "\"start_time\": ", - "\"startTime\": ", - "\"device\": ", - "\"index\": ", - "\"seconds\": ", - "\"nanoseconds\": ", - ] { - text = replace_after(&text, prefix, |c| c.is_ascii_digit(), None, "{int}"); - } - text = replace_after(&text, "openvmm-microvm-", is_hex, Some(32), "{hex32}"); - for prefix in [ - "\"operation_id\": \"", - "\"instance_id\": \"", - "\"fileId\": \"", - "\"launch\": \"", - "\"boot\": \"", - ] { - text = replace_after(&text, prefix, is_hex, Some(32), "{hex32}"); - } - // On Linux, a launch names its checked files by the descriptors that OpenVMM inherits. - replace_after( - &text, - "/proc/self/fd/", - |c| c.is_ascii_digit(), - None, - "{int}", - ) -} - -/// Creates the tree of the fixture below `root`. -fn populate(root: &Root, tree: &[Value]) { - for entry in tree { - let relative = entry["path"].as_str().unwrap(); - if entry.get("openvmm").is_some() { - root.install_openvmm(relative); - } else if let Some(text) = entry.get("text") { - root.write(relative, text.as_str().unwrap()); - } else { - fs::create_dir_all(root.below(relative)).unwrap(); - } - } -} - -/// Returns what a step shows of a file or directory below the root, as the script records -/// it. -fn snapshot(root: &Root, relative: &str) -> Value { - let path = root.below(relative); - let Ok(metadata) = fs::symlink_metadata(&path) else { - return Value::Null; - }; - let name = path.file_name().unwrap().to_str().unwrap(); - let mut entry = serde_json::Map::new(); - if metadata.is_dir() { - let mut names: Vec = fs::read_dir(&path) - .unwrap() - .map(|entry| entry.unwrap().file_name().into_string().unwrap()) - .collect(); - names.sort(); - entry.insert("entries".into(), json!(names)); - } else if name == "control.capability" { - entry.insert("size".into(), json!(metadata.len())); - } else { - let text = String::from_utf8(fs::read(&path).unwrap()).unwrap(); - entry.insert("text".into(), json!(normalize(root, &text))); - } - #[cfg(unix)] - if MODE_NAMES.contains(&name) || name.starts_with("exec") { - use std::os::unix::fs::PermissionsExt; - entry.insert("mode".into(), json!(metadata.permissions().mode() & 0o7777)); - } - Value::Object(entry) -} - -fn is_hex(c: char) -> bool { - c.is_ascii_digit() || ('a'..='f').contains(&c) -} - -/// Replaces each run of characters of `class` after `prefix`, of exactly `length` characters if -/// given, with `placeholder`. -fn replace_after( - text: &str, - prefix: &str, - class: fn(char) -> bool, - length: Option, - placeholder: &str, -) -> String { - let mut output = String::with_capacity(text.len()); - let mut rest = text; - while let Some(position) = rest.find(prefix) { - let start = position + prefix.len(); - output.push_str(&rest[..start]); - let tail = &rest[start..]; - let run = tail.find(|c| !class(c)).unwrap_or(tail.len()); - if run > 0 && length.is_none_or(|length| run == length) { - output.push_str(placeholder); - rest = &tail[run..]; - } else { - rest = tail; - } - } - output.push_str(rest); - output -} - -/// Returns `json.dumps(text)` without its quotes: `ensure_ascii` escapes. -fn python_json_escape(text: &str) -> String { - let mut output = String::new(); - for c in text.chars() { - match c { - '"' => output.push_str("\\\""), - '\\' => output.push_str("\\\\"), - '\n' => output.push_str("\\n"), - '\r' => output.push_str("\\r"), - '\t' => output.push_str("\\t"), - '\u{8}' => output.push_str("\\b"), - '\u{c}' => output.push_str("\\f"), - ' '..='~' => output.push(c), - _ => { - let mut units = [0u16; 2]; - for unit in c.encode_utf16(&mut units) { - output.push_str(&format!("\\u{unit:04x}")); - } - } - } - } - output -} - /// Runs `nvx-rs --root ROOT ARGUMENTS` in the root, without the variables that change its /// output. fn nvx_rs(root: &Root, arguments: &[String], environment: &BTreeMap) -> Output { root.command(arguments).envs(environment).output().unwrap() } -/// Writes a file of a step: text, `hex` bytes, or `text` then `fill` repeated to `size` bytes. -fn write_file(path: &Path, content: &Value) { - let data = match content { - Value::String(text) => text.clone().into_bytes(), - Value::Object(spec) => match spec.get("hex") { - Some(hex) => (0..hex.as_str().unwrap().len()) - .step_by(2) - .map(|i| u8::from_str_radix(&hex.as_str().unwrap()[i..i + 2], 16).unwrap()) - .collect(), - None => { - let mut data = spec - .get("text") - .and_then(Value::as_str) - .unwrap_or_default() - .as_bytes() - .to_vec(); - let fill = spec["fill"].as_str().unwrap().as_bytes(); - let size = usize::try_from(spec["size"].as_u64().unwrap()).unwrap(); - while data.len() < size { - data.extend_from_slice(fill); - } - data - } - }, - other => panic!("invalid file content {other}"), - }; - fs::create_dir_all(path.parent().unwrap()).unwrap(); - fs::write(path, data).unwrap(); -} - -/// Plays a scenario and returns how its steps differ from the recording. -fn play(tree: &[Value], scenario: &Value) -> Vec { - let name = scenario["name"].as_str().unwrap(); - let root = Root::empty(); - // The recorded commands quote no part of the root, as `shlex.join` or - // `subprocess.list2cmdline` would quote a path with spaces or other special characters. - let text = root.text(); - let plain = if cfg!(windows) { - text.is_ascii() && !text.contains([' ', '\t', '"']) - } else { - text.chars() - .all(|c| c.is_ascii_alphanumeric() || "_@%+=:,./-".contains(c)) - }; - assert!( - plain, - "the golden CLI tests need a temporary directory without spaces or special \ - characters, not {text}; set TMPDIR or TEMP" - ); - populate(&root, tree); - let mut problems = Vec::new(); - for (index, step) in scenario["steps"].as_array().unwrap().iter().enumerate() { - for relative in step - .get("remove") - .and_then(Value::as_array) - .into_iter() - .flatten() - { - fs::remove_file(root.below(relative.as_str().unwrap())).unwrap(); - } - for (relative, content) in step - .get("write") - .and_then(Value::as_object) - .into_iter() - .flatten() - { - write_file(&root.below(relative), content); - } - let arguments: Vec = step["argv"] - .as_array() - .unwrap() - .iter() - .map(|argument| root.expand(argument.as_str().unwrap())) - .collect(); - let environment: BTreeMap = step - .get("env") - .and_then(Value::as_object) - .into_iter() - .flatten() - .map(|(name, value)| (name.clone(), root.expand(value.as_str().unwrap()))) - .collect(); - let output = nvx_rs(&root, &arguments, &environment); - let mut actual = json!({ - "status": output.status.code(), - "stdout": normalize(&root, &String::from_utf8_lossy(&output.stdout)), - "stderr": normalize(&root, &String::from_utf8_lossy(&output.stderr)), - }); - if let Some(checks) = step.get("check").and_then(Value::as_array) { - let files: serde_json::Map = checks - .iter() - .map(|relative| { - let relative = relative.as_str().unwrap(); - (relative.to_owned(), snapshot(&root, relative)) - }) - .collect(); - actual["files"] = Value::Object(files); - } - for field in ["status", "stdout", "stderr", "files"] { - let expected = step.get(field).unwrap_or(&Value::Null); - let got = actual.get(field).unwrap_or(&Value::Null); - if expected != got { - problems.push(format!( - "{name}, step {} ({}), {field}:\n expected: {expected}\n actual: {got}", - index + 1, - arguments.join(" ") - )); - } - } - } - problems -} - -#[test] -fn nvx_rs_reproduces_the_recorded_scenarios() { - let fixture: Value = serde_json::from_str(FIXTURE).unwrap(); - let tree = fixture["tree"].as_array().unwrap().clone(); - // The fixture's roots are those of the scenario tests. - let recorded = Root::empty(); - populate(&recorded, &tree); - let fresh = Root::new(); - let without_openvmm = |root: &Root| { - let mut snapshot = root.snapshot(); - assert!( - snapshot - .remove(&harness::OPENVMM.replace("{exe}", std::env::consts::EXE_SUFFIX)) - .is_some() - ); - snapshot - }; - assert_eq!(without_openvmm(&recorded), without_openvmm(&fresh)); - let scenarios = fixture[PLATFORM].as_array().unwrap().clone(); - assert!( - !scenarios.is_empty(), - "tests/fixtures/cli.json has no {PLATFORM} scenarios" - ); - let chunks: Vec<&[Value]> = scenarios - .chunks(scenarios.len().div_ceil(PARALLELISM)) - .collect(); - let problems: Vec = thread::scope(|scope| { - let handles: Vec<_> = chunks - .iter() - .map(|chunk| { - let tree = &tree; - scope.spawn(move || { - chunk - .iter() - .flat_map(|scenario| play(tree, scenario)) - .collect::>() - }) - }) - .collect(); - handles - .into_iter() - .flat_map(|handle| handle.join().unwrap()) - .collect() - }); - assert!( - problems.is_empty(), - "{} differences from nvx.py:\n{}", - problems.len(), - problems.join("\n") - ); -} - /// Returns the arguments that provision a minimal sandbox in `state` below the root. fn provision(root: &Root, state: &str, command_line: &str) -> Vec { provision_layer(root, state, &root.path.join("distro.erofs"), command_line) diff --git a/nvx-rs/tests/cli/artifacts.rs b/nvx-rs/tests/cli/artifacts.rs index 235a3588e..965af130b 100644 --- a/nvx-rs/tests/cli/artifacts.rs +++ b/nvx-rs/tests/cli/artifacts.rs @@ -9,9 +9,9 @@ use serde_json::{Value, json}; use crate::harness::{LINE_END, Root}; /// A root whose artifacts `artifacts` lists. -pub(crate) struct Listing { +struct Listing { /// The name of the case. - pub(crate) name: &'static str, + name: &'static str, /// The variables that the case sets, with placeholders. environment: &'static [(&'static str, &'static str)], /// The OpenVMM that `artifacts` prints, with placeholders. @@ -20,7 +20,7 @@ pub(crate) struct Listing { /// The roots whose artifacts `artifacts` lists: a checkout, and one whose OpenVMM `NVX_OPENVMM` /// overrides, which it does not check, since the variable may name an OpenVMM that does not exist. -pub(crate) const LISTINGS: [Listing; 2] = [ +const LISTINGS: [Listing; 2] = [ Listing { name: "checkout", environment: &[], diff --git a/nvx-rs/tests/cli/dry_run.rs b/nvx-rs/tests/cli/dry_run.rs index 0edaa0584..5e2ef91dd 100644 --- a/nvx-rs/tests/cli/dry_run.rs +++ b/nvx-rs/tests/cli/dry_run.rs @@ -25,9 +25,9 @@ const COMMAS: [(&str, Content); 3] = [ ]; /// A dry run, and the OpenVMM command that it prints. -pub(crate) struct DryRun { +struct DryRun { /// The name of the case. - pub(crate) name: &'static str, + name: &'static str, /// The hosts on which it runs. hosts: Hosts, /// The files that the case writes below the root first, with their contents. @@ -116,7 +116,7 @@ fn mount_child(index: usize, target: &str, host: &str, mode: &str) -> String { } /// Returns the dry runs of `nvx-rs sandbox run`. -pub(crate) fn sandbox_dry_runs() -> Vec { +fn sandbox_dry_runs() -> Vec { let network = || { one_shot() .with("--net", ["10.0.0.2/24"]) @@ -319,7 +319,7 @@ pub(crate) fn sandbox_dry_runs() -> Vec { } /// Returns the dry runs of `nvx-rs run`. -pub(crate) fn run_dry_runs() -> Vec { +fn run_dry_runs() -> Vec { let ubuntu = ("build/initramfs-ubuntu.cpio.gz", Content::Text("ubuntu\n")); let azure = ( "build/initramfs-azurelinux.cpio.gz", diff --git a/nvx-rs/tests/cli/egress.rs b/nvx-rs/tests/cli/egress.rs index 21d3509ea..73c6a160e 100644 --- a/nvx-rs/tests/cli/egress.rs +++ b/nvx-rs/tests/cli/egress.rs @@ -17,9 +17,9 @@ type Rules = (&'static [&'static str], &'static [&'static str]); type Refusal = (&'static str, &'static [&'static str]); /// An egress policy file, and what `egress compile` prints for it. -pub(crate) struct Compilation { +struct Compilation { /// The name of the case. - pub(crate) name: &'static str, + name: &'static str, /// The content of `policy.json`, which the case writes below the root, if any. policy: Option<&'static str>, /// The path that `egress compile` compiles, with placeholders. @@ -29,7 +29,7 @@ pub(crate) struct Compilation { } /// The policy files that `egress compile` compiles, or refuses. -pub(crate) const COMPILATIONS: [Compilation; 9] = [ +const COMPILATIONS: [Compilation; 9] = [ Compilation { name: "empty", policy: Some("{}"), @@ -71,7 +71,7 @@ pub(crate) const COMPILATIONS: [Compilation; 9] = [ name: "unknown field", policy: Some(r#"{"allow": [], "other": []}"#), path: "{root/policy.json}", - expected: Err(("unsupported", &["unknown field", "'other'"])), + expected: Err(("unsupported", &["unknown field", "\"other\""])), }, Compilation { name: "missing file", diff --git a/nvx-rs/tests/cli/formats.rs b/nvx-rs/tests/cli/formats.rs index f185fe226..3354c5b0f 100644 --- a/nvx-rs/tests/cli/formats.rs +++ b/nvx-rs/tests/cli/formats.rs @@ -1,7 +1,8 @@ //! The configurations of every format that a build of `nvx-rs` or `nvx.py` wrote, from the -//! hand-written `config.json` files of `tests/fixtures/state/`: `start` reads formats 1 and 7, -//! which this build writes, and refuses the others, and the configurations that `nvx.py` wrote, -//! without bindings, before it launches OpenVMM. +//! hand-written `config.json` files of `tests/fixtures/state/`: `start` reads format 7, which this +//! build writes, with shares or without, and format 1, which earlier builds wrote for a sandbox +//! without shares, and refuses the others, and the configurations that `nvx.py` wrote, without +//! bindings, before it launches OpenVMM. //! //! A fixture names the paths of a root as `{root/RELATIVE}`, the hypervisor that a provision //! records on this host as `{hypervisor}`, and the bindings of the root's distro layer and scratch @@ -35,8 +36,25 @@ enum Start { Refused(&'static [&'static str]), } +/// Returns the options with which a start launches OpenVMM for the sandbox of `format-1.json` and +/// `format-7-without-shares.json`, a reader without shares, from those of the minimal sandbox. +fn reader(options: Options) -> Options { + options + .with("--microvm-workload-identity", ["2000:2000"]) + .with("--memory", ["320M"]) + .sandbox_kernel( + "quiet", + &[ + WORKLOAD[0], + "nvx_hostname=reader", + "nvx_memory_max=134217728", + "nvx_pids_max=33", + ], + ) +} + /// The configurations of every format, as fixtures, and what a start does with each. -fn formats() -> [(&'static str, &'static str, Start); 9] { +fn formats() -> [(&'static str, &'static str, Start); 10] { let unsupported = &[ "sandbox configuration has an unsupported format", "{root/state/config.json}", @@ -46,20 +64,7 @@ fn formats() -> [(&'static str, &'static str, Start); 9] { "format 1", include_str!("../fixtures/state/format-1.json"), Start::Runs { - openvmm: |options| { - options - .with("--microvm-workload-identity", ["2000:2000"]) - .with("--memory", ["320M"]) - .sandbox_kernel( - "quiet", - &[ - WORKLOAD[0], - "nvx_hostname=reader", - "nvx_memory_max=134217728", - "nvx_pids_max=33", - ], - ) - }, + openvmm: reader, maps: None, exec: (&["--entrypoint", "/bin/echo", "--arg", "one"], "one\n"), }, @@ -114,6 +119,15 @@ fn formats() -> [(&'static str, &'static str, Start); 9] { exec: (&["--entrypoint", "/bin/pwd", "--cwd", "/data"], "/data\n"), }, ), + ( + "format 7 without shares", + include_str!("../fixtures/state/format-7-without-shares.json"), + Start::Runs { + openvmm: reader, + maps: None, + exec: (&["--entrypoint", "/bin/echo", "--arg", "seven"], "seven\n"), + }, + ), // Formats 2 to 6 recorded shares as they were requested, which no start reads any more: // such a sandbox is provisioned again. ( diff --git a/nvx-rs/tests/cli/harness.rs b/nvx-rs/tests/cli/harness.rs index cac431780..5465fbc0d 100644 --- a/nvx-rs/tests/cli/harness.rs +++ b/nvx-rs/tests/cli/harness.rs @@ -163,7 +163,7 @@ impl Root { } /// Returns a fresh, empty root. - pub(crate) fn empty() -> Self { + fn empty() -> Self { let directory = tempfile::Builder::new() .prefix("nvx-cli-") .tempdir() diff --git a/nvx-rs/tests/cli/lifecycle.rs b/nvx-rs/tests/cli/lifecycle.rs index 33469dbad..bb1f039a3 100644 --- a/nvx-rs/tests/cli/lifecycle.rs +++ b/nvx-rs/tests/cli/lifecycle.rs @@ -65,18 +65,18 @@ pub(crate) fn provision(state: &str, options: &[&str]) -> Vec { sandbox("provision", state, &all) } -/// Returns the configuration that provision records for the minimal sandbox, in format 1, with +/// Returns the configuration that provision records for the minimal sandbox, in format 7, with /// placeholders, and without the bindings of its images, which [`assert_bindings`] checks. pub(crate) fn minimal_config() -> Value { json!({ "cmdline": "", - "format": 1, + "export": null, + "format": 7, "hostname": "nvx-sandbox", "hypervisor": HYPERVISOR, "layers": [{"path": "{root/distro.erofs}", "role": "distro", "uuid": UUID}], "memory_max": null, "memory_mib": 256, - "mount": null, "network": null, "pids_max": null, "scratch": "{root/scratch.ext4}", @@ -85,14 +85,10 @@ pub(crate) fn minimal_config() -> Value { }) } -/// Returns the configuration of a sandbox with shares, whose export plan is `export`: in format 7, -/// with the plan in place of `mount`. +/// Returns the configuration of a sandbox with shares, whose export plan is `export`. pub(crate) fn shared_config(export: Value) -> Value { let mut config = minimal_config(); - config["format"] = json!(7); - let members = config.as_object_mut().unwrap(); - members.remove("mount"); - members.insert("export".to_owned(), export); + config["export"] = export; config } @@ -192,9 +188,9 @@ fn assert_capability(state: &Path) { } /// A configuration of a managed sandbox, and what its lifecycle shows of it. -pub(crate) struct Configuration { +struct Configuration { /// The name of the case. - pub(crate) name: &'static str, + name: &'static str, /// The hosts on which it runs. hosts: Hosts, /// The `--state-dir` of the sandbox, with placeholders. @@ -260,7 +256,7 @@ fn exported(options: Options, children: &[&str]) -> Options { } /// Returns the configurations of every kind of sandbox. -pub(crate) fn configurations() -> Vec { +fn configurations() -> Vec { let workdir = |directory: &'static str| -> (Vec<&'static str>, &'static str) { ( vec!["--entrypoint", "/bin/pwd", "--cwd", directory], @@ -634,9 +630,9 @@ fn lifecycles_of_every_configuration() { } /// A workload that `exec` runs in a running sandbox, and how it ends. -pub(crate) struct Execution { +struct Execution { /// The name of the case. - pub(crate) name: &'static str, + name: &'static str, /// The files that the case writes below the root first, with their contents. files: Vec<(&'static str, Content)>, /// The options of `exec` after `--state-dir`, with placeholders. @@ -671,7 +667,7 @@ fn execution(name: &'static str, options: &[&str], status: i32, stdout: &str) -> } /// Returns the executions that `exec` runs, or refuses. -pub(crate) fn executions() -> Vec { +fn executions() -> Vec { let environment_file = |name, text| { let mut case = execution( name, @@ -1069,28 +1065,40 @@ fn start_without_openvmm(root: &Root) { } /// A start refuses a configuration of a format that it does not read, one that is not an object, -/// and one without the fields of its format, before it launches OpenVMM. +/// one without the fields of its format, and one whose format is not that of its shares, before it +/// launches OpenVMM. fn malformed_configuration(root: &Root) { root.nvx_rs(&provision("{root/state}", &[])) .assert_silent_success(); + // Format 7 records the shares under `export`, `null` for none, and format 1 records no + // `export`. + let config = json(&root.below("state/config.json")); + let mut without_export = config.clone(); + without_export.as_object_mut().unwrap().remove("export"); + let mut format_1_with_export = config; + format_1_with_export["format"] = json!(1); + let unsupported = &["unsupported format", "{root/state/config.json}"][..]; + let mismatched = &["format does not match its mounts"][..]; for (text, code, fragments) in [ ( - r#"{"format": 8}"#, + r#"{"format": 8}"#.to_owned(), "format-unsupported", - &["unsupported format", "{root/state/config.json}"][..], + unsupported, ), + ("[]".to_owned(), "format-unsupported", unsupported), ( - "[]", - "format-unsupported", - &["unsupported format", "{root/state/config.json}"][..], - ), - ( - r#"{"format": 1}"#, + r#"{"format": 1}"#.to_owned(), "io", &["sandbox configuration is malformed"][..], ), + (without_export.to_string(), "format-unsupported", mismatched), + ( + format_1_with_export.to_string(), + "format-unsupported", + mismatched, + ), ] { - root.write("state/config.json", text); + root.write("state/config.json", &text); let before = root.snapshot(); let outcome = operate(root, "start", "state", &[]); assert_refused(root, &outcome, code, fragments); @@ -1253,10 +1261,10 @@ fn concurrent_starts(root: &Root) { } /// A refusal of a lifecycle operation: its name, and the steps that lead to it and check it. -pub(crate) type Refusal = (&'static str, fn(&Root)); +type Refusal = (&'static str, fn(&Root)); /// The refusals of the lifecycle operations. -pub(crate) const REFUSALS: [Refusal; 10] = [ +const REFUSALS: [Refusal; 10] = [ ("operations without a sandbox", operations_without_a_sandbox), ( "refusals of a running sandbox", diff --git a/nvx-rs/tests/cli/one_shot.rs b/nvx-rs/tests/cli/one_shot.rs index 0b1077d14..2f82567b2 100644 --- a/nvx-rs/tests/cli/one_shot.rs +++ b/nvx-rs/tests/cli/one_shot.rs @@ -25,9 +25,9 @@ struct Report { } /// A run that launches OpenVMM, and how it ends. -pub(crate) struct Launch { +struct Launch { /// The name of the case. - pub(crate) name: &'static str, + name: &'static str, /// The files that the case writes below the root first, with their contents. files: Vec<(&'static str, Content)>, /// The files that the case removes from the root first. @@ -161,7 +161,7 @@ fn run(options: &[&str]) -> Vec { } /// Returns the one-shot runs of `nvx-rs sandbox run`. -pub(crate) fn sandbox_launches() -> Vec { +fn sandbox_launches() -> Vec { let echo = || workload("", "/bin/echo", &["hello", "world"]); let mut launches = vec![ launch( @@ -285,7 +285,7 @@ pub(crate) fn sandbox_launches() -> Vec { } /// Returns the runs of `nvx-rs run`. -pub(crate) fn run_launches() -> Vec { +fn run_launches() -> Vec { let booted = "openvmm: booted the microVM\n"; let restored = "openvmm: restored the microVM\n"; vec![ diff --git a/nvx-rs/tests/cli/scenarios.rs b/nvx-rs/tests/cli/scenarios.rs deleted file mode 100644 index bd5f5db47..000000000 --- a/nvx-rs/tests/cli/scenarios.rs +++ /dev/null @@ -1,1387 +0,0 @@ -//! The tests that replace each scenario of `tests/fixtures/cli.json`, and those that guard against -//! the regressions that microsoft/nvx#722 traces, until the replay of the scenarios retires -//! (microsoft/nvx#728). This mapping retires with it. - -use std::collections::BTreeMap; -use std::fs; -use std::path::Path; - -use nvx::host::artifacts::MANIFEST_NAME; -use serde_json::Value; - -use crate::{artifacts, dry_run, egress, lifecycle, one_shot, usage, validation}; - -/// `usage::usage_errors_exit_2_and_name_the_option`. -const USAGE: &str = "usage_errors_exit_2_and_name_the_option"; -/// `usage::help_prints_the_usage_and_the_options_and_exits_0`. -const HELP: &str = "help_prints_the_usage_and_the_options_and_exits_0"; -/// `validation::validation_errors_exit_1_before_any_side_effect`. -const VALIDATION: &str = "validation_errors_exit_1_before_any_side_effect"; -/// `dry_run::dry_runs_print_the_openvmm_command_and_launch_nothing`. -const DRY_RUNS: &str = "dry_runs_print_the_openvmm_command_and_launch_nothing"; -/// `one_shot::one_shot_runs_exit_with_the_workload_or_openvmm_status`. -const ONE_SHOT: &str = "one_shot_runs_exit_with_the_workload_or_openvmm_status"; -/// `lifecycle::lifecycles_of_every_configuration`. -const LIFECYCLES: &str = "lifecycles_of_every_configuration"; -/// `lifecycle::managed_execs_exit_with_the_workload_status`. -const EXECS: &str = "managed_execs_exit_with_the_workload_status"; -/// `lifecycle::refusals_of_lifecycle_operations`. -const REFUSALS: &str = "refusals_of_lifecycle_operations"; -/// `egress::egress_compile_prints_the_library_lowering`. -const EGRESS: &str = "egress_compile_prints_the_library_lowering"; -/// `artifacts::artifacts_list_every_guest_in_order`. -const ARTIFACTS: &str = "artifacts_list_every_guest_in_order"; - -/// The sources of this crate that define the tests that the mapping names: those of the CLI's -/// tests, the unit tests of its control sessions, and those of the guest agent's launches. -const SOURCES: [&str; 10] = [ - include_str!("../cli.rs"), - include_str!("artifacts.rs"), - include_str!("dry_run.rs"), - include_str!("egress.rs"), - include_str!("lifecycle.rs"), - include_str!("one_shot.rs"), - include_str!("usage.rs"), - include_str!("validation.rs"), - include_str!("../../src/host/cli/session/tests.rs"), - include_str!("../../src/guest/managed_agent/launch.rs"), -]; - -/// A recorded scenario or a regression, and the tests that check what it checked: each test by -/// its name, with the name of a case of its table, or an empty name for a test without one. -type Mapping = (&'static str, &'static [(&'static str, &'static str)]); - -/// Each recorded scenario, of either section of the fixture, by its name. -const SCENARIOS: &[Mapping] = &[ - ("egress compile: empty", &[(EGRESS, "empty")]), - ("egress compile: allow", &[(EGRESS, "allow")]), - ("egress compile: both", &[(EGRESS, "both")]), - ("egress compile: invalid JSON", &[(EGRESS, "invalid JSON")]), - ("egress compile: invalid rule", &[(EGRESS, "invalid rule")]), - ( - "egress compile: unknown field", - &[(EGRESS, "unknown field")], - ), - ("egress compile: missing file", &[(EGRESS, "missing file")]), - ("egress compile: directory", &[(EGRESS, "directory")]), - ("artifacts: checkout", &[(ARTIFACTS, "checkout")]), - ( - "artifacts: OpenVMM override", - &[(ARTIFACTS, "OpenVMM override")], - ), - ("usage: help", &[(HELP, "sandbox")]), - ( - "usage: help after operation", - &[(HELP, "sandbox after an operation")], - ), - ( - "usage: timeout not a number", - &[(USAGE, "timeout not a number")], - ), - ("usage: zero timeout", &[(USAGE, "zero timeout")]), - ("usage: negative timeout", &[(USAGE, "negative timeout")]), - ("usage: infinite timeout", &[(USAGE, "infinite timeout")]), - ( - "usage: timeout not finite", - &[(USAGE, "timeout not finite")], - ), - ( - "usage: timeout not a number either", - &[(USAGE, "timeout not a number either")], - ), - ( - "usage: exec timeout not an integer", - &[(USAGE, "exec timeout not an integer")], - ), - ( - "usage: memory not an integer", - &[(USAGE, "memory not an integer")], - ), - ( - "usage: invalid hypervisor", - &[(USAGE, "invalid hypervisor")], - ), - ("usage: invalid operation", &[(USAGE, "invalid operation")]), - ("usage: second operation", &[(USAGE, "second operation")]), - ( - "usage: invalid mount owner", - &[(USAGE, "invalid mount owner")], - ), - ( - "usage: invalid network profile", - &[(USAGE, "invalid network profile")], - ), - ( - "usage: invalid egress default", - &[(USAGE, "invalid egress default")], - ), - ( - "usage: invalid host loopback", - &[(USAGE, "invalid host loopback")], - ), - ("usage: missing value", &[(USAGE, "missing value")]), - ("usage: option as value", &[(USAGE, "option as value")]), - ("usage: dash value", &[(USAGE, "dash value")]), - ("usage: flag with value", &[(USAGE, "flag with value")]), - ( - "usage: unrecognized option", - &[(USAGE, "unrecognized option")], - ), - ( - "usage: unrecognized short option", - &[(USAGE, "unrecognized short option")], - ), - ( - "usage: unrecognized after separator", - &[(USAGE, "unrecognized after separator")], - ), - ( - "validation: dry run outside run", - &[(VALIDATION, "dry run outside run")], - ), - ( - "validation: environment and environment file", - &[(VALIDATION, "environment and environment file")], - ), - ( - "validation: cwd outside exec", - &[(VALIDATION, "cwd outside exec")], - ), - ( - "validation: environment outside exec", - &[(VALIDATION, "environment outside exec")], - ), - ( - "validation: environment file outside exec", - &[(VALIDATION, "environment file outside exec")], - ), - ( - "validation: inherited environment outside exec", - &[(VALIDATION, "inherited environment outside exec")], - ), - ( - "validation: environment file too large", - &[(VALIDATION, "environment file too large")], - ), - ( - "validation: environment file at the limit", - &[(VALIDATION, "environment file at the limit")], - ), - ( - "validation: environment file missing", - &[(VALIDATION, "environment file missing")], - ), - ( - "validation: environment file directory", - &[(VALIDATION, "environment file directory")], - ), - ( - "validation: environment file not UTF-8", - &[(VALIDATION, "environment file not UTF-8")], - ), - ( - "validation: environment file not JSON", - &[(VALIDATION, "environment file not JSON")], - ), - ( - "validation: environment file object", - &[(VALIDATION, "environment file object")], - ), - ( - "validation: environment file non-string", - &[(VALIDATION, "environment file non-string")], - ), - ( - "validation: environment file entry without equals", - &[(VALIDATION, "environment file entry without equals")], - ), - ( - "validation: environment file entry with NUL", - &[(VALIDATION, "environment file entry with NUL")], - ), - ( - "validation: environment file duplicate entry", - &[(VALIDATION, "environment file duplicate entry")], - ), - ( - "validation: environment entry without name", - &[(VALIDATION, "environment entry without name")], - ), - ( - "validation: environment entry with space", - &[(VALIDATION, "environment entry with space")], - ), - ( - "validation: network outside run", - &[(VALIDATION, "network outside run")], - ), - ( - "validation: egress rule outside run", - &[(VALIDATION, "egress rule outside run")], - ), - ( - "validation: forward outside run", - &[(VALIDATION, "forward outside run")], - ), - ( - "validation: policy file outside run", - &[(VALIDATION, "policy file outside run")], - ), - ( - "validation: systemd entrypoint of run", - &[(VALIDATION, "systemd entrypoint of run")], - ), - ( - "validation: systemd entrypoint of exec", - &[(VALIDATION, "systemd entrypoint of exec")], - ), - ( - "validation: outcome report outside run", - &[(VALIDATION, "outcome report outside run")], - ), - ( - "validation: deny without mount", - &[(VALIDATION, "deny without mount")], - ), - ( - "validation: allow without mount", - &[(VALIDATION, "allow without mount")], - ), - ( - "validation: write without mount", - &[(VALIDATION, "write without mount")], - ), - ( - "validation: owner without mount", - &[(VALIDATION, "owner without mount")], - ), - ( - "validation: mount outside run", - &[(VALIDATION, "mount outside run")], - ), - ( - "validation: net without profile", - &[(VALIDATION, "net without profile")], - ), - ( - "validation: profile without net", - &[(VALIDATION, "profile without net")], - ), - ( - "validation: run without layers", - &[(VALIDATION, "run without layers")], - ), - ( - "validation: provision without scratch", - &[(VALIDATION, "provision without scratch")], - ), - ( - "validation: run without layer", - &[(VALIDATION, "run without layer")], - ), - ( - "validation: policy file with rules", - &[(VALIDATION, "policy file with rules")], - ), - ( - "validation: policy file without egress", - &[(VALIDATION, "policy file without egress")], - ), - ( - "validation: policy file missing", - &[(VALIDATION, "policy file missing")], - ), - ( - "validation: policy file invalid", - &[(VALIDATION, "policy file invalid")], - ), - ( - "validation: provision without state directory", - &[(VALIDATION, "provision without state directory")], - ), - ( - "validation: start without state directory", - &[(VALIDATION, "start without state directory")], - ), - ( - "validation: exec without state directory", - &[(VALIDATION, "exec without state directory")], - ), - ( - "validation: stop without state directory", - &[(VALIDATION, "stop without state directory")], - ), - ( - "validation: deprovision without state directory", - &[(VALIDATION, "deprovision without state directory")], - ), - ( - "validation: run with state directory", - &[(VALIDATION, "run with state directory")], - ), - ( - "validation: invalid layer UUID", - &[(USAGE, "invalid layer UUID")], - ), - ( - "validation: invalid layer role", - &[(USAGE, "invalid layer role")], - ), - ( - "validation: retired layer role", - &[(USAGE, "retired layer role")], - ), - ( - "validation: missing layer", - &[(VALIDATION, "missing layer")], - ), - ( - "validation: duplicate layer", - &[(VALIDATION, "duplicate layer")], - ), - ( - "validation: missing scratch", - &[(VALIDATION, "missing scratch")], - ), - ( - "validation: relative entrypoint", - &[(VALIDATION, "relative entrypoint")], - ), - ( - "validation: invalid hostname", - &[(VALIDATION, "invalid hostname")], - ), - ( - "validation: argument with space", - &[(VALIDATION, "argument with space")], - ), - ("validation: root workload", &[(USAGE, "root workload")]), - ( - "validation: invalid workload user", - &[(USAGE, "invalid workload user")], - ), - ( - "validation: invalid memory limit", - &[(USAGE, "invalid memory limit")], - ), - ( - "validation: invalid process limit", - &[(VALIDATION, "invalid process limit")], - ), - ( - "validation: relative mount target", - &[(VALIDATION, "relative mount target")], - ), - ( - "validation: missing mount host", - &[(VALIDATION, "missing mount host")], - ), - ( - "validation: invalid mount mode", - &[(VALIDATION, "invalid mount mode")], - ), - ( - "validation: deny outside share", - &[(VALIDATION, "deny outside share")], - ), - ( - "validation: allow outside denied path", - &[(VALIDATION, "allow outside denied path")], - ), - ( - "validation: write in read-only share", - &[(VALIDATION, "write in read-only share")], - ), - ( - "validation: reserved command-line token", - &[(VALIDATION, "reserved command-line token")], - ), - ( - "validation: systemd distro image", - &[(VALIDATION, "systemd distro image")], - ), - ( - "validation: mismatched distro manifest", - &[(VALIDATION, "mismatched distro manifest")], - ), - ( - "validation: invalid distro manifest", - &[(VALIDATION, "invalid distro manifest")], - ), - ( - "validation: distro manifest without packages", - &[(VALIDATION, "distro manifest without packages")], - ), - ("dry run: minimal", &[(DRY_RUNS, "minimal")]), - ( - "dry run: every layer and option", - &[(DRY_RUNS, "every layer and option")], - ), - ( - "dry run: explicit hypervisor", - &[(DRY_RUNS, "explicit hypervisor")], - ), - ("dry run: one share", &[(DRY_RUNS, "one share")]), - ("dry run: writable share", &[(DRY_RUNS, "writable share")]), - ("dry run: file share", &[(DRY_RUNS, "file share")]), - ( - "dry run: several shares with policies", - &[(DRY_RUNS, "several shares with policies")], - ), - ("dry run: network", &[(DRY_RUNS, "network")]), - ( - "dry run: proxy-only network", - &[(DRY_RUNS, "proxy-only network")], - ), - ( - "dry run: egress policy file", - &[(DRY_RUNS, "egress policy file")], - ), - ( - "dry run: quoted arguments", - &[(DRY_RUNS, "quoted arguments")], - ), - ( - "dry run: caller-owned share", - &[(DRY_RUNS, "caller-owned share")], - ), - ("run: echo", &[(ONE_SHOT, "echo")]), - ("run: default operation", &[(ONE_SHOT, "default operation")]), - ("run: failure", &[(ONE_SHOT, "failure")]), - ("run: missing program", &[(ONE_SHOT, "missing program")]), - ("run: exit status", &[(ONE_SHOT, "exit status")]), - ("run: outcome report", &[(ONE_SHOT, "outcome report")]), - ( - "run: network outcome report", - &[(ONE_SHOT, "network outcome report")], - ), - ( - "run: network options without --net", - &[(VALIDATION, "network options without --net")], - ), - ("run: missing OpenVMM", &[(VALIDATION, "missing OpenVMM")]), - ("run: missing kernel", &[(VALIDATION, "missing kernel")]), - ( - "run: missing initramfs", - &[(VALIDATION, "missing initramfs")], - ), - ( - "lifecycle: minimal", - &[ - (LIFECYCLES, "minimal"), - (EXECS, "echo"), - (EXECS, "working directory"), - (EXECS, "exit status with output"), - (EXECS, "exact environment"), - (EXECS, "inherited environment"), - (EXECS, "environment file"), - (EXECS, "empty environment file"), - (EXECS, "timeout"), - (EXECS, "signal"), - (EXECS, "missing program"), - (EXECS, "missing working directory"), - (EXECS, "relative working directory"), - (EXECS, "existing outcome report"), - (EXECS, "outcome report in a missing directory"), - ], - ), - ("lifecycle: one share", &[(LIFECYCLES, "one share")]), - ( - "lifecycle: caller-owned share", - &[(LIFECYCLES, "caller-owned share")], - ), - ( - "lifecycle: several shares", - &[(LIFECYCLES, "several shares")], - ), - ( - "lifecycle: share policies", - &[(LIFECYCLES, "share policies")], - ), - ("lifecycle: file share", &[(LIFECYCLES, "file share")]), - ( - "lifecycle: network and launch options", - &[(LIFECYCLES, "network and launch options")], - ), - ( - "lifecycle: proxy-only network", - &[(LIFECYCLES, "proxy-only network")], - ), - ( - "state: operations without a sandbox", - &[(REFUSALS, "operations without a sandbox")], - ), - ( - "state: refusals of a running sandbox", - &[(REFUSALS, "refusals of a running sandbox")], - ), - ( - "state: relative and nested state directory", - &[(LIFECYCLES, "relative and nested state directory")], - ), - ("state: failed start", &[(REFUSALS, "failed start")]), - ( - "state: start without OpenVMM", - &[(REFUSALS, "start without OpenVMM")], - ), - ( - "state: malformed configuration", - &[(REFUSALS, "malformed configuration")], - ), - ("state: not a directory", &[(REFUSALS, "not a directory")]), - ("state: foreign file", &[(REFUSALS, "foreign file")]), - ("run, usage: help", &[(HELP, "run")]), - ( - "run, usage: help after options", - &[(HELP, "run after options")], - ), - ( - "run, usage: help before an invalid value", - &[(HELP, "run before an invalid value")], - ), - ( - "run, usage: invalid value before help", - &[(USAGE, "run: invalid value before help")], - ), - ( - "run, usage: invalid guest", - &[(USAGE, "run: invalid guest")], - ), - ( - "run, usage: invalid second guest", - &[(USAGE, "run: invalid second guest")], - ), - ( - "run, usage: invalid hypervisor", - &[(USAGE, "run: invalid hypervisor")], - ), - ( - "run, usage: invalid machine", - &[(USAGE, "run: invalid machine")], - ), - ( - "run, usage: memory not an integer", - &[(USAGE, "run: memory not an integer")], - ), - ( - "run, usage: memory not a whole number", - &[(USAGE, "run: memory not a whole number")], - ), - ( - "run, usage: memory with a space", - &[(USAGE, "run: memory with a space")], - ), - ( - "run, usage: memory with other digits", - &[(USAGE, "run: memory with other digits")], - ), - ( - "run, usage: memory capacity not an integer", - &[(USAGE, "run: memory capacity not an integer")], - ), - ( - "run, usage: restore memory not an integer", - &[(USAGE, "run: restore memory not an integer")], - ), - ( - "run, usage: processors not an integer", - &[(USAGE, "run: processors not an integer")], - ), - ( - "run, usage: processors not a choice", - &[(USAGE, "run: processors not a choice")], - ), - ( - "run, usage: processors converted before the choice", - &[(USAGE, "run: processors converted before the choice")], - ), - ( - "run, usage: processors with a leading zero", - &[(USAGE, "run: processors with a leading zero")], - ), - ( - "run, usage: negative processors", - &[(USAGE, "run: negative processors")], - ), - ( - "run, usage: restore processors not an integer", - &[(USAGE, "run: restore processors not an integer")], - ), - ( - "run, usage: restore processors not a choice", - &[(USAGE, "run: restore processors not a choice")], - ), - ( - "run, usage: invalid mount owner", - &[(USAGE, "run: invalid mount owner")], - ), - ( - "run, usage: invalid network profile", - &[(USAGE, "run: invalid network profile")], - ), - ( - "run, usage: invalid network egress", - &[(USAGE, "run: invalid network egress")], - ), - ( - "run, usage: invalid network ingress", - &[(USAGE, "run: invalid network ingress")], - ), - ( - "run, usage: invalid host loopback", - &[(USAGE, "run: invalid host loopback")], - ), - ( - "run, usage: missing value", - &[(USAGE, "run: missing value")], - ), - ("run, usage: missing path", &[(USAGE, "run: missing path")]), - ( - "run, usage: option as value", - &[(USAGE, "run: option as value")], - ), - ("run, usage: dash value", &[(USAGE, "run: dash value")]), - ( - "run, usage: flag with value", - &[(USAGE, "run: flag with value")], - ), - ( - "run, usage: unrecognized option", - &[(USAGE, "run: unrecognized option")], - ), - ( - "run, usage: unrecognized short option", - &[(USAGE, "run: unrecognized short option")], - ), - ( - "run, usage: unrecognized positional", - &[(USAGE, "run: unrecognized positional")], - ), - ( - "run, usage: unrecognized after separator", - &[(USAGE, "run: unrecognized after separator")], - ), - ( - "run, usage: unrecognized after options", - &[(USAGE, "run: unrecognized after options")], - ), - ( - "run, validation: net without profile", - &[(VALIDATION, "run: net without profile")], - ), - ( - "run, validation: profile without net", - &[(VALIDATION, "run: profile without net")], - ), - ( - "run, validation: ready path without snapshot", - &[(VALIDATION, "run: ready path without snapshot")], - ), - ( - "run, validation: restore processors without snapshot", - &[(VALIDATION, "run: restore processors without snapshot")], - ), - ( - "run, validation: restore memory without snapshot", - &[(VALIDATION, "run: restore memory without snapshot")], - ), - ( - "run, validation: memory capacity of a restore", - &[(VALIDATION, "run: memory capacity of a restore")], - ), - ( - "run, validation: Ubuntu guest of a restore", - &[(VALIDATION, "run: Ubuntu guest of a restore")], - ), - ( - "run, validation: Azure Linux guest of a restore", - &[(VALIDATION, "run: Azure Linux guest of a restore")], - ), - ( - "run, validation: memory capacity below memory", - &[(VALIDATION, "run: memory capacity below memory")], - ), - ( - "run, validation: memory capacity below the guest default", - &[(VALIDATION, "run: memory capacity below the guest default")], - ), - ( - "run, validation: restore processors above processors", - &[(VALIDATION, "run: restore processors above processors")], - ), - ( - "run, validation: policy file with allow rules", - &[(VALIDATION, "run: policy file with allow rules")], - ), - ( - "run, validation: policy file with deny rules", - &[(VALIDATION, "run: policy file with deny rules")], - ), - ( - "run, validation: policy file without egress", - &[(VALIDATION, "run: policy file without egress")], - ), - ( - "run, validation: policy file missing", - &[(VALIDATION, "run: policy file missing")], - ), - ( - "run, validation: policy file directory", - &[(VALIDATION, "run: policy file directory")], - ), - ( - "run, validation: policy file invalid", - &[(VALIDATION, "run: policy file invalid")], - ), - ( - "run, validation: policy file not JSON", - &[(VALIDATION, "run: policy file not JSON")], - ), - ( - "run, validation: policy errors before missing artifacts", - &[(VALIDATION, "run: policy errors before missing artifacts")], - ), - ( - "run, validation: missing OpenVMM", - &[(VALIDATION, "run: missing OpenVMM")], - ), - ( - "run, validation: missing kernel", - &[(VALIDATION, "run: missing kernel")], - ), - ( - "run, validation: missing Alpine initramfs", - &[(VALIDATION, "run: missing Alpine initramfs")], - ), - ( - "run, validation: missing Ubuntu initramfs", - &[(VALIDATION, "run: missing Ubuntu initramfs")], - ), - ( - "run, validation: missing Azure Linux initramfs", - &[(VALIDATION, "run: missing Azure Linux initramfs")], - ), - ( - "run, validation: missing artifacts before invalid shares", - &[(VALIDATION, "run: missing artifacts before invalid shares")], - ), - ( - "run, validation: mount without host path", - &[(VALIDATION, "run: mount without host path")], - ), - ( - "run, validation: mount with empty host path", - &[(VALIDATION, "run: mount with empty host path")], - ), - ( - "run, validation: mount with empty host path and mode", - &[(VALIDATION, "run: mount with empty host path and mode")], - ), - ( - "run, validation: mount with invalid mode", - &[(VALIDATION, "run: mount with invalid mode")], - ), - ( - "run, validation: mount with commas but no mode", - &[(VALIDATION, "run: mount with commas but no mode")], - ), - ( - "run, validation: invalid second mount", - &[(VALIDATION, "run: invalid second mount")], - ), - ( - "run, validation: invalid mount before invalid targets", - &[(VALIDATION, "run: invalid mount before invalid targets")], - ), - ( - "run, validation: owner without mount", - &[(VALIDATION, "run: owner without mount")], - ), - ( - "run, validation: relative deny path with several shares", - &[(VALIDATION, "run: relative deny path with several shares")], - ), - ( - "run, validation: relative allow path with a shared file", - &[(VALIDATION, "run: relative allow path with a shared file")], - ), - ( - "run, validation: relative write path with several shares", - &[(VALIDATION, "run: relative write path with several shares")], - ), - ( - "run, validation: relative paths in kind order", - &[(VALIDATION, "run: relative paths in kind order")], - ), - ( - "run, validation: relative target with several shares", - &[(VALIDATION, "run: relative target with several shares")], - ), - ( - "run, validation: relative target of a shared file", - &[(VALIDATION, "run: relative target of a shared file")], - ), - ( - "run, validation: root target with several shares", - &[(VALIDATION, "run: root target with several shares")], - ), - ( - "run, validation: target with a space", - &[(VALIDATION, "run: target with a space")], - ), - ( - "run, validation: target with an equals sign", - &[(VALIDATION, "run: target with an equals sign")], - ), - ( - "run, validation: target with a backslash", - &[(VALIDATION, "run: target with a backslash")], - ), - ( - "run, validation: target with a dot component", - &[(VALIDATION, "run: target with a dot component")], - ), - ( - "run, validation: target with a parent component", - &[(VALIDATION, "run: target with a parent component")], - ), - ( - "run, validation: target with an empty component", - &[(VALIDATION, "run: target with an empty component")], - ), - ( - "run, validation: equal targets", - &[(VALIDATION, "run: equal targets")], - ), - ( - "run, validation: nested targets", - &[(VALIDATION, "run: nested targets")], - ), - ( - "run, validation: target containing another", - &[(VALIDATION, "run: target containing another")], - ), - ( - "run, validation: target containing the aggregate", - &[(VALIDATION, "run: target containing the aggregate")], - ), - ( - "run, validation: target in the aggregate", - &[(VALIDATION, "run: target in the aggregate")], - ), - ( - "run, validation: too many shares for the budget", - &[(VALIDATION, "run: too many shares for the budget")], - ), - ( - "run, validation: budget exceeded by a byte", - &[(VALIDATION, "run: budget exceeded by a byte")], - ), - ( - "run, validation: budget in UTF-8 bytes", - &[(VALIDATION, "run: budget in UTF-8 bytes")], - ), - ( - "run, validation: missing OpenVMM override", - &[(VALIDATION, "run: missing OpenVMM override")], - ), - ( - "run, dry run: Alpine default", - &[(DRY_RUNS, "run: Alpine default")], - ), - ( - "run, dry run: Ubuntu default", - &[(DRY_RUNS, "run: Ubuntu default")], - ), - ( - "run, dry run: Azure Linux default", - &[(DRY_RUNS, "run: Azure Linux default")], - ), - ( - "run, dry run: Alpine with memory", - &[(DRY_RUNS, "run: Alpine with memory")], - ), - ( - "run, dry run: Ubuntu with memory and capacity", - &[(DRY_RUNS, "run: Ubuntu with memory and capacity")], - ), - ( - "run, dry run: Azure Linux with the default capacity", - &[(DRY_RUNS, "run: Azure Linux with the default capacity")], - ), - ("run, dry run: last guest", &[(DRY_RUNS, "run: last guest")]), - ( - "run, dry run: every boot option", - &[(DRY_RUNS, "run: every boot option")], - ), - ( - "run, dry run: auto hypervisor", - &[(DRY_RUNS, "run: auto hypervisor")], - ), - ("run, dry run: KVM", &[(DRY_RUNS, "run: KVM")]), - ("run, dry run: WHP", &[(DRY_RUNS, "run: WHP")]), - ( - "run, dry run: canonical integers", - &[(DRY_RUNS, "run: canonical integers")], - ), - ( - "run, dry run: other digits", - &[(DRY_RUNS, "run: other digits")], - ), - ( - "run, dry run: negative memory", - &[(DRY_RUNS, "run: negative memory")], - ), - ( - "run, dry run: attached negative memory", - &[(DRY_RUNS, "run: attached negative memory")], - ), - ( - "run, dry run: equal memory and capacity", - &[(DRY_RUNS, "run: equal memory and capacity")], - ), - ( - "run, dry run: last processors", - &[(DRY_RUNS, "run: last processors")], - ), - ( - "run, dry run: cpu profile auto", - &[(DRY_RUNS, "run: cpu profile auto")], - ), - ( - "run, dry run: cpu profile host", - &[(DRY_RUNS, "run: cpu profile host")], - ), - ("run, dry run: restore", &[(DRY_RUNS, "run: restore")]), - ( - "run, dry run: restore without guest artifacts", - &[(DRY_RUNS, "run: restore without guest artifacts")], - ), - ( - "run, dry run: restore with every option", - &[(DRY_RUNS, "run: restore with every option")], - ), - ( - "run, dry run: restore of the Alpine guest", - &[(DRY_RUNS, "run: restore of the Alpine guest")], - ), - ( - "run, dry run: restore with equal processors", - &[(DRY_RUNS, "run: restore with equal processors")], - ), - ( - "run, dry run: restore ignores the memory", - &[(DRY_RUNS, "run: restore ignores the memory")], - ), - ( - "run, dry run: restore paths", - &[(DRY_RUNS, "run: restore paths")], - ), - ("run, dry run: one share", &[(DRY_RUNS, "run: one share")]), - ( - "run, dry run: one writable share", - &[(DRY_RUNS, "run: one writable share")], - ), - ( - "run, dry run: one relative share", - &[(DRY_RUNS, "run: one relative share")], - ), - ( - "run, dry run: one share with relative policy paths", - &[(DRY_RUNS, "run: one share with relative policy paths")], - ), - ( - "run, dry run: policy paths without a share", - &[(DRY_RUNS, "run: policy paths without a share")], - ), - ( - "run, dry run: several shares with policy paths", - &[(DRY_RUNS, "run: several shares with policy paths")], - ), - ( - "run, dry run: several shares with a command line", - &[(DRY_RUNS, "run: several shares with a command line")], - ), - ( - "run, dry run: one shared file", - &[(DRY_RUNS, "run: one shared file")], - ), - ( - "run, dry run: one relative shared file", - &[(DRY_RUNS, "run: one relative shared file")], - ), - ( - "run, dry run: a directory and a file", - &[(DRY_RUNS, "run: a directory and a file")], - ), - ( - "run, dry run: host paths with commas", - &[(DRY_RUNS, "run: host paths with commas")], - ), - ( - "run, dry run: one directory with commas", - &[(DRY_RUNS, "run: one directory with commas")], - ), - ( - "run, dry run: host path ending in a mode", - &[(DRY_RUNS, "run: host path ending in a mode")], - ), - ( - "run, dry run: host path ending in a comma", - &[(DRY_RUNS, "run: host path ending in a comma")], - ), - ("run, dry run: vmm owner", &[(DRY_RUNS, "run: vmm owner")]), - ( - "run, dry run: vmm owner of several shares", - &[(DRY_RUNS, "run: vmm owner of several shares")], - ), - ( - "run, dry run: restore with shares", - &[(DRY_RUNS, "run: restore with shares")], - ), - ( - "run, dry run: restore with shares and a command line", - &[(DRY_RUNS, "run: restore with shares and a command line")], - ), - ("run, dry run: network", &[(DRY_RUNS, "run: network")]), - ( - "run, dry run: egress default", - &[(DRY_RUNS, "run: egress default")], - ), - ( - "run, dry run: host loopback forward", - &[(DRY_RUNS, "run: host loopback forward")], - ), - ( - "run, dry run: egress policy file", - &[(DRY_RUNS, "run: egress policy file")], - ), - ( - "run, dry run: empty egress policy file", - &[(DRY_RUNS, "run: empty egress policy file")], - ), - ( - "run, dry run: outcome report path", - &[(DRY_RUNS, "run: outcome report path")], - ), - ( - "run, dry run: quoted command line", - &[(DRY_RUNS, "run: quoted command line")], - ), - ( - "run, dry run: command line starting with a dash", - &[(DRY_RUNS, "run: command line starting with a dash")], - ), - ( - "run, dry run: command line of help", - &[(DRY_RUNS, "run: command line of help")], - ), - ( - "run, dry run: empty command line", - &[(DRY_RUNS, "run: empty command line")], - ), - ( - "run, dry run: blank command line", - &[(DRY_RUNS, "run: blank command line")], - ), - ( - "run, dry run: last command line", - &[(DRY_RUNS, "run: last command line")], - ), - ( - "run, dry run: long command line of one directory share", - &[(DRY_RUNS, "run: long command line of one directory share")], - ), - ( - "run, dry run: restore without the budget", - &[(DRY_RUNS, "run: restore without the budget")], - ), - ( - "run, dry run: budget fits", - &[(DRY_RUNS, "run: budget fits")], - ), - ( - "run, dry run: caller owner", - &[(DRY_RUNS, "run: caller owner")], - ), - ("run, launch: boot", &[(ONE_SHOT, "run: boot")]), - ( - "run, launch: exit status", - &[(ONE_SHOT, "run: exit status")], - ), - ( - "run, launch: failed boot", - &[(ONE_SHOT, "run: failed boot")], - ), - ("run, launch: Ubuntu", &[(ONE_SHOT, "run: Ubuntu")]), - ( - "run, launch: every boot option", - &[(ONE_SHOT, "run: every boot option")], - ), - ("run, launch: restore", &[(ONE_SHOT, "run: restore")]), - ( - "run, launch: restore without guest artifacts", - &[(ONE_SHOT, "run: restore without guest artifacts")], - ), - ( - "run, launch: missing snapshot", - &[(ONE_SHOT, "run: missing snapshot")], - ), - ( - "run, launch: outcome report", - &[(ONE_SHOT, "run: outcome report")], - ), - ( - "run, launch: restore outcome report", - &[(ONE_SHOT, "run: restore outcome report")], - ), - ( - "run, launch: network outcome report", - &[(ONE_SHOT, "run: network outcome report")], - ), - ("run, launch: one share", &[(ONE_SHOT, "run: one share")]), - ( - "run, launch: several shares and a file", - &[(ONE_SHOT, "run: several shares and a file")], - ), - ( - "run, launch: OpenVMM refuses its options", - &[(ONE_SHOT, "run: OpenVMM refuses its options")], - ), - ( - "run, launch: relative OpenVMM override", - &[(ONE_SHOT, "run: relative OpenVMM override")], - ), - ( - "run, launch: missing OpenVMM", - &[(VALIDATION, "run: missing OpenVMM at launch")], - ), - ( - "run, launch: missing kernel", - &[(VALIDATION, "run: missing kernel at launch")], - ), - ( - "run, launch: missing initramfs", - &[(VALIDATION, "run: missing initramfs at launch")], - ), - ( - "run, launch: missing Ubuntu initramfs", - &[(VALIDATION, "run: missing Ubuntu initramfs at launch")], - ), - ( - "validation: caller-owned share on Windows", - &[(VALIDATION, "caller-owned share on Windows")], - ), - ( - "run, validation: caller owner on Windows", - &[(VALIDATION, "run: caller owner on Windows")], - ), -]; - -/// The regressions that microsoft/nvx#722 traces and the tests of this crate guard against, by -/// their issues: of the managed sandbox, of its executions, and of the egress policies. -const REGRESSIONS: &[Mapping] = &[ - // A record that names the ID of a process that is not its OpenVMM. - ( - "microsoft/nvx#369", - &[ - (REFUSALS, "recycled process ID"), - ( - "a_stop_under_another_identity_never_ends_a_process_that_its_record_does_not_name", - "", - ), - ( - "a_sandbox_whose_openvmm_exited_reports_it_once_and_starts_again", - "", - ), - ], - ), - // `--dry-run` of a lifecycle operation, and the `PWD` of the environment that the sandbox - // agent gives a workload in a working directory. - ( - "microsoft/nvx#373", - &[ - (VALIDATION, "dry run outside run"), - (REFUSALS, "dry runs of lifecycle operations"), - ( - "sandbox_launch_runs_the_workload_itself_through_its_entry", - "", - ), - ], - ), - // A scoped IPv6 range whose host bits normalization drops. - ("microsoft/nvx#462", &[(EGRESS, "scoped IPv6 range")]), - // Concurrent starts, and a request that the control endpoint does not read. - ( - "microsoft/nvx#464", - &[ - (REFUSALS, "concurrent starts"), - ( - "request_to_a_stalled_endpoint_times_out_and_closes_the_session", - "", - ), - ], - ), -]; - -/// The regressions that microsoft/nvx#722 traces and checks in other parts of the repository -/// guard against, by their issues, with each check by the path of its source in the repository -/// and a fragment that only it holds. The package of this crate lacks those sources, so the -/// mapping test reads them at run time, from a checkout. -const ELSEWHERE: &[(&str, &[(&str, &str)])] = &[ - // The `PWD` that a real guest gives a workload in a working directory: the - // `managed-exec-config` microVM scenario checks it with `/usr/bin/env`, which, unlike a - // shell, exports no `PWD` of its own. - ( - "microsoft/nvx#373", - &[( - "scripts/nvx_tools/managed_exec_tests.py", - "public managed environment did not point PWD at the", - )], - ), - // An asynchronous collection of output that the workload's timeout ends, as a synchronous - // one does, also when the workload fills a stream that the caller does not read. - ( - "microsoft/nvx#513", - &[( - "aci_edge_sandboxes/tests/async_api.rs", - "fn async_wait_with_output_honors_the_workload_timeout(", - )], - ), -]; - -/// Returns the names of the cases of the table of each test that has one, by the name of the test. -fn inventory() -> BTreeMap<&'static str, Vec<&'static str>> { - BTreeMap::from([ - ( - USAGE, - usage::USAGE_ERRORS.iter().map(|case| case.name).collect(), - ), - (HELP, usage::HELP.iter().map(|case| case.name).collect()), - ( - VALIDATION, - validation::sandbox_refusals() - .into_iter() - .chain(validation::run_refusals()) - .map(|case| case.name) - .collect(), - ), - ( - DRY_RUNS, - dry_run::sandbox_dry_runs() - .into_iter() - .chain(dry_run::run_dry_runs()) - .map(|case| case.name) - .collect(), - ), - ( - ONE_SHOT, - one_shot::sandbox_launches() - .into_iter() - .chain(one_shot::run_launches()) - .map(|case| case.name) - .collect(), - ), - ( - LIFECYCLES, - lifecycle::configurations() - .into_iter() - .map(|case| case.name) - .collect(), - ), - ( - EXECS, - lifecycle::executions() - .into_iter() - .map(|case| case.name) - .collect(), - ), - ( - REFUSALS, - lifecycle::REFUSALS.iter().map(|(name, _)| *name).collect(), - ), - ( - EGRESS, - egress::COMPILATIONS.iter().map(|case| case.name).collect(), - ), - ( - ARTIFACTS, - artifacts::LISTINGS.iter().map(|case| case.name).collect(), - ), - ]) -} - -#[test] -fn every_recorded_scenario_maps_to_a_test() { - let fixture: Value = serde_json::from_str(crate::FIXTURE).unwrap(); - let mut recorded: Vec<&str> = Vec::new(); - for platform in ["posix", "windows"] { - for scenario in fixture[platform].as_array().unwrap() { - let name = scenario["name"].as_str().unwrap(); - if !recorded.contains(&name) { - recorded.push(name); - } - } - } - let mapped: Vec<&str> = SCENARIOS.iter().map(|(name, _)| *name).collect(); - let unmapped: Vec<&&str> = recorded - .iter() - .filter(|name| !mapped.contains(name)) - .collect(); - assert!( - unmapped.is_empty(), - "scenarios that map to no test: {unmapped:?}" - ); - let unrecorded: Vec<&&str> = mapped - .iter() - .filter(|name| !recorded.contains(name)) - .collect(); - assert!( - unrecorded.is_empty(), - "mapped scenarios that the fixture lacks: {unrecorded:?}" - ); - assert_eq!( - mapped.len(), - recorded.len(), - "a scenario maps more than once" - ); - let inventory = inventory(); - for (test, cases) in &inventory { - let mut names = cases.clone(); - names.sort_unstable(); - names.dedup(); - assert_eq!(names.len(), cases.len(), "{test} names a case twice"); - } - for (name, tests) in SCENARIOS.iter().chain(REGRESSIONS) { - assert!(!tests.is_empty(), "{name} maps to no test"); - for (test, case) in *tests { - let defining = SOURCES - .iter() - .filter(|source| source.contains(&format!("fn {test}("))) - .count(); - assert_eq!(defining, 1, "{name}: no test {test}"); - match inventory.get(test) { - Some(cases) => assert!(cases.contains(case), "{name}: {test} has no case {case:?}"), - None => assert!(case.is_empty(), "{name}: {test} has no table of cases"), - } - } - } - // A checkout holds the release manifest at its root, and the other parts of the repository, - // which the package of this crate lacks. - let repository = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap(); - if repository.join(MANIFEST_NAME).is_file() { - for (name, checks) in ELSEWHERE { - for (path, fragment) in *checks { - let path = repository.join(path); - let source = fs::read_to_string(&path) - .unwrap_or_else(|error| panic!("cannot read {}: {error}", path.display())); - assert_eq!( - source.matches(fragment).count(), - 1, - "{name}: {} does not hold {fragment:?} once", - path.display() - ); - } - } - } -} diff --git a/nvx-rs/tests/cli/usage.rs b/nvx-rs/tests/cli/usage.rs index 0bf19dabb..24a48df04 100644 --- a/nvx-rs/tests/cli/usage.rs +++ b/nvx-rs/tests/cli/usage.rs @@ -1,11 +1,15 @@ //! The usage errors of the parsers of `nvx-rs sandbox` and `nvx-rs run`, and their help. -use crate::harness::{LAYER, Root, SCRATCH}; +use crate::harness::{LAYER, LINE_END, Root, SCRATCH}; + +/// The help of `nvx-rs run`, which `nvx.py run` prints too, since it parses the options of +/// `nvx-rs run` before it runs it: a test of `nvx.py` checks its help against this one. +const RUN_HELP: &str = include_str!("../fixtures/run-help.txt"); /// A command line that a parser of `nvx-rs` refuses. -pub(crate) struct UsageError { +struct UsageError { /// The name of the case. - pub(crate) name: &'static str, + name: &'static str, /// The arguments after `--root ROOT`, with placeholders. arguments: &'static [&'static str], /// The code of the error: `argument-unrecognized`, `argument-missing`, or `argument-invalid`. @@ -16,7 +20,7 @@ pub(crate) struct UsageError { } /// The command lines that the parsers refuse before they check anything else. -pub(crate) const USAGE_ERRORS: &[UsageError] = &[ +const USAGE_ERRORS: &[UsageError] = &[ UsageError { name: "timeout not a number", arguments: &["sandbox", "--timeout", "x"], @@ -447,9 +451,9 @@ fn usage_errors_exit_2_and_name_the_option() { } /// A command line that asks a parser for its help, and options that the help describes. -pub(crate) struct Help { +struct Help { /// The name of the case. - pub(crate) name: &'static str, + name: &'static str, /// The arguments after `--root ROOT`. arguments: &'static [&'static str], /// How its usage starts. @@ -460,7 +464,7 @@ pub(crate) struct Help { /// The command lines that print help, which comes before any value that the parser would refuse /// after it. -pub(crate) const HELP: [Help; 5] = [ +const HELP: [Help; 5] = [ Help { name: "sandbox", arguments: &["sandbox", "-h"], @@ -510,7 +514,7 @@ fn help_prints_the_usage_and_the_options_and_exits_0() { let help = outcome.stdout(); assert!(help.starts_with(case.usage), "{}: {help}", case.name); assert!( - help.contains("\n -h, --help ") && help.ends_with(crate::harness::LINE_END), + help.contains("\n -h, --help ") && help.ends_with(LINE_END), "{}: {help}", case.name ); @@ -523,3 +527,10 @@ fn help_prints_the_usage_and_the_options_and_exits_0() { } } } + +#[test] +fn run_prints_the_help_of_nvx_py_run() { + let outcome = Root::new().nvx_rs(&["run", "--help"]); + outcome.assert_success(); + assert_eq!(outcome.stdout(), RUN_HELP.replace('\n', LINE_END)); +} diff --git a/nvx-rs/tests/cli/validation.rs b/nvx-rs/tests/cli/validation.rs index 2b1ced192..3eb710038 100644 --- a/nvx-rs/tests/cli/validation.rs +++ b/nvx-rs/tests/cli/validation.rs @@ -30,9 +30,9 @@ const PACKAGELESS_MANIFEST: Content = Content::Text( const INITRAMFS: Content = Content::Text("initramfs\n"); /// A command line that fails a check before it changes anything. -pub(crate) struct Refusal { +struct Refusal { /// The name of the case. - pub(crate) name: &'static str, + name: &'static str, /// The hosts that refuse it. hosts: Hosts, /// The files that the case writes below the root first, with their contents. @@ -131,7 +131,7 @@ fn shares(count: usize) -> Vec { } /// Returns the refusals of `nvx-rs sandbox`. -pub(crate) fn sandbox_refusals() -> Vec { +fn sandbox_refusals() -> Vec { let network_outside = &["network policy options are only valid for sandbox run or provision"][..]; let exec_options = &["managed execution options", "sandbox exec"][..]; @@ -668,7 +668,7 @@ pub(crate) fn sandbox_refusals() -> Vec { } /// Returns the refusals of `nvx-rs run`. -pub(crate) fn run_refusals() -> Vec { +fn run_refusals() -> Vec { let targets = "with several shares, or a shared file"; let budget = &["--mount", "--cmdline", "1024"][..]; let two_shares = |cmdline: &str| { @@ -806,6 +806,7 @@ pub(crate) fn run_refusals() -> Vec { ], ) .with_file("policy.json", POLICY), + // The refusal names the file as it was given, without normalizing its path. refusal( "run: policy file missing", "io", @@ -815,7 +816,7 @@ pub(crate) fn run_refusals() -> Vec { "--network-egress-policy-file", "{root/./missing.json}", ]), - &["egress policy file", "{root/missing.json}"], + &["egress policy file", "{root/./missing.json}"], ), refusal( "run: policy file directory", diff --git a/nvx-rs/tests/fixtures/cli.json b/nvx-rs/tests/fixtures/cli.json deleted file mode 100644 index 4d05ac87d..000000000 --- a/nvx-rs/tests/fixtures/cli.json +++ /dev/null @@ -1,652 +0,0 @@ -{ -"generator": "scripts/nvx_rs_fixtures.py and scripts/nvx_rs_run_fixtures.py, retired by microsoft/nvx#359 and microsoft/nvx#638", -"python": "3.14", -"tree": [ -{"path":"build/vmlinux","text":"kernel\n"}, -{"path":"build/initramfs.cpio.gz","text":"initramfs\n"}, -{"path":"build/openvmm.provenance.json","text":"{\n \"format\": 1,\n \"executable_sha256\": \"1e8c924cdaac227bf74b4a4a9bcdb9e8836a1355fd0408cc81dab5d9aa71eb4d\"\n}\n"}, -{"path":"build/vmlinux.provenance.json","text":"{\n \"format\": 1,\n \"kernel_sha256\": \"a0c936696eb7d5ee3192bf53b9d281cecbb40ca9db520de72cb95817ad92ac72\"\n}\n"}, -{"path":"build/initramfs.provenance.json","text":"{\n \"format\": 1,\n \"initramfs_sha256\": \"2f77c2c97621e8bf69794e9d12815bb7c46338638f126bea8b18dfe02a684d62\"\n}\n"}, -{"path":"distro.erofs","text":"distro\n"}, -{"path":"runtime.erofs","text":"runtime\n"}, -{"path":"custom.erofs","text":"custom\n"}, -{"path":"scratch.ext4","text":"scratch\n"}, -{"path":"share/file.txt","text":"file\n"}, -{"path":"share/sub/data.txt","text":"data\n"}, -{"path":"share/hidden/shown/data.txt","text":"data\n"}, -{"path":"share/writable/data.txt","text":"data\n"}, -{"path":"share2/data.txt","text":"data\n"}, -{"path":"single.txt","text":"single\n"}, -{"path":"reports"}, -{"path":"openvmm/target/release/openvmm{exe}","openvmm":true} -], -"posix": [ -{"name":"egress compile: empty","steps":[{"argv":["egress","compile","{root}/policy.json"],"write":{"policy.json":"{}"},"status":0,"stdout":"{\n \"allow\": [],\n \"deny\": []\n}\n","stderr":""}]}, -{"name":"egress compile: allow","steps":[{"argv":["egress","compile","{root}/policy.json"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\"}]}"},"status":0,"stdout":"{\n \"allow\": [\n \"192.0.2.0/24\"\n ],\n \"deny\": []\n}\n","stderr":""}]}, -{"name":"egress compile: both","steps":[{"argv":["egress","compile","{root}/policy.json"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"except\": [\"192.0.2.128/25\"]}, {\"to\": [{\"cidr\": \"2001:db8::/32\"}], \"ports\": [{\"protocol\": \"tcp\", \"port\": 80, \"endPort\": 81}]}], \"deny\": [{\"cidr\": \"198.51.100.0/24\", \"protocol\": \"icmp\"}]}"},"status":0,"stdout":"{\n \"allow\": [\n \"192.0.2.0/25\",\n \"2001:db8::/32:tcp:80-81\"\n ],\n \"deny\": [\n \"198.51.100.0/24:icmp\"\n ]\n}\n","stderr":""}]}, -{"name":"egress compile: invalid JSON","steps":[{"argv":["egress","compile","{root}/policy.json"],"write":{"policy.json":"{"},"status":1,"stdout":"","stderr":"error[unsupported]: egress policy file {root}/policy.json is not valid JSON: EOF while parsing an object at line 1 column 1\n"}]}, -{"name":"egress compile: invalid rule","steps":[{"argv":["egress","compile","{root}/policy.json"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"port\": 70000}]}"},"status":1,"stdout":"","stderr":"error[unsupported]: allow[0].port requires protocol\n"}]}, -{"name":"egress compile: unknown field","steps":[{"argv":["egress","compile","{root}/policy.json"],"write":{"policy.json":"{\"allow\": [], \"other\": []}"},"status":1,"stdout":"","stderr":"error[unsupported]: egress policy has unknown field \"other\"\n"}]}, -{"name":"egress compile: missing file","steps":[{"argv":["egress","compile","{root}/missing.json"],"status":1,"stdout":"","stderr":"error[io]: failed to read egress policy file: {root}/missing.json\n"}]}, -{"name":"egress compile: directory","steps":[{"argv":["egress","compile","{root}/share"],"status":1,"stdout":"","stderr":"error[io]: failed to read egress policy file: {root}/share\n"}]}, -{"name":"artifacts: checkout","steps":[{"argv":["artifacts"],"status":0,"stdout":"{\n \"guests\": [\n {\n \"distribution\": \"Alpine Linux\",\n \"distro_layer\": null,\n \"distro_manifest\": null,\n \"initramfs\": \"{root}/build/initramfs.cpio.gz\",\n \"name\": \"alpine\",\n \"package_manifest\": \"{root}/build/initramfs.cpio.gz.packages.json\"\n },\n {\n \"distribution\": \"Ubuntu Base\",\n \"distro_layer\": \"{root}/build/ubuntu-distro.erofs\",\n \"distro_manifest\": \"{root}/build/ubuntu-distro.erofs.manifest.json\",\n \"initramfs\": \"{root}/build/initramfs-ubuntu.cpio.gz\",\n \"name\": \"ubuntu\",\n \"package_manifest\": \"{root}/build/initramfs-ubuntu.cpio.gz.packages.json\"\n },\n {\n \"distribution\": \"Azure Linux\",\n \"distro_layer\": null,\n \"distro_manifest\": null,\n \"initramfs\": \"{root}/build/initramfs-azurelinux.cpio.gz\",\n \"name\": \"azurelinux\",\n \"package_manifest\": \"{root}/build/initramfs-azurelinux.cpio.gz.packages.json\"\n }\n ],\n \"kernel\": \"{root}/build/vmlinux\",\n \"layout\": \"repository\",\n \"openvmm\": \"{root}/openvmm/target/release/openvmm\",\n \"root\": \"{root}\"\n}\n","stderr":""}]}, -{"name":"artifacts: OpenVMM override","steps":[{"argv":["artifacts"],"env":{"NVX_OPENVMM":"{root}/alt/openvmm{exe}"},"status":0,"stdout":"{\n \"guests\": [\n {\n \"distribution\": \"Alpine Linux\",\n \"distro_layer\": null,\n \"distro_manifest\": null,\n \"initramfs\": \"{root}/build/initramfs.cpio.gz\",\n \"name\": \"alpine\",\n \"package_manifest\": \"{root}/build/initramfs.cpio.gz.packages.json\"\n },\n {\n \"distribution\": \"Ubuntu Base\",\n \"distro_layer\": \"{root}/build/ubuntu-distro.erofs\",\n \"distro_manifest\": \"{root}/build/ubuntu-distro.erofs.manifest.json\",\n \"initramfs\": \"{root}/build/initramfs-ubuntu.cpio.gz\",\n \"name\": \"ubuntu\",\n \"package_manifest\": \"{root}/build/initramfs-ubuntu.cpio.gz.packages.json\"\n },\n {\n \"distribution\": \"Azure Linux\",\n \"distro_layer\": null,\n \"distro_manifest\": null,\n \"initramfs\": \"{root}/build/initramfs-azurelinux.cpio.gz\",\n \"name\": \"azurelinux\",\n \"package_manifest\": \"{root}/build/initramfs-azurelinux.cpio.gz.packages.json\"\n }\n ],\n \"kernel\": \"{root}/build/vmlinux\",\n \"layout\": \"repository\",\n \"openvmm\": \"{root}/alt/openvmm\",\n \"root\": \"{root}\"\n}\n","stderr":""}]}, -{"name":"usage: help","steps":[{"argv":["sandbox","-h"],"status":0,"stdout":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\n\npositional arguments:\n {run,provision,start,exec,stop,deprovision}\n\noptions:\n -h, --help show this help message and exit\n --layer ROLE,PATH,EROFS_UUID\n --scratch SCRATCH\n --state-dir STATE_DIR\n --entrypoint ENTRYPOINT\n --arg SANDBOX_ARG\n --hostname HOSTNAME\n --workload-user UID:GID\n fixed non-root workload identity (default:\n 65534:65534)\n --memory-max MEMORY_MAX\n --pids-max PIDS_MAX\n --memory-mib MEMORY_MIB\n --timeout TIMEOUT control operation timeout, and the longest wait for\n another lifecycle transition of the sandbox, in\n seconds (default: 60)\n --exec-timeout-ms EXEC_TIMEOUT_MS\n guest workload timeout in milliseconds; zero disables\n it\n --cwd CWD absolute guest working directory for managed exec\n (default: /)\n --environment KEY=VALUE\n set the exact managed exec environment; repeat for\n multiple entries\n --environment-file PATH\n read the exact managed exec environment from a JSON\n string array\n --inherit-default-environment\n layer the managed exec environment over the guest\n default environment instead of replacing it\n --hypervisor {auto,whp,kvm,mshv}\n --mount GUEST_TARGET,HOST_PATH[,ro|rw]\n live-share a host directory, or a single regular host\n file without its directory, inside the container\n rootfs; the mode follows the last comma, so HOST_PATH\n may contain commas when the mode is given; repeat to\n attach more shares, each with its own target and mode,\n as children of one virtio-fs device\n --mount-deny HOST_PATH\n hide one existing path inside a --mount host\n directory; with several --mount options, it applies to\n the --mount before it\n --mount-allow HOST_PATH\n expose one existing path inside a --mount-deny path of\n the same share again; the hidden directories on the\n way list only it\n --mount-write HOST_PATH\n make one existing path one of the only writable parts\n of a read-write --mount; the rest of the share is\n read-only\n --mount-owner {vmm,caller}\n host identity of the share's file operations: vmm\n (default) or caller, the workload identity with guest\n root squashed to the owner of the shared directory or\n file (Linux only)\n --net IPV4/PREFIX\n --network-profile {portable}\n --network-egress {allow,deny}\n --network-ingress {allow,deny}\n --network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]\n allow guest egress to an IPv4 or IPv6 CIDR, optionally\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\n udp only on PORT or on the inclusive range PORT-PORT;\n repeat to add rules\n --network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]\n deny guest egress to an IPv4 or IPv6 CIDR, optionally\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\n udp only on PORT or on the inclusive range PORT-PORT;\n repeat to add rules\n --network-egress-policy-file PATH\n load bounded IPv4 and IPv6 ranges and rule-local\n exclusions for run/provision\n --host-loopback {allow,deny}\n --network-proxy IPV4:TCP-PORT\n --host-loopback-forward HOST_LOOPBACK_FORWARD\n --outcome-report OUTCOME_REPORT\n write a bounded local JSON outcome report for run or\n exec\n --cmdline CMDLINE\n --dry-run print the one-shot run command without launching it\n","stderr":""}]}, -{"name":"usage: help after operation","steps":[{"argv":["sandbox","exec","--help"],"status":0,"stdout":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\n\npositional arguments:\n {run,provision,start,exec,stop,deprovision}\n\noptions:\n -h, --help show this help message and exit\n --layer ROLE,PATH,EROFS_UUID\n --scratch SCRATCH\n --state-dir STATE_DIR\n --entrypoint ENTRYPOINT\n --arg SANDBOX_ARG\n --hostname HOSTNAME\n --workload-user UID:GID\n fixed non-root workload identity (default:\n 65534:65534)\n --memory-max MEMORY_MAX\n --pids-max PIDS_MAX\n --memory-mib MEMORY_MIB\n --timeout TIMEOUT control operation timeout, and the longest wait for\n another lifecycle transition of the sandbox, in\n seconds (default: 60)\n --exec-timeout-ms EXEC_TIMEOUT_MS\n guest workload timeout in milliseconds; zero disables\n it\n --cwd CWD absolute guest working directory for managed exec\n (default: /)\n --environment KEY=VALUE\n set the exact managed exec environment; repeat for\n multiple entries\n --environment-file PATH\n read the exact managed exec environment from a JSON\n string array\n --inherit-default-environment\n layer the managed exec environment over the guest\n default environment instead of replacing it\n --hypervisor {auto,whp,kvm,mshv}\n --mount GUEST_TARGET,HOST_PATH[,ro|rw]\n live-share a host directory, or a single regular host\n file without its directory, inside the container\n rootfs; the mode follows the last comma, so HOST_PATH\n may contain commas when the mode is given; repeat to\n attach more shares, each with its own target and mode,\n as children of one virtio-fs device\n --mount-deny HOST_PATH\n hide one existing path inside a --mount host\n directory; with several --mount options, it applies to\n the --mount before it\n --mount-allow HOST_PATH\n expose one existing path inside a --mount-deny path of\n the same share again; the hidden directories on the\n way list only it\n --mount-write HOST_PATH\n make one existing path one of the only writable parts\n of a read-write --mount; the rest of the share is\n read-only\n --mount-owner {vmm,caller}\n host identity of the share's file operations: vmm\n (default) or caller, the workload identity with guest\n root squashed to the owner of the shared directory or\n file (Linux only)\n --net IPV4/PREFIX\n --network-profile {portable}\n --network-egress {allow,deny}\n --network-ingress {allow,deny}\n --network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]\n allow guest egress to an IPv4 or IPv6 CIDR, optionally\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\n udp only on PORT or on the inclusive range PORT-PORT;\n repeat to add rules\n --network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]\n deny guest egress to an IPv4 or IPv6 CIDR, optionally\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\n udp only on PORT or on the inclusive range PORT-PORT;\n repeat to add rules\n --network-egress-policy-file PATH\n load bounded IPv4 and IPv6 ranges and rule-local\n exclusions for run/provision\n --host-loopback {allow,deny}\n --network-proxy IPV4:TCP-PORT\n --host-loopback-forward HOST_LOOPBACK_FORWARD\n --outcome-report OUTCOME_REPORT\n write a bounded local JSON outcome report for run or\n exec\n --cmdline CMDLINE\n --dry-run print the one-shot run command without launching it\n","stderr":""}]}, -{"name":"usage: timeout not a number","steps":[{"argv":["sandbox","--timeout","x"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --timeout: invalid positive_float value: 'x'\n"}]}, -{"name":"usage: zero timeout","steps":[{"argv":["sandbox","--timeout","0"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --timeout: must be finite and greater than 0\n"}]}, -{"name":"usage: negative timeout","steps":[{"argv":["sandbox","--timeout","-1"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --timeout: must be finite and greater than 0\n"}]}, -{"name":"usage: infinite timeout","steps":[{"argv":["sandbox","--timeout","inf"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --timeout: must be finite and greater than 0\n"}]}, -{"name":"usage: timeout not finite","steps":[{"argv":["sandbox","--timeout=1e400"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --timeout: must be finite and greater than 0\n"}]}, -{"name":"usage: timeout not a number either","steps":[{"argv":["sandbox","--timeout","nan"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --timeout: must be finite and greater than 0\n"}]}, -{"name":"usage: exec timeout not an integer","steps":[{"argv":["sandbox","--exec-timeout-ms","1.5"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --exec-timeout-ms: invalid int value: '1.5'\n"}]}, -{"name":"usage: memory not an integer","steps":[{"argv":["sandbox","--memory-mib","x"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --memory-mib: invalid int value: 'x'\n"}]}, -{"name":"usage: invalid hypervisor","steps":[{"argv":["sandbox","--hypervisor","hyperv"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --hypervisor: invalid choice: 'hyperv' (choose from 'auto', 'whp', 'kvm', 'mshv')\n"}]}, -{"name":"usage: invalid operation","steps":[{"argv":["sandbox","restart"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument sandbox_operation: invalid choice: 'restart' (choose from 'run', 'provision', 'start', 'exec', 'stop', 'deprovision')\n"}]}, -{"name":"usage: second operation","steps":[{"argv":["sandbox","run","start"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\n {artifacts,egress,run,sandbox} ...\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: start\n"}]}, -{"name":"usage: invalid mount owner","steps":[{"argv":["sandbox","--mount-owner","root"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --mount-owner: invalid choice: 'root' (choose from 'vmm', 'caller')\n"}]}, -{"name":"usage: invalid network profile","steps":[{"argv":["sandbox","--network-profile","open"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --network-profile: invalid choice: 'open' (choose from 'portable')\n"}]}, -{"name":"usage: invalid egress default","steps":[{"argv":["sandbox","--network-egress","block"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --network-egress: invalid choice: 'block' (choose from 'allow', 'deny')\n"}]}, -{"name":"usage: invalid host loopback","steps":[{"argv":["sandbox","--host-loopback","yes"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --host-loopback: invalid choice: 'yes' (choose from 'allow', 'deny')\n"}]}, -{"name":"usage: missing value","steps":[{"argv":["sandbox","--layer"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-missing]: argument --layer: expected one argument\n"}]}, -{"name":"usage: option as value","steps":[{"argv":["sandbox","--layer","--scratch"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-missing]: argument --layer: expected one argument\n"}]}, -{"name":"usage: dash value","steps":[{"argv":["sandbox","--arg","-x"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-missing]: argument --arg: expected one argument\n"}]}, -{"name":"usage: flag with value","steps":[{"argv":["sandbox","--dry-run=1"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --dry-run: ignored explicit argument '1'\n"}]}, -{"name":"usage: unrecognized option","steps":[{"argv":["sandbox","--bogus"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\n {artifacts,egress,run,sandbox} ...\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: --bogus\n"}]}, -{"name":"usage: unrecognized short option","steps":[{"argv":["sandbox","-x"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\n {artifacts,egress,run,sandbox} ...\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: -x\n"}]}, -{"name":"usage: unrecognized after separator","steps":[{"argv":["sandbox","run","--","extra"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\n {artifacts,egress,run,sandbox} ...\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: extra\n"}]}, -{"name":"validation: dry run outside run","steps":[{"argv":["sandbox","provision","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --dry-run is only valid for sandbox run\n"}]}, -{"name":"validation: environment and environment file","steps":[{"argv":["sandbox","exec","--environment","A=1","--environment-file","{root}/env.json"],"write":{"env.json":"[\"A=1\"]"},"status":1,"stdout":"","stderr":"error[unsupported]: --environment and --environment-file are mutually exclusive\n"}]}, -{"name":"validation: cwd outside exec","steps":[{"argv":["sandbox","run","--cwd","/"],"status":1,"stdout":"","stderr":"error[unsupported]: managed execution options require the sandbox exec operation\n"}]}, -{"name":"validation: environment outside exec","steps":[{"argv":["sandbox","start","--environment","A=1"],"status":1,"stdout":"","stderr":"error[unsupported]: managed execution options require the sandbox exec operation\n"}]}, -{"name":"validation: environment file outside exec","steps":[{"argv":["sandbox","provision","--environment-file","{root}/env.json"],"write":{"env.json":"[\"A=1\"]"},"status":1,"stdout":"","stderr":"error[unsupported]: managed execution options require the sandbox exec operation\n"}]}, -{"name":"validation: inherited environment outside exec","steps":[{"argv":["sandbox","stop","--inherit-default-environment"],"status":1,"stdout":"","stderr":"error[unsupported]: managed execution options require the sandbox exec operation\n"}]}, -{"name":"validation: environment file too large","steps":[{"argv":["sandbox","exec","--environment-file","{root}/env.json"],"write":{"env.json":{"fill":" ","size":1048577}},"status":1,"stdout":"","stderr":"error[unsupported]: managed execution environment file exceeds 1048576-byte limit\n"}]}, -{"name":"validation: environment file at the limit","steps":[{"argv":["sandbox","exec","--environment-file","{root}/env.json"],"write":{"env.json":{"text":"[\"A=1\"]","fill":" ","size":1048576}},"status":1,"stdout":"","stderr":"error[unsupported]: sandbox exec requires --state-dir\n"}]}, -{"name":"validation: environment file missing","steps":[{"argv":["sandbox","exec","--environment-file","{root}/missing.json"],"status":1,"stdout":"","stderr":"error[unsupported]: failed to read managed execution environment: {root}/missing.json\n"}]}, -{"name":"validation: environment file directory","steps":[{"argv":["sandbox","exec","--environment-file","{root}/share"],"status":1,"stdout":"","stderr":"error[unsupported]: failed to read managed execution environment: {root}/share\n"}]}, -{"name":"validation: environment file not UTF-8","steps":[{"argv":["sandbox","exec","--environment-file","{root}/env.json"],"write":{"env.json":{"hex":"5b22ff225d"}},"status":1,"stdout":"","stderr":"error[unsupported]: failed to read managed execution environment: {root}/env.json\n"}]}, -{"name":"validation: environment file not JSON","steps":[{"argv":["sandbox","exec","--environment-file","{root}/env.json"],"write":{"env.json":"[\"A=1\""},"status":1,"stdout":"","stderr":"error[unsupported]: failed to read managed execution environment: {root}/env.json\n"}]}, -{"name":"validation: environment file object","steps":[{"argv":["sandbox","exec","--environment-file","{root}/env.json"],"write":{"env.json":"{\"A\": \"1\"}"},"status":1,"stdout":"","stderr":"error[unsupported]: managed execution environment file must contain a JSON array of KEY=VALUE strings\n"}]}, -{"name":"validation: environment file non-string","steps":[{"argv":["sandbox","exec","--environment-file","{root}/env.json"],"write":{"env.json":"[\"A=1\", 2]"},"status":1,"stdout":"","stderr":"error[unsupported]: managed execution environment file must contain a JSON array of KEY=VALUE strings\n"}]}, -{"name":"validation: environment file entry without equals","steps":[{"argv":["sandbox","exec","--environment-file","{root}/env.json"],"write":{"env.json":"[\"A\"]"},"status":1,"stdout":"","stderr":"error[unsupported]: managed exec environment entries must be non-empty KEY=VALUE strings of at most 4096 bytes\n"}]}, -{"name":"validation: environment file entry with NUL","steps":[{"argv":["sandbox","exec","--environment-file","{root}/env.json"],"write":{"env.json":"[\"A=\\u0000\"]"},"status":1,"stdout":"","stderr":"error[unsupported]: managed exec environment entries must be non-empty KEY=VALUE strings of at most 4096 bytes\n"}]}, -{"name":"validation: environment file duplicate entry","steps":[{"argv":["sandbox","exec","--environment-file","{root}/env.json"],"write":{"env.json":"[\"A=1\", \"A=2\"]"},"status":1,"stdout":"","stderr":"error[unsupported]: managed exec environment contains duplicate key: A\n"}]}, -{"name":"validation: environment entry without name","steps":[{"argv":["sandbox","exec","--environment","=x"],"status":1,"stdout":"","stderr":"error[unsupported]: managed exec environment entries must be non-empty KEY=VALUE strings of at most 4096 bytes\n"}]}, -{"name":"validation: environment entry with space","steps":[{"argv":["sandbox","exec","--environment","A B=x"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox exec requires --state-dir\n"}]}, -{"name":"validation: network outside run","steps":[{"argv":["sandbox","start","--net","10.0.0.2/24"],"status":1,"stdout":"","stderr":"error[unsupported]: network policy options are only valid for sandbox run or provision\n"}]}, -{"name":"validation: egress rule outside run","steps":[{"argv":["sandbox","exec","--network-egress-allow","10.0.0.0/8"],"status":1,"stdout":"","stderr":"error[unsupported]: network policy options are only valid for sandbox run or provision\n"}]}, -{"name":"validation: forward outside run","steps":[{"argv":["sandbox","stop","--host-loopback-forward","80"],"status":1,"stdout":"","stderr":"error[unsupported]: network policy options are only valid for sandbox run or provision\n"}]}, -{"name":"validation: policy file outside run","steps":[{"argv":["sandbox","deprovision","--network-egress-policy-file","{root}/policy.json"],"status":1,"stdout":"","stderr":"error[unsupported]: network policy options are only valid for sandbox run or provision\n"}]}, -{"name":"validation: systemd entrypoint of run","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--entrypoint","/usr/lib/systemd/systemd"],"status":1,"stdout":"","stderr":"error[unsupported]: systemd entrypoints are unsupported by the sandbox security profile\n"}]}, -{"name":"validation: systemd entrypoint of exec","steps":[{"argv":["sandbox","exec","--entrypoint","/lib/systemd/systemd"],"status":1,"stdout":"","stderr":"error[unsupported]: systemd entrypoints are unsupported by the sandbox security profile\n"}]}, -{"name":"validation: outcome report outside run","steps":[{"argv":["sandbox","provision","--outcome-report","{root}/reports/exec.json"],"status":1,"stdout":"","stderr":"error[unsupported]: --outcome-report is only valid for one-shot run or managed exec\n"}]}, -{"name":"validation: deny without mount","steps":[{"argv":["sandbox","run","--mount-deny","{root}/share/hidden"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-deny requires --mount\n"}]}, -{"name":"validation: allow without mount","steps":[{"argv":["sandbox","run","--mount-allow","{root}/share/hidden"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-allow requires --mount\n"}]}, -{"name":"validation: write without mount","steps":[{"argv":["sandbox","run","--mount-write","{root}/share/writable"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-write requires --mount\n"}]}, -{"name":"validation: owner without mount","steps":[{"argv":["sandbox","run","--mount-owner","vmm"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-owner requires --mount\n"}]}, -{"name":"validation: mount outside run","steps":[{"argv":["sandbox","start","--mount","/data,{root}/share"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount is only valid for sandbox run or provision\n"}]}, -{"name":"validation: net without profile","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--net","10.0.0.2/24"],"status":1,"stdout":"","stderr":"error[unsupported]: --net and --network-profile must be specified together\n"}]}, -{"name":"validation: profile without net","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--network-profile","portable"],"status":1,"stdout":"","stderr":"error[unsupported]: --net and --network-profile must be specified together\n"}]}, -{"name":"validation: run without layers","steps":[{"argv":["sandbox","run"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox run requires --layer and --scratch\n"}]}, -{"name":"validation: provision without scratch","steps":[{"argv":["sandbox","provision","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox provision requires --layer and --scratch\n"}]}, -{"name":"validation: run without layer","steps":[{"argv":["sandbox","run","--scratch","{root}/scratch.ext4"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox run requires --layer and --scratch\n"}]}, -{"name":"validation: policy file with rules","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--network-egress","allow","--network-egress-policy-file","{root}/policy.json","--network-egress-deny","10.0.0.0/8"],"status":1,"stdout":"","stderr":"error[unsupported]: --network-egress-policy-file cannot be combined with --network-egress-allow or --network-egress-deny\n"}]}, -{"name":"validation: policy file without egress","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--network-egress-policy-file","{root}/policy.json"],"status":1,"stdout":"","stderr":"error[unsupported]: --network-egress is required with --network-egress-policy-file\n"}]}, -{"name":"validation: policy file missing","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--network-egress","deny","--network-egress-policy-file","{root}/missing.json"],"status":1,"stdout":"","stderr":"error[io]: failed to read egress policy file: {root}/missing.json\n"}]}, -{"name":"validation: policy file invalid","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--network-egress","deny","--network-egress-policy-file","{root}/policy.json"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"10.0.0.0/8\", \"port\": 0}]}"},"status":1,"stdout":"","stderr":"error[unsupported]: allow[0].port requires protocol\n"}]}, -{"name":"validation: provision without state directory","steps":[{"argv":["sandbox","provision","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox provision requires --state-dir\n"}]}, -{"name":"validation: start without state directory","steps":[{"argv":["sandbox","start"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox start requires --state-dir\n"}]}, -{"name":"validation: exec without state directory","steps":[{"argv":["sandbox","exec"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox exec requires --state-dir\n"}]}, -{"name":"validation: stop without state directory","steps":[{"argv":["sandbox","stop"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox stop requires --state-dir\n"}]}, -{"name":"validation: deprovision without state directory","steps":[{"argv":["sandbox","deprovision"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox deprovision requires --state-dir\n"}]}, -{"name":"validation: run with state directory","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--state-dir","{root}/state"],"status":1,"stdout":"","stderr":"error[unsupported]: one-shot sandbox execution rejects persistent --state-dir settings\n"}]}, -{"name":"validation: invalid layer UUID","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,nope","--scratch","{root}/scratch.ext4"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --layer: distro layer UUID is invalid: 'nope'\n"}]}, -{"name":"validation: invalid layer role","steps":[{"argv":["sandbox","run","--layer","base,{root}/distro.erofs,11111111-1111-1111-1111-111111111111"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --layer: unsupported layer role 'base'; choose distro\n"}]}, -{"name":"validation: retired layer role","steps":[{"argv":["sandbox","run","--layer","runtime,{root}/runtime.erofs,22222222-2222-2222-2222-222222222222"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --layer: unsupported layer role 'runtime'; choose distro\n"}]}, -{"name":"validation: missing layer","steps":[{"argv":["sandbox","run","--layer","distro,{root}/missing.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"status":1,"stdout":"","stderr":"error[unavailable]: distro EROFS layer not found: {root}/missing.erofs\n"}]}, -{"name":"validation: duplicate layer","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"status":1,"stdout":"","stderr":"error[unsupported]: duplicate sandbox layer role(s): distro\n"}]}, -{"name":"validation: missing scratch","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/missing.ext4"],"status":1,"stdout":"","stderr":"error[unavailable]: ext4 scratch image not found: {root}/missing.ext4\n"}]}, -{"name":"validation: relative entrypoint","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--entrypoint","bin/sh"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox entrypoint must be an absolute path without spaces or quotes\n"}]}, -{"name":"validation: invalid hostname","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--hostname","bad host"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox hostname must be a lowercase RFC 1123 label up to 63 characters\n"}]}, -{"name":"validation: argument with space","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--arg","a b"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox arguments must be nonempty and contain no spaces or quotes\n"}]}, -{"name":"validation: root workload","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--workload-user","0:0"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --workload-user: --workload-user UID must be between 1 and 4294967295\n"}]}, -{"name":"validation: invalid workload user","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--workload-user","x"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --workload-user: --workload-user must be UID:GID\n"}]}, -{"name":"validation: invalid memory limit","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--memory-max","x"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\n [--cwd CWD] [--environment KEY=VALUE]\n [--environment-file PATH]\n [--inherit-default-environment]\n [--hypervisor {auto,whp,kvm,mshv}]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--dry-run]\n [{run,provision,start,exec,stop,deprovision}]\nnvx-rs sandbox: error[argument-invalid]: argument --memory-max: invalid int value: 'x'\n"}]}, -{"name":"validation: invalid process limit","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--pids-max","0"],"status":1,"stdout":"","stderr":"error[unsupported]: --pids-max must be positive\n"}]}, -{"name":"validation: relative mount target","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","data,{root}/share"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid sandbox mount target 'data': expected an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\n"}]}, -{"name":"validation: missing mount host","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/missing"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox mount host path is not a plain directory: {root}/missing\n"}]}, -{"name":"validation: invalid mount mode","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share,rx"],"status":1,"stdout":"","stderr":"error[unsupported]: unsupported --mount mode 'rx'; choose ro or rw (if HOST_PATH contains commas, end the value with ,ro or ,rw)\n"}]}, -{"name":"validation: deny outside share","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share","--mount-deny","{root}/share2"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-deny {root}/share2 is not inside the host directory of --mount /data\n"}]}, -{"name":"validation: allow outside denied path","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share","--mount-allow","{root}/share/hidden/shown"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-allow exposes a path inside a --mount-deny path of the same share, which has none\n"}]}, -{"name":"validation: write in read-only share","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share,ro","--mount-write","{root}/share/writable"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-write narrows the writes of a read-write share; --mount /data is read-only\n"}]}, -{"name":"validation: reserved command-line token","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--cmdline","nvx_sandbox=0"],"status":1,"stdout":"","stderr":"error[unsupported]: nvx_sandbox is owned by the sandbox profile\n"}]}, -{"name":"validation: systemd distro image","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"write":{"distro.erofs.manifest.json":"{\"format\": 1, \"artifact\": \"distro.erofs\", \"artifact_sha256\": \"8a475efd5fd711d481a9a19de6d12b88dff0cd81cb8135ffcd5b65b062c7bf04\", \"packages\": [{\"name\": \"busybox\", \"version\": \"1\"}, {\"name\": \"systemd\", \"version\": \"1\"}]}"},"status":1,"stdout":"","stderr":"error[unsupported]: systemd images are unsupported by the sandbox security profile\n"}]}, -{"name":"validation: mismatched distro manifest","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"write":{"distro.erofs.manifest.json":"{\"format\": 1, \"artifact\": \"distro.erofs\", \"artifact_sha256\": \"0000000000000000000000000000000000000000000000000000000000000000\", \"packages\": []}"},"status":1,"stdout":"","stderr":"error[unsupported]: sandbox distro manifest does not match its artifact\n"}]}, -{"name":"validation: invalid distro manifest","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"write":{"distro.erofs.manifest.json":"{"},"status":1,"stdout":"","stderr":"error[unsupported]: invalid sandbox distro manifest: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)\n"}]}, -{"name":"validation: distro manifest without packages","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"write":{"distro.erofs.manifest.json":"{\"format\": 1, \"artifact\": \"distro.erofs\", \"artifact_sha256\": \"8a475efd5fd711d481a9a19de6d12b88dff0cd81cb8135ffcd5b65b062c7bf04\"}"},"status":1,"stdout":"","stderr":"error[unsupported]: sandbox distro manifest has invalid package metadata\n"}]}, -{"name":"dry run: minimal","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --machine microvm --microvm-sandbox-block distro:file:{root}/distro.erofs,ro --microvm-sandbox-block scratch:file:{root}/scratch.ext4 --microvm-workload-identity 65534:65534 --microvm-lifecycle one-shot --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'\n","stderr":""}]}, -{"name":"dry run: every layer and option","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--entrypoint","/bin/server","--arg=--port","--arg","8080","--hostname","worker","--workload-user","1000:1000","--memory-max","268435456","--pids-max","64","--memory-mib","512","--hypervisor","mshv","--cmdline","quiet loglevel=3","--outcome-report","{root}/reports/openvmm-run.json","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --machine microvm --microvm-sandbox-block distro:file:{root}/distro.erofs,ro --microvm-sandbox-block scratch:file:{root}/scratch.ext4 --microvm-workload-identity 1000:1000 --microvm-lifecycle one-shot --single-process --hypervisor mshv --memory 512M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --cmdline 'quiet loglevel=3 nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/server nvx_hostname=worker nvx_arg=--port nvx_arg=8080 nvx_memory_max=268435456 nvx_pids_max=65' --microvm-report {root}/reports/openvmm-run.json\n","stderr":""}]}, -{"name":"dry run: explicit hypervisor","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--hypervisor","kvm","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --machine microvm --microvm-sandbox-block distro:file:{root}/distro.erofs,ro --microvm-sandbox-block scratch:file:{root}/scratch.ext4 --microvm-workload-identity 65534:65534 --microvm-lifecycle one-shot --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'\n","stderr":""}]}, -{"name":"dry run: one share","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --machine microvm --microvm-sandbox-block distro:file:{root}/distro.erofs,ro --microvm-sandbox-block scratch:file:{root}/scratch.ext4 --microvm-workload-identity 65534:65534 --mount /data,{root}/share,ro --microvm-lifecycle one-shot --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'\n","stderr":""}]}, -{"name":"dry run: writable share","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share,rw","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --machine microvm --microvm-sandbox-block distro:file:{root}/distro.erofs,ro --microvm-sandbox-block scratch:file:{root}/scratch.ext4 --microvm-workload-identity 65534:65534 --mount /data,{root}/share,rw --microvm-lifecycle one-shot --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'\n","stderr":""}]}, -{"name":"dry run: file share","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/etc/single.txt,{root}/single.txt,ro","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --machine microvm --microvm-sandbox-block distro:file:{root}/distro.erofs,ro --microvm-sandbox-block scratch:file:{root}/scratch.ext4 --microvm-workload-identity 65534:65534 --mount-aggregate /run/nvx/shares --mount-child 0-a80a05e9cb129bc27b7ba103bf2f5ac0,{root}/single.txt,ro,file --microvm-lifecycle one-shot --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'\n","stderr":""}]}, -{"name":"dry run: several shares with policies","steps":[{"argv":["sandbox","run","--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","--mount","/other,{root}/share2","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --machine microvm --microvm-sandbox-block distro:file:{root}/distro.erofs,ro --microvm-sandbox-block scratch:file:{root}/scratch.ext4 --microvm-workload-identity 65534:65534 --mount-aggregate /run/nvx/shares --mount-child 0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}/share,rw --mount-child 1-bf2faee2596026620b5cbc997c2d7d45,{root}/share2,ro --mount-deny {root}/share/hidden --mount-allow {root}/share/hidden/shown --mount-write {root}/share/writable --microvm-lifecycle one-shot --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,rw nvx_share=1-bf2faee2596026620b5cbc997c2d7d45,/other,ro'\n","stderr":""}]}, -{"name":"dry run: network","steps":[{"argv":["sandbox","run","--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","--network-ingress","allow","--network-egress-allow","10.0.0.0/8:tcp:443","--network-egress-deny","10.1.0.0/16","--host-loopback","allow","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --machine microvm --microvm-sandbox-block distro:file:{root}/distro.erofs,ro --microvm-sandbox-block scratch:file:{root}/scratch.ext4 --microvm-workload-identity 65534:65534 --net 10.0.0.2/24 --network-profile portable --network-egress deny --network-ingress allow --host-loopback allow --network-egress-allow 10.0.0.0/8:tcp:443 --network-egress-deny 10.1.0.0/16 --microvm-lifecycle one-shot --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'\n","stderr":""}]}, -{"name":"dry run: proxy-only network","steps":[{"argv":["sandbox","run","--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","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --machine microvm --microvm-sandbox-block distro:file:{root}/distro.erofs,ro --microvm-sandbox-block scratch:file:{root}/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 one-shot --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'\n","stderr":""}]}, -{"name":"dry run: egress policy file","steps":[{"argv":["sandbox","run","--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","--network-egress-policy-file","{root}/policy.json","--dry-run"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"except\": [\"192.0.2.128/25\"]}, {\"cidr\": \"2001:db8::/32\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"198.51.100.0/24\", \"protocol\": \"udp\"}]}"},"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --machine microvm --microvm-sandbox-block distro:file:{root}/distro.erofs,ro --microvm-sandbox-block scratch:file:{root}/scratch.ext4 --microvm-workload-identity 65534:65534 --net 10.0.0.2/24 --network-profile portable --network-egress deny --network-ingress deny --network-egress-allow 192.0.2.0/25 --network-egress-allow 2001:db8::/32:tcp:443 --network-egress-deny 198.51.100.0/24:udp --microvm-lifecycle one-shot --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'\n","stderr":""}]}, -{"name":"dry run: quoted arguments","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--cmdline","a=\"b c\" d","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --machine microvm --microvm-sandbox-block distro:file:{root}/distro.erofs,ro --microvm-sandbox-block scratch:file:{root}/scratch.ext4 --microvm-workload-identity 65534:65534 --microvm-lifecycle one-shot --single-process --hypervisor kvm --memory 256M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --cmdline 'a=\"b c\" d 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'\n","stderr":""}]}, -{"name":"dry run: caller-owned share","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--mount","/data,{root}/share","--mount-owner","caller","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --machine microvm --microvm-sandbox-block distro:file:{root}/distro.erofs,ro --microvm-sandbox-block scratch:file:{root}/scratch.ext4 --microvm-workload-identity 65534:65534 --mount /data,{root}/share,ro --mount-owner caller --microvm-lifecycle one-shot --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'\n","stderr":""}]}, -{"name":"run: echo","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--entrypoint","/bin/echo","--arg","hello","--arg","world"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --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 one-shot --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/echo nvx_hostname=nvx-sandbox nvx_arg=hello nvx_arg=world'\nhello world\n","stderr":""}]}, -{"name":"run: default operation","steps":[{"argv":["sandbox","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--entrypoint","/bin/echo","--arg","hello","--arg","world"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --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 one-shot --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/echo nvx_hostname=nvx-sandbox nvx_arg=hello nvx_arg=world'\nhello world\n","stderr":""}]}, -{"name":"run: failure","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--entrypoint","/bin/false"],"status":1,"stdout":">> {root}/openvmm/target/release/openvmm --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 one-shot --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/false nvx_hostname=nvx-sandbox'\n","stderr":""}]}, -{"name":"run: missing program","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--entrypoint","/bin/missing"],"status":127,"stdout":">> {root}/openvmm/target/release/openvmm --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 one-shot --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/missing nvx_hostname=nvx-sandbox'\n","stderr":"openvmm: /bin/missing: not found\n"}]}, -{"name":"run: exit status","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--entrypoint","/bin/true","--cmdline","fake_exit_status=7"],"status":7,"stdout":">> {root}/openvmm/target/release/openvmm --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 one-shot --single-process --hypervisor kvm --memory 256M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --cmdline 'fake_exit_status=7 nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/true nvx_hostname=nvx-sandbox'\n","stderr":""}]}, -{"name":"run: outcome report","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--entrypoint","/bin/echo","--arg","hello","--arg","world","--outcome-report","{root}/reports/openvmm-run.json"],"check":["reports/openvmm-run.json","build/fake-openvmm-reports.json"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --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 one-shot --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/echo nvx_hostname=nvx-sandbox nvx_arg=hello nvx_arg=world' --microvm-report {root}/reports/openvmm-run.json\nhello world\n","stderr":"","files":{"reports/openvmm-run.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\": \"run\",\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"},"build/fake-openvmm-reports.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\",\"one-shot\",\"--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/echo nvx_hostname=nvx-sandbox nvx_arg=hello nvx_arg=world\",\"--microvm-report\",\"{root}/reports/openvmm-run.json\"]"}}}]}, -{"name":"run: network outcome report","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--entrypoint","/bin/true","--net","10.0.0.2/24","--network-profile","portable","--network-egress","deny","--network-egress-allow","10.0.0.0/8:tcp:443","--outcome-report","{root}/reports/openvmm-run.json"],"check":["reports/openvmm-run.json"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --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 --network-egress-allow 10.0.0.0/8:tcp:443 --microvm-lifecycle one-shot --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/true nvx_hostname=nvx-sandbox' --microvm-report {root}/reports/openvmm-run.json\n","stderr":"","files":{"reports/openvmm-run.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 1,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"allow\",\n \"mode\": \"rules\",\n \"status\": \"applied\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"run\",\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"}}}]}, -{"name":"run: network options without --net","steps":[{"argv":["sandbox","run","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--host-loopback-forward","8080"],"status":1,"stdout":"","stderr":"error[unsupported]: network policy options require --net\n"}]}, -{"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[artifact-missing]: 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[artifact-missing]: 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[artifact-missing]: 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","build/fake-openvmm-state-maps.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\"]"},"build/fake-openvmm-state-maps.json":null}},{"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[exec-refused]: 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[unsupported]: 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-exists]: 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[unsupported]: 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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": false,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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","build/fake-openvmm-state-maps.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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": false,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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/hostfs/root\",\"--mount-child\",\"0,{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 nvx_maps=1\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"},"build/fake-openvmm-state-maps.json":{"text":"[{\"source\":\"0\",\"target\":\"/data\",\"read_only\":true,\"directory\":true}]"}}},{"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": false,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": false,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": false,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": true,\n \"write\": []\n }\n ],\n \"owner\": \"caller\"\n },\n \"format\": 7,\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 \"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","build/fake-openvmm-state-maps.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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": true,\n \"write\": []\n }\n ],\n \"owner\": \"caller\"\n },\n \"format\": 7,\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 \"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/hostfs/root\",\"--mount-child\",\"0,{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 nvx_maps=1\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"},"build/fake-openvmm-state-maps.json":{"text":"[{\"source\":\"0\",\"target\":\"/data\",\"read_only\":false,\"directory\":true}]"}}},{"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": true,\n \"write\": []\n }\n ],\n \"owner\": \"caller\"\n },\n \"format\": 7,\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 \"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": true,\n \"write\": []\n }\n ],\n \"owner\": \"caller\"\n },\n \"format\": 7,\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 \"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": true,\n \"write\": []\n }\n ],\n \"owner\": \"caller\"\n },\n \"format\": 7,\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 \"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/data\"\n },\n {\n \"child\": 1,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/other\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": false,\n \"write\": []\n },\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share2\",\n \"writable\": true,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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","build/fake-openvmm-state-maps.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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/data\"\n },\n {\n \"child\": 1,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/other\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": false,\n \"write\": []\n },\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share2\",\n \"writable\": true,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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/hostfs/root\",\"--mount-child\",\"0,{root}/share,ro\",\"--mount-child\",\"1,{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_maps=2\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"},"build/fake-openvmm-state-maps.json":{"text":"[{\"source\":\"0\",\"target\":\"/data\",\"read_only\":true,\"directory\":true},{\"source\":\"1\",\"target\":\"/other\",\"read_only\":false,\"directory\":true}]"}}},{"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/data\"\n },\n {\n \"child\": 1,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/other\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": false,\n \"write\": []\n },\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share2\",\n \"writable\": true,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/data\"\n },\n {\n \"child\": 1,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/other\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": false,\n \"write\": []\n },\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share2\",\n \"writable\": true,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/data\"\n },\n {\n \"child\": 1,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/other\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share\",\n \"writable\": false,\n \"write\": []\n },\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"root\": \"{root}/share2\",\n \"writable\": true,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied\": [\n \"{root}/share/hidden\"\n ],\n \"deniedIdentities\": [\n null\n ],\n \"root\": \"{root}/share\",\n \"writable\": true,\n \"write\": [\n \"{root}/share/writable\"\n ]\n }\n ]\n },\n \"format\": 7,\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 \"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","build/fake-openvmm-state-maps.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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied\": [\n \"{root}/share/hidden\"\n ],\n \"deniedIdentities\": [\n null\n ],\n \"root\": \"{root}/share\",\n \"writable\": true,\n \"write\": [\n \"{root}/share/writable\"\n ]\n }\n ]\n },\n \"format\": 7,\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 \"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/hostfs/root\",\"--mount-child\",\"0,{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 nvx_maps=1\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"},"build/fake-openvmm-state-maps.json":{"text":"[{\"source\":\"0\",\"target\":\"/data\",\"read_only\":false,\"directory\":true}]"}}},{"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied\": [\n \"{root}/share/hidden\"\n ],\n \"deniedIdentities\": [\n null\n ],\n \"root\": \"{root}/share\",\n \"writable\": true,\n \"write\": [\n \"{root}/share/writable\"\n ]\n }\n ]\n },\n \"format\": 7,\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 \"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied\": [\n \"{root}/share/hidden\"\n ],\n \"deniedIdentities\": [\n null\n ],\n \"root\": \"{root}/share\",\n \"writable\": true,\n \"write\": [\n \"{root}/share/writable\"\n ]\n }\n ]\n },\n \"format\": 7,\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 \"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": false,\n \"source\": \"\",\n \"target\": \"/data\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [\n \"{root}/share/hidden/shown\"\n ],\n \"denied\": [\n \"{root}/share/hidden\"\n ],\n \"deniedIdentities\": [\n null\n ],\n \"root\": \"{root}/share\",\n \"writable\": true,\n \"write\": [\n \"{root}/share/writable\"\n ]\n }\n ]\n },\n \"format\": 7,\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 \"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/etc/single.txt\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"file\": true,\n \"root\": \"{root}/single.txt\",\n \"writable\": false,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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","build/fake-openvmm-state-maps.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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/etc/single.txt\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"file\": true,\n \"root\": \"{root}/single.txt\",\n \"writable\": false,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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/hostfs/root\",\"--mount-child\",\"0,{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_maps=1\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen={root}/state/control.sock\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root}/state/outcome.json\"]"},"build/fake-openvmm-state-maps.json":{"text":"[{\"source\":\"0\",\"target\":\"/etc/single.txt\",\"read_only\":true,\"directory\":false}]"}}},{"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/etc/single.txt\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"file\": true,\n \"root\": \"{root}/single.txt\",\n \"writable\": false,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/etc/single.txt\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"file\": true,\n \"root\": \"{root}/single.txt\",\n \"writable\": false,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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 \"export\": {\n \"binds\": [\n {\n \"child\": 0,\n \"readOnly\": true,\n \"source\": \"\",\n \"target\": \"/etc/single.txt\"\n }\n ],\n \"children\": [\n {\n \"allowed\": [],\n \"denied\": [],\n \"deniedIdentities\": [],\n \"file\": true,\n \"root\": \"{root}/single.txt\",\n \"writable\": false,\n \"write\": []\n }\n ]\n },\n \"format\": 7,\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 \"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-not-provisioned]: sandbox state path is not a plain directory: {root}/state\n"},{"argv":["sandbox","exec","--state-dir","{root}/state"],"status":1,"stdout":"","stderr":"error[sandbox-not-provisioned]: sandbox state path is not a plain directory: {root}/state\n"},{"argv":["sandbox","stop","--state-dir","{root}/state"],"status":1,"stdout":"","stderr":"error[sandbox-not-provisioned]: sandbox state path is not a plain directory: {root}/state\n"},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"status":1,"stdout":"","stderr":"error[sandbox-not-provisioned]: 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-provisioned]: 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-running]: sandbox is already running or has stale runtime state\n"},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"status":1,"stdout":"","stderr":"error[sandbox-running]: 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-not-running]: sandbox is not running\n"},{"argv":["sandbox","exec","--state-dir","{root}/state"],"status":1,"stdout":"","stderr":"error[sandbox-not-running]: sandbox is not running\n"},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"state: relative and nested state directory","steps":[{"argv":["sandbox","provision","--state-dir","nested/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"check":["nested/state","nested/state/config.json"],"status":0,"stdout":"","stderr":"","files":{"nested/state":{"entries":["config.json","sandbox.lock"],"mode":448},"nested/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}}},{"argv":["sandbox","deprovision","--state-dir","nested/state"],"check":["nested/state"],"status":0,"stdout":"","stderr":"","files":{"nested/state":null}}]}, -{"name":"state: failed start","steps":[{"argv":["sandbox","provision","--state-dir","{root}/state","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4","--cmdline","fake_exit_on_start=5"],"status":0,"stdout":"","stderr":""},{"argv":["sandbox","start","--state-dir","{root}/state","--timeout","0.5"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":1,"stdout":"","stderr":"error[exited]: OpenVMM exited during startup with status 5\n","files":{"state":{"entries":["config.json","openvmm.log","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"fake_exit_on_start=5\",\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":{"text":"openvmm: failing the launch as requested\n"}}},{"argv":["sandbox","start","--state-dir","{root}/state","--timeout","0.5"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":1,"stdout":"","stderr":"error[exited]: OpenVMM exited during startup with status 5\n","files":{"state":{"entries":["config.json","openvmm.log","sandbox.lock"],"mode":448},"state/config.json":{"text":"{\n \"cmdline\": \"fake_exit_on_start=5\",\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":{"text":"openvmm: failing the launch as requested\n"}}},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"state: start without OpenVMM","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","start","--state-dir","{root}/state"],"remove":["openvmm/target/release/openvmm{exe}"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":1,"stdout":"","stderr":"error[artifact-missing]: OpenVMM release binary not found: {root}/openvmm/target/release/openvmm\n","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","deprovision","--state-dir","{root}/state"],"status":0,"stdout":"","stderr":""}]}, -{"name":"state: malformed configuration","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","start","--state-dir","{root}/state"],"write":{"state/config.json":"{\"format\": 8}"},"status":1,"stdout":"","stderr":"error[format-unsupported]: sandbox configuration has an unsupported format: {root}/state/config.json\n"},{"argv":["sandbox","start","--state-dir","{root}/state"],"write":{"state/config.json":"[]"},"status":1,"stdout":"","stderr":"error[format-unsupported]: sandbox configuration has an unsupported format: {root}/state/config.json\n"},{"argv":["sandbox","start","--state-dir","{root}/state"],"write":{"state/config.json":"{\"format\": 1}"},"status":1,"stdout":"","stderr":"error[io]: sandbox configuration is malformed\n"},{"argv":["sandbox","deprovision","--state-dir","{root}/state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}]}, -{"name":"state: not a directory","steps":[{"argv":["sandbox","start","--state-dir","{root}/single.txt"],"status":1,"stdout":"","stderr":"error[sandbox-not-provisioned]: sandbox state path is not a plain directory: {root}/single.txt\n"},{"argv":["sandbox","provision","--state-dir","{root}/single.txt","--layer","distro,{root}/distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}/scratch.ext4"],"status":1,"stdout":"","stderr":"error[io]: [Errno 17] File exists: '{root}/single.txt'\n"},{"argv":["sandbox","deprovision","--state-dir","{root}/single.txt"],"status":1,"stdout":"","stderr":"error[sandbox-not-provisioned]: sandbox state path is not a plain directory: {root}/single.txt\n"}]}, -{"name":"state: foreign file","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","deprovision","--state-dir","{root}/state"],"write":{"state/foreign.txt":"x"},"check":["state"],"status":1,"stdout":"","stderr":"error[foreign-files]: sandbox state directory contains files not owned by NVX: foreign.txt\n","files":{"state":{"entries":["foreign.txt"],"mode":448}}}]}, -{"name":"run, usage: help","steps":[{"argv":["run","-h"],"status":0,"stdout":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\n\noptions:\n -h, --help show this help message and exit\n --guest {alpine,ubuntu,azurelinux}\n --hypervisor {auto,whp,kvm,mshv}\n --machine {microvm}\n --memory-mib MEMORY_MIB\n guest RAM in MiB (default by --guest: alpine 128,\n ubuntu 512, azurelinux 512)\n --memory-capacity-mib MEMORY_CAPACITY_MIB\n --processors {1,2,4,8}\n --cpu-profile ID OpenVMM CPU profile: auto (OpenVMM's default) for the\n built-in profile of the host's CPU, a built-in profile\n ID, or host to derive a development profile from this\n host (doc/usage.md)\n --mount GUEST_TARGET,HOST_PATH[,ro|rw]\n live-share a host directory, or a single regular host\n file without its directory; the mode follows the last\n comma, so HOST_PATH may contain commas when the mode\n is given; repeat for more shares, each with its own\n guest target and mode, as children of one virtio-fs\n device\n --mount-deny MOUNT_DENY\n --mount-allow HOST_PATH\n expose one existing path inside a --mount-deny path\n again\n --mount-write HOST_PATH\n make one existing path one of the only writable parts\n of a read-write --mount\n --mount-owner {vmm,caller}\n host identity of the share's file operations: vmm\n (default) or caller, with guest root squashed to the\n owner of the shared directory or file (Linux only)\n --net IPV4/PREFIX\n --network-profile {portable}\n --network-egress {allow,deny}\n --network-ingress {allow,deny}\n --network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]\n allow guest egress to an IPv4 or IPv6 CIDR, optionally\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\n udp only on PORT or on the inclusive range PORT-PORT;\n repeat to add rules\n --network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]\n deny guest egress to an IPv4 or IPv6 CIDR, optionally\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\n udp only on PORT or on the inclusive range PORT-PORT;\n repeat to add rules\n --network-egress-policy-file PATH\n load bounded MXC-shaped IPv4 and IPv6 egress rules\n from JSON\n --host-loopback {allow,deny}\n --network-proxy IPV4:TCP-PORT\n --host-loopback-forward HOST_LOOPBACK_FORWARD\n --outcome-report OUTCOME_REPORT\n write a bounded local JSON outcome report\n --cmdline CMDLINE\n --restore-snapshot RESTORE_SNAPSHOT\n --restore-processors {1,2,4,8}\n --restore-memory-mib RESTORE_MEMORY_MIB\n --restore-ready-path RESTORE_READY_PATH\n --dry-run\n","stderr":""}]}, -{"name":"run, usage: help after options","steps":[{"argv":["run","--guest","ubuntu","--help"],"status":0,"stdout":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\n\noptions:\n -h, --help show this help message and exit\n --guest {alpine,ubuntu,azurelinux}\n --hypervisor {auto,whp,kvm,mshv}\n --machine {microvm}\n --memory-mib MEMORY_MIB\n guest RAM in MiB (default by --guest: alpine 128,\n ubuntu 512, azurelinux 512)\n --memory-capacity-mib MEMORY_CAPACITY_MIB\n --processors {1,2,4,8}\n --cpu-profile ID OpenVMM CPU profile: auto (OpenVMM's default) for the\n built-in profile of the host's CPU, a built-in profile\n ID, or host to derive a development profile from this\n host (doc/usage.md)\n --mount GUEST_TARGET,HOST_PATH[,ro|rw]\n live-share a host directory, or a single regular host\n file without its directory; the mode follows the last\n comma, so HOST_PATH may contain commas when the mode\n is given; repeat for more shares, each with its own\n guest target and mode, as children of one virtio-fs\n device\n --mount-deny MOUNT_DENY\n --mount-allow HOST_PATH\n expose one existing path inside a --mount-deny path\n again\n --mount-write HOST_PATH\n make one existing path one of the only writable parts\n of a read-write --mount\n --mount-owner {vmm,caller}\n host identity of the share's file operations: vmm\n (default) or caller, with guest root squashed to the\n owner of the shared directory or file (Linux only)\n --net IPV4/PREFIX\n --network-profile {portable}\n --network-egress {allow,deny}\n --network-ingress {allow,deny}\n --network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]\n allow guest egress to an IPv4 or IPv6 CIDR, optionally\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\n udp only on PORT or on the inclusive range PORT-PORT;\n repeat to add rules\n --network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]\n deny guest egress to an IPv4 or IPv6 CIDR, optionally\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\n udp only on PORT or on the inclusive range PORT-PORT;\n repeat to add rules\n --network-egress-policy-file PATH\n load bounded MXC-shaped IPv4 and IPv6 egress rules\n from JSON\n --host-loopback {allow,deny}\n --network-proxy IPV4:TCP-PORT\n --host-loopback-forward HOST_LOOPBACK_FORWARD\n --outcome-report OUTCOME_REPORT\n write a bounded local JSON outcome report\n --cmdline CMDLINE\n --restore-snapshot RESTORE_SNAPSHOT\n --restore-processors {1,2,4,8}\n --restore-memory-mib RESTORE_MEMORY_MIB\n --restore-ready-path RESTORE_READY_PATH\n --dry-run\n","stderr":""}]}, -{"name":"run, usage: help before an invalid value","steps":[{"argv":["run","--help","--memory-mib","x"],"status":0,"stdout":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\n\noptions:\n -h, --help show this help message and exit\n --guest {alpine,ubuntu,azurelinux}\n --hypervisor {auto,whp,kvm,mshv}\n --machine {microvm}\n --memory-mib MEMORY_MIB\n guest RAM in MiB (default by --guest: alpine 128,\n ubuntu 512, azurelinux 512)\n --memory-capacity-mib MEMORY_CAPACITY_MIB\n --processors {1,2,4,8}\n --cpu-profile ID OpenVMM CPU profile: auto (OpenVMM's default) for the\n built-in profile of the host's CPU, a built-in profile\n ID, or host to derive a development profile from this\n host (doc/usage.md)\n --mount GUEST_TARGET,HOST_PATH[,ro|rw]\n live-share a host directory, or a single regular host\n file without its directory; the mode follows the last\n comma, so HOST_PATH may contain commas when the mode\n is given; repeat for more shares, each with its own\n guest target and mode, as children of one virtio-fs\n device\n --mount-deny MOUNT_DENY\n --mount-allow HOST_PATH\n expose one existing path inside a --mount-deny path\n again\n --mount-write HOST_PATH\n make one existing path one of the only writable parts\n of a read-write --mount\n --mount-owner {vmm,caller}\n host identity of the share's file operations: vmm\n (default) or caller, with guest root squashed to the\n owner of the shared directory or file (Linux only)\n --net IPV4/PREFIX\n --network-profile {portable}\n --network-egress {allow,deny}\n --network-ingress {allow,deny}\n --network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]\n allow guest egress to an IPv4 or IPv6 CIDR, optionally\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\n udp only on PORT or on the inclusive range PORT-PORT;\n repeat to add rules\n --network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]\n deny guest egress to an IPv4 or IPv6 CIDR, optionally\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\n udp only on PORT or on the inclusive range PORT-PORT;\n repeat to add rules\n --network-egress-policy-file PATH\n load bounded MXC-shaped IPv4 and IPv6 egress rules\n from JSON\n --host-loopback {allow,deny}\n --network-proxy IPV4:TCP-PORT\n --host-loopback-forward HOST_LOOPBACK_FORWARD\n --outcome-report OUTCOME_REPORT\n write a bounded local JSON outcome report\n --cmdline CMDLINE\n --restore-snapshot RESTORE_SNAPSHOT\n --restore-processors {1,2,4,8}\n --restore-memory-mib RESTORE_MEMORY_MIB\n --restore-ready-path RESTORE_READY_PATH\n --dry-run\n","stderr":""}]}, -{"name":"run, usage: invalid value before help","steps":[{"argv":["run","--memory-mib","x","--help"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --memory-mib: invalid int value: 'x'\n"}]}, -{"name":"run, usage: invalid guest","steps":[{"argv":["run","--guest","debian"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --guest: invalid choice: 'debian' (choose from 'alpine', 'ubuntu', 'azurelinux')\n"}]}, -{"name":"run, usage: invalid second guest","steps":[{"argv":["run","--guest","alpine","--guest","debian"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --guest: invalid choice: 'debian' (choose from 'alpine', 'ubuntu', 'azurelinux')\n"}]}, -{"name":"run, usage: invalid hypervisor","steps":[{"argv":["run","--hypervisor","hyperv"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --hypervisor: invalid choice: 'hyperv' (choose from 'auto', 'whp', 'kvm', 'mshv')\n"}]}, -{"name":"run, usage: invalid machine","steps":[{"argv":["run","--machine","microvm-v2"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --machine: invalid choice: 'microvm-v2' (choose from 'microvm')\n"}]}, -{"name":"run, usage: memory not an integer","steps":[{"argv":["run","--memory-mib","x"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --memory-mib: invalid int value: 'x'\n"}]}, -{"name":"run, usage: memory not a whole number","steps":[{"argv":["run","--memory-mib","1.5"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --memory-mib: invalid int value: '1.5'\n"}]}, -{"name":"run, usage: memory with a space","steps":[{"argv":["run","--memory-mib","1 2"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --memory-mib: invalid int value: '1 2'\n"}]}, -{"name":"run, usage: memory with other digits","steps":[{"argv":["run","--memory-mib","\u0661\u0662\u0668x"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --memory-mib: invalid int value: '\u0661\u0662\u0668x'\n"}]}, -{"name":"run, usage: memory capacity not an integer","steps":[{"argv":["run","--memory-capacity-mib","1e3"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --memory-capacity-mib: invalid int value: '1e3'\n"}]}, -{"name":"run, usage: restore memory not an integer","steps":[{"argv":["run","--restore-memory-mib",""],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --restore-memory-mib: invalid int value: ''\n"}]}, -{"name":"run, usage: processors not an integer","steps":[{"argv":["run","--processors","two"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --processors: invalid int value: 'two'\n"}]}, -{"name":"run, usage: processors not a choice","steps":[{"argv":["run","--processors","3"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --processors: invalid choice: '3' (choose from '1', '2', '4', '8')\n"}]}, -{"name":"run, usage: processors converted before the choice","steps":[{"argv":["run","--processors","1_6"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --processors: invalid choice: '16' (choose from '1', '2', '4', '8')\n"}]}, -{"name":"run, usage: processors with a leading zero","steps":[{"argv":["run","--processors","03"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --processors: invalid choice: '3' (choose from '1', '2', '4', '8')\n"}]}, -{"name":"run, usage: negative processors","steps":[{"argv":["run","--processors","-5"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --processors: invalid choice: '-5' (choose from '1', '2', '4', '8')\n"}]}, -{"name":"run, usage: restore processors not an integer","steps":[{"argv":["run","--restore-processors","x"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --restore-processors: invalid int value: 'x'\n"}]}, -{"name":"run, usage: restore processors not a choice","steps":[{"argv":["run","--restore-processors","16"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --restore-processors: invalid choice: '16' (choose from '1', '2', '4', '8')\n"}]}, -{"name":"run, usage: invalid mount owner","steps":[{"argv":["run","--mount-owner","root"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --mount-owner: invalid choice: 'root' (choose from 'vmm', 'caller')\n"}]}, -{"name":"run, usage: invalid network profile","steps":[{"argv":["run","--network-profile","open"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --network-profile: invalid choice: 'open' (choose from 'portable')\n"}]}, -{"name":"run, usage: invalid network egress","steps":[{"argv":["run","--network-egress","block"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --network-egress: invalid choice: 'block' (choose from 'allow', 'deny')\n"}]}, -{"name":"run, usage: invalid network ingress","steps":[{"argv":["run","--network-ingress","open"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --network-ingress: invalid choice: 'open' (choose from 'allow', 'deny')\n"}]}, -{"name":"run, usage: invalid host loopback","steps":[{"argv":["run","--host-loopback","yes"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --host-loopback: invalid choice: 'yes' (choose from 'allow', 'deny')\n"}]}, -{"name":"run, usage: missing value","steps":[{"argv":["run","--memory-mib"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-missing]: argument --memory-mib: expected one argument\n"}]}, -{"name":"run, usage: missing path","steps":[{"argv":["run","--restore-snapshot"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-missing]: argument --restore-snapshot: expected one argument\n"}]}, -{"name":"run, usage: option as value","steps":[{"argv":["run","--cpu-profile","--dry-run"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-missing]: argument --cpu-profile: expected one argument\n"}]}, -{"name":"run, usage: dash value","steps":[{"argv":["run","--cmdline","-x"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-missing]: argument --cmdline: expected one argument\n"}]}, -{"name":"run, usage: flag with value","steps":[{"argv":["run","--dry-run=1"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\n [--memory-mib MEMORY_MIB]\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\n [--processors {1,2,4,8}] [--cpu-profile ID]\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\n [--net IPV4/PREFIX] [--network-profile {portable}]\n [--network-egress {allow,deny}]\n [--network-ingress {allow,deny}]\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\n [--network-egress-policy-file PATH]\n [--host-loopback {allow,deny}]\n [--network-proxy IPV4:TCP-PORT]\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\n [--restore-snapshot RESTORE_SNAPSHOT]\n [--restore-processors {1,2,4,8}]\n [--restore-memory-mib RESTORE_MEMORY_MIB]\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\nnvx-rs run: error[argument-invalid]: argument --dry-run: ignored explicit argument '1'\n"}]}, -{"name":"run, usage: unrecognized option","steps":[{"argv":["run","--bogus"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\n {artifacts,egress,run,sandbox} ...\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: --bogus\n"}]}, -{"name":"run, usage: unrecognized short option","steps":[{"argv":["run","-x"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\n {artifacts,egress,run,sandbox} ...\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: -x\n"}]}, -{"name":"run, usage: unrecognized positional","steps":[{"argv":["run","extra"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\n {artifacts,egress,run,sandbox} ...\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: extra\n"}]}, -{"name":"run, usage: unrecognized after separator","steps":[{"argv":["run","--","extra"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\n {artifacts,egress,run,sandbox} ...\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: -- extra\n"}]}, -{"name":"run, usage: unrecognized after options","steps":[{"argv":["run","--dry-run","--guest","alpine","extra"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\n {artifacts,egress,run,sandbox} ...\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: extra\n"}]}, -{"name":"run, validation: net without profile","steps":[{"argv":["run","--net","10.0.0.2/24","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --net and --network-profile must be specified together\n"}]}, -{"name":"run, validation: profile without net","steps":[{"argv":["run","--network-profile","portable","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --net and --network-profile must be specified together\n"}]}, -{"name":"run, validation: ready path without snapshot","steps":[{"argv":["run","--restore-ready-path","{root}/ready.sock","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --restore-ready-path requires --restore-snapshot\n"}]}, -{"name":"run, validation: restore processors without snapshot","steps":[{"argv":["run","--restore-processors","1","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --restore-processors requires --restore-snapshot\n"}]}, -{"name":"run, validation: restore memory without snapshot","steps":[{"argv":["run","--restore-memory-mib","1024","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --restore-memory-mib requires --restore-snapshot\n"}]}, -{"name":"run, validation: memory capacity of a restore","steps":[{"argv":["run","--restore-snapshot","{root}/snapshot","--memory-capacity-mib","1024","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --memory-capacity-mib is only valid for a fresh boot\n"}]}, -{"name":"run, validation: Ubuntu guest of a restore","steps":[{"argv":["run","--guest","ubuntu","--restore-snapshot","{root}/snapshot","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --guest is not accepted for restore; the snapshot already fixes the guest\n"}]}, -{"name":"run, validation: Azure Linux guest of a restore","steps":[{"argv":["run","--restore-snapshot","{root}/snapshot","--guest","azurelinux","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --guest is not accepted for restore; the snapshot already fixes the guest\n"}]}, -{"name":"run, validation: memory capacity below memory","steps":[{"argv":["run","--memory-mib","512","--memory-capacity-mib","256","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --memory-capacity-mib cannot be below --memory-mib\n"}]}, -{"name":"run, validation: memory capacity below the guest default","steps":[{"argv":["run","--guest","ubuntu","--memory-capacity-mib","256","--dry-run"],"write":{"build/initramfs-ubuntu.cpio.gz":"ubuntu\n"},"status":1,"stdout":"","stderr":"error[unsupported]: --memory-capacity-mib cannot be below --memory-mib\n"}]}, -{"name":"run, validation: restore processors above processors","steps":[{"argv":["run","--processors","2","--restore-snapshot","{root}/snapshot","--restore-processors","4","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --restore-processors cannot exceed --processors capacity\n"}]}, -{"name":"run, validation: policy file with allow rules","steps":[{"argv":["run","--network-egress","deny","--network-egress-policy-file","{root}/policy.json","--network-egress-allow","10.0.0.0/8","--dry-run"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"except\": [\"192.0.2.128/25\"]}, {\"cidr\": \"2001:db8::/32\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"198.51.100.0/24\", \"protocol\": \"udp\"}]}"},"status":1,"stdout":"","stderr":"error[unsupported]: --network-egress-policy-file cannot be combined with --network-egress-allow or --network-egress-deny\n"}]}, -{"name":"run, validation: policy file with deny rules","steps":[{"argv":["run","--network-egress-deny","10.0.0.0/8","--network-egress-policy-file","{root}/policy.json","--dry-run"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"except\": [\"192.0.2.128/25\"]}, {\"cidr\": \"2001:db8::/32\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"198.51.100.0/24\", \"protocol\": \"udp\"}]}"},"status":1,"stdout":"","stderr":"error[unsupported]: --network-egress-policy-file cannot be combined with --network-egress-allow or --network-egress-deny\n"}]}, -{"name":"run, validation: policy file without egress","steps":[{"argv":["run","--network-egress-policy-file","{root}/policy.json","--dry-run"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"except\": [\"192.0.2.128/25\"]}, {\"cidr\": \"2001:db8::/32\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"198.51.100.0/24\", \"protocol\": \"udp\"}]}"},"status":1,"stdout":"","stderr":"error[unsupported]: --network-egress is required with --network-egress-policy-file\n"}]}, -{"name":"run, validation: policy file missing","steps":[{"argv":["run","--network-egress","deny","--network-egress-policy-file","{root}/./missing.json","--dry-run"],"status":1,"stdout":"","stderr":"error[io]: failed to read egress policy file: {root}/./missing.json\n"}]}, -{"name":"run, validation: policy file directory","steps":[{"argv":["run","--network-egress","deny","--network-egress-policy-file","{root}/share","--dry-run"],"status":1,"stdout":"","stderr":"error[io]: failed to read egress policy file: {root}/share\n"}]}, -{"name":"run, validation: policy file invalid","steps":[{"argv":["run","--network-egress","allow","--network-egress-policy-file","policy.json","--dry-run"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"10.0.0.0/8\", \"port\": 0}]}"},"status":1,"stdout":"","stderr":"error[unsupported]: allow[0].port requires protocol\n"}]}, -{"name":"run, validation: policy file not JSON","steps":[{"argv":["run","--network-egress","allow","--network-egress-policy-file","policy.json","--dry-run"],"write":{"policy.json":"{"},"status":1,"stdout":"","stderr":"error[unsupported]: egress policy file policy.json is not valid JSON: EOF while parsing an object at line 1 column 1\n"}]}, -{"name":"run, validation: policy errors before missing artifacts","steps":[{"argv":["run","--network-egress-policy-file","{root}/policy.json","--dry-run"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"except\": [\"192.0.2.128/25\"]}, {\"cidr\": \"2001:db8::/32\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"198.51.100.0/24\", \"protocol\": \"udp\"}]}"},"remove":["openvmm/target/release/openvmm{exe}","build/vmlinux"],"status":1,"stdout":"","stderr":"error[unsupported]: --network-egress is required with --network-egress-policy-file\n"}]}, -{"name":"run, validation: missing OpenVMM","steps":[{"argv":["run","--dry-run"],"remove":["openvmm/target/release/openvmm{exe}"],"status":1,"stdout":"","stderr":"error[artifact-missing]: OpenVMM release binary not found: {root}/openvmm/target/release/openvmm\n"}]}, -{"name":"run, validation: missing kernel","steps":[{"argv":["run","--dry-run"],"remove":["build/vmlinux"],"status":1,"stdout":"","stderr":"error[artifact-missing]: Linux direct kernel not found: {root}/build/vmlinux\n"}]}, -{"name":"run, validation: missing Alpine initramfs","steps":[{"argv":["run","--dry-run"],"remove":["build/initramfs.cpio.gz"],"status":1,"stdout":"","stderr":"error[artifact-missing]: Alpine Linux initramfs not found: {root}/build/initramfs.cpio.gz\n"}]}, -{"name":"run, validation: missing Ubuntu initramfs","steps":[{"argv":["run","--guest","ubuntu","--dry-run"],"status":1,"stdout":"","stderr":"error[artifact-missing]: Ubuntu Base initramfs not found: {root}/build/initramfs-ubuntu.cpio.gz\n"}]}, -{"name":"run, validation: missing Azure Linux initramfs","steps":[{"argv":["run","--guest","azurelinux","--dry-run"],"status":1,"stdout":"","stderr":"error[artifact-missing]: Azure Linux initramfs not found: {root}/build/initramfs-azurelinux.cpio.gz\n"}]}, -{"name":"run, validation: missing artifacts before invalid shares","steps":[{"argv":["run","--mount","/data","--dry-run"],"remove":["openvmm/target/release/openvmm{exe}"],"status":1,"stdout":"","stderr":"error[artifact-missing]: OpenVMM release binary not found: {root}/openvmm/target/release/openvmm\n"}]}, -{"name":"run, validation: mount without host path","steps":[{"argv":["run","--mount","/data","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount must be GUEST_TARGET,HOST_PATH[,ro|rw]\n"}]}, -{"name":"run, validation: mount with empty host path","steps":[{"argv":["run","--mount","/data,","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount host path is empty\n"}]}, -{"name":"run, validation: mount with empty host path and mode","steps":[{"argv":["run","--mount","/data,,rw","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount host path is empty\n"}]}, -{"name":"run, validation: mount with invalid mode","steps":[{"argv":["run","--mount","/data,{root}/share,rx","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: unsupported --mount mode 'rx'; choose ro or rw (if HOST_PATH contains commas, end the value with ,ro or ,rw)\n"}]}, -{"name":"run, validation: mount with commas but no mode","steps":[{"argv":["run","--mount","/data,{root}/alpha,beta","--dry-run"],"write":{"alpha,beta/data.txt":"data\n","2026, final/data.txt":"data\n","settings,v2.json":"{}\n"},"status":1,"stdout":"","stderr":"error[unsupported]: unsupported --mount mode 'beta'; choose ro or rw (if HOST_PATH contains commas, end the value with ,ro or ,rw)\n"}]}, -{"name":"run, validation: invalid second mount","steps":[{"argv":["run","--mount","/a,{root}/share","--mount","relative","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount must be GUEST_TARGET,HOST_PATH[,ro|rw]\n"}]}, -{"name":"run, validation: invalid mount before invalid targets","steps":[{"argv":["run","--mount","a,{root}/share","--mount","/b","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount must be GUEST_TARGET,HOST_PATH[,ro|rw]\n"}]}, -{"name":"run, validation: owner without mount","steps":[{"argv":["run","--mount-owner","vmm","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-owner requires --mount\n"}]}, -{"name":"run, validation: relative deny path with several shares","steps":[{"argv":["run","--mount","/a,{root}/share","--mount","/b,{root}/share2","--mount-deny","secrets","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: with several --mount shares, or a shared file, --mount-deny secrets must be an absolute host path\n"}]}, -{"name":"run, validation: relative allow path with a shared file","steps":[{"argv":["run","--mount","/etc/single.txt,{root}/single.txt","--mount-allow","secrets","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: with several --mount shares, or a shared file, --mount-allow secrets must be an absolute host path\n"}]}, -{"name":"run, validation: relative write path with several shares","steps":[{"argv":["run","--mount","/a,{root}/share","--mount","/b,{root}/share2","--mount-write","./out/","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: with several --mount shares, or a shared file, --mount-write out must be an absolute host path\n"}]}, -{"name":"run, validation: relative paths in kind order","steps":[{"argv":["run","--mount","/a,{root}/share","--mount","/b,{root}/share2","--mount-write","out","--mount-deny","secrets","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: with several --mount shares, or a shared file, --mount-deny secrets must be an absolute host path\n"}]}, -{"name":"run, validation: relative target with several shares","steps":[{"argv":["run","--mount","a,{root}/share","--mount","/b,{root}/share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target 'a': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\n"}]}, -{"name":"run, validation: relative target of a shared file","steps":[{"argv":["run","--mount","single.txt,{root}/single.txt","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target 'single.txt': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\n"}]}, -{"name":"run, validation: root target with several shares","steps":[{"argv":["run","--mount","/,{root}/share","--mount","/b,{root}/share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target '/': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\n"}]}, -{"name":"run, validation: target with a space","steps":[{"argv":["run","--mount","/a b,{root}/share","--mount","/b,{root}/share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target '/a b': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\n"}]}, -{"name":"run, validation: target with an equals sign","steps":[{"argv":["run","--mount","/a=b,{root}/share","--mount","/b,{root}/share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target '/a=b': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\n"}]}, -{"name":"run, validation: target with a backslash","steps":[{"argv":["run","--mount","/a\\b,{root}/share","--mount","/b,{root}/share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target '/a\\\\b': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\n"}]}, -{"name":"run, validation: target with a dot component","steps":[{"argv":["run","--mount","/a/./b,{root}/share","--mount","/b,{root}/share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target '/a/./b': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\n"}]}, -{"name":"run, validation: target with a parent component","steps":[{"argv":["run","--mount","/a/../b,{root}/share","--mount","/c,{root}/share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target '/a/../b': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\n"}]}, -{"name":"run, validation: target with an empty component","steps":[{"argv":["run","--mount","/a//b,{root}/share","--mount","/c,{root}/share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target '/a//b': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\n"}]}, -{"name":"run, validation: equal targets","steps":[{"argv":["run","--mount","/a,{root}/share","--mount","/a,{root}/share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount targets /a and /a overlap; a share cannot hide another\n"}]}, -{"name":"run, validation: nested targets","steps":[{"argv":["run","--mount","/workspace,{root}/share","--mount","/workspace/cache,{root}/share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount targets /workspace and /workspace/cache overlap; a share cannot hide another\n"}]}, -{"name":"run, validation: target containing another","steps":[{"argv":["run","--mount","/workspace/cache,{root}/share","--mount","/workspace,{root}/share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount targets /workspace/cache and /workspace overlap; a share cannot hide another\n"}]}, -{"name":"run, validation: target containing the aggregate","steps":[{"argv":["run","--mount","/run/nvx,{root}/share","--mount","/b,{root}/share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount targets /run/nvx/shares and /run/nvx overlap; a share cannot hide another\n"}]}, -{"name":"run, validation: target in the aggregate","steps":[{"argv":["run","--mount","/run/nvx/shares/x,{root}/share","--mount","/b,{root}/share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount targets /run/nvx/shares and /run/nvx/shares/x overlap; a share cannot hide another\n"}]}, -{"name":"run, validation: too many shares for the budget","steps":[{"argv":["run","--mount","/share/00,{root}/share","--mount","/share/01,{root}/share","--mount","/share/02,{root}/share","--mount","/share/03,{root}/share","--mount","/share/04,{root}/share","--mount","/share/05,{root}/share","--mount","/share/06,{root}/share","--mount","/share/07,{root}/share","--mount","/share/08,{root}/share","--mount","/share/09,{root}/share","--mount","/share/10,{root}/share","--mount","/share/11,{root}/share","--mount","/share/12,{root}/share","--mount","/share/13,{root}/share","--mount","/share/14,{root}/share","--mount","/share/15,{root}/share","--mount","/share/16,{root}/share","--mount","/share/17,{root}/share","--mount","/share/18,{root}/share","--mount","/share/19,{root}/share","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: the --mount shares and --cmdline exceed the 1024-byte budget of the kernel command line; attach fewer shares or use shorter targets\n"}]}, -{"name":"run, validation: budget exceeded by a byte","steps":[{"argv":["run","--mount","/a,{root}/share","--mount","/b,{root}/share2,rw","--cmdline","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: the --mount shares and --cmdline exceed the 1024-byte budget of the kernel command line; attach fewer shares or use shorter targets\n"}]}, -{"name":"run, validation: budget in UTF-8 bytes","steps":[{"argv":["run","--mount","/a,{root}/share","--mount","/b,{root}/share2,rw","--cmdline","\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: the --mount shares and --cmdline exceed the 1024-byte budget of the kernel command line; attach fewer shares or use shorter targets\n"}]}, -{"name":"run, validation: missing OpenVMM override","steps":[{"argv":["run","--dry-run"],"env":{"NVX_OPENVMM":"{root}/alt/openvmm{exe}"},"status":1,"stdout":"","stderr":"error[artifact-missing]: OpenVMM release binary not found: {root}/alt/openvmm\n"}]}, -{"name":"run, dry run: Alpine default","steps":[{"argv":["run","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz\n","stderr":""}]}, -{"name":"run, dry run: Ubuntu default","steps":[{"argv":["run","--guest","ubuntu","--dry-run"],"write":{"build/initramfs-ubuntu.cpio.gz":"ubuntu\n"},"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 512M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs-ubuntu.cpio.gz\n","stderr":""}]}, -{"name":"run, dry run: Azure Linux default","steps":[{"argv":["run","--guest","azurelinux","--dry-run"],"write":{"build/initramfs-azurelinux.cpio.gz":"azurelinux\n"},"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 512M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs-azurelinux.cpio.gz\n","stderr":""}]}, -{"name":"run, dry run: Alpine with memory","steps":[{"argv":["run","--guest","alpine","--memory-mib","256","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 256M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz\n","stderr":""}]}, -{"name":"run, dry run: Ubuntu with memory and capacity","steps":[{"argv":["run","--guest","ubuntu","--memory-mib","1024","--memory-capacity-mib","2048","--dry-run"],"write":{"build/initramfs-ubuntu.cpio.gz":"ubuntu\n"},"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 1024M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs-ubuntu.cpio.gz --memory-capacity 2048M\n","stderr":""}]}, -{"name":"run, dry run: Azure Linux with the default capacity","steps":[{"argv":["run","--guest","azurelinux","--memory-capacity-mib","512","--dry-run"],"write":{"build/initramfs-azurelinux.cpio.gz":"azurelinux\n"},"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 512M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs-azurelinux.cpio.gz --memory-capacity 512M\n","stderr":""}]}, -{"name":"run, dry run: last guest","steps":[{"argv":["run","--guest","ubuntu","--guest","azurelinux","--dry-run"],"write":{"build/initramfs-azurelinux.cpio.gz":"azurelinux\n"},"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 512M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs-azurelinux.cpio.gz\n","stderr":""}]}, -{"name":"run, dry run: every boot option","steps":[{"argv":["run","--hypervisor","mshv","--machine","microvm","--memory-mib","1024","--memory-capacity-mib","2048","--processors","8","--cpu-profile","intel.alderlake.v1","--cmdline","quiet loglevel=3","--outcome-report","{root}/reports/openvmm-run.json","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 8 --hypervisor mshv --memory 1024M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --memory-capacity 2048M --cpu-profile intel.alderlake.v1 --microvm-report {root}/reports/openvmm-run.json --cmdline 'quiet loglevel=3'\n","stderr":""}]}, -{"name":"run, dry run: auto hypervisor","steps":[{"argv":["run","--hypervisor","auto","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz\n","stderr":""}]}, -{"name":"run, dry run: KVM","steps":[{"argv":["run","--hypervisor","kvm","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz\n","stderr":""}]}, -{"name":"run, dry run: WHP","steps":[{"argv":["run","--hypervisor","whp","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz\n","stderr":""}]}, -{"name":"run, dry run: canonical integers","steps":[{"argv":["run","--memory-mib"," +12_8 ","--memory-capacity-mib","0256","--processors"," 2 ","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 2 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --memory-capacity 256M\n","stderr":""}]}, -{"name":"run, dry run: other digits","steps":[{"argv":["run","--processors","\u0664","--memory-mib","\u0665\u0661\u0662","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 4 --hypervisor kvm --memory 512M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz\n","stderr":""}]}, -{"name":"run, dry run: negative memory","steps":[{"argv":["run","--memory-mib","-5","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory -5M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz\n","stderr":""}]}, -{"name":"run, dry run: attached negative memory","steps":[{"argv":["run","--memory-mib=-128","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory -128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz\n","stderr":""}]}, -{"name":"run, dry run: equal memory and capacity","steps":[{"argv":["run","--memory-mib","512","--memory-capacity-mib","512","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 512M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --memory-capacity 512M\n","stderr":""}]}, -{"name":"run, dry run: last processors","steps":[{"argv":["run","--processors","2","--processors","4","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 4 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz\n","stderr":""}]}, -{"name":"run, dry run: cpu profile auto","steps":[{"argv":["run","--cpu-profile","auto","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --cpu-profile auto\n","stderr":""}]}, -{"name":"run, dry run: cpu profile host","steps":[{"argv":["run","--cpu-profile","host","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --cpu-profile host\n","stderr":""}]}, -{"name":"run, dry run: restore","steps":[{"argv":["run","--restore-snapshot","{root}/snapshot","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --restore-snapshot {root}/snapshot\n","stderr":""}]}, -{"name":"run, dry run: restore without guest artifacts","steps":[{"argv":["run","--restore-snapshot","{root}/snapshot","--dry-run"],"remove":["build/vmlinux","build/initramfs.cpio.gz"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --restore-snapshot {root}/snapshot\n","stderr":""}]}, -{"name":"run, dry run: restore with every option","steps":[{"argv":["run","--hypervisor","mshv","--processors","4","--restore-snapshot","{root}/snapshot","--restore-processors","2","--restore-memory-mib","1024","--restore-ready-path","{root}/ready.sock","--cpu-profile","host","--outcome-report","{root}/reports/restore.json","--cmdline","quiet","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 4 --hypervisor mshv --restore-snapshot {root}/snapshot --restore-processors 2 --restore-memory 1024M --restore-ready-path {root}/ready.sock --cpu-profile host --microvm-report {root}/reports/restore.json --cmdline quiet\n","stderr":""}]}, -{"name":"run, dry run: restore of the Alpine guest","steps":[{"argv":["run","--guest","alpine","--restore-snapshot","{root}/snapshot","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --restore-snapshot {root}/snapshot\n","stderr":""}]}, -{"name":"run, dry run: restore with equal processors","steps":[{"argv":["run","--processors","2","--restore-processors","2","--restore-snapshot","{root}/snapshot","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 2 --hypervisor kvm --restore-snapshot {root}/snapshot --restore-processors 2\n","stderr":""}]}, -{"name":"run, dry run: restore ignores the memory","steps":[{"argv":["run","--memory-mib","512","--restore-snapshot","{root}/snapshot","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --restore-snapshot {root}/snapshot\n","stderr":""}]}, -{"name":"run, dry run: restore paths","steps":[{"argv":["run","--restore-snapshot","./snapshot/","--restore-ready-path","run//ready.sock","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --restore-snapshot snapshot --restore-ready-path run/ready.sock\n","stderr":""}]}, -{"name":"run, dry run: one share","steps":[{"argv":["run","--mount","/data,{root}/share","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount /data,{root}/share,ro\n","stderr":""}]}, -{"name":"run, dry run: one writable share","steps":[{"argv":["run","--mount","/data,{root}/share,rw","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount /data,{root}/share,rw\n","stderr":""}]}, -{"name":"run, dry run: one relative share","steps":[{"argv":["run","--mount","/data,share","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount /data,share,ro\n","stderr":""}]}, -{"name":"run, dry run: one share with relative policy paths","steps":[{"argv":["run","--mount","/data,{root}/share,rw","--mount-write","writable","--mount-allow","hidden/shown","--mount-deny","./hidden/","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount /data,{root}/share,rw --mount-deny hidden --mount-allow hidden/shown --mount-write writable\n","stderr":""}]}, -{"name":"run, dry run: policy paths without a share","steps":[{"argv":["run","--mount-deny","{root}/share/hidden","--mount-allow","x","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount-deny {root}/share/hidden --mount-allow x\n","stderr":""}]}, -{"name":"run, dry run: several shares with policy paths","steps":[{"argv":["run","--mount","/data,{root}/share,rw","--mount","/other,{root}/share2","--mount-write","{root}/share/writable","--mount-allow","{root}/share/hidden/shown","--mount-deny","{root}/share/hidden","--mount-deny","{root}/share2/./data.txt","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}/share,rw --mount-child 1-bf2faee2596026620b5cbc997c2d7d45,{root}/share2,ro --mount-deny {root}/share/hidden --mount-deny {root}/share2/data.txt --mount-allow {root}/share/hidden/shown --mount-write {root}/share/writable --cmdline 'nvx_share=0-bd47413b5c03dfc6e4b5b8143fe205ea,/data,rw nvx_share=1-bf2faee2596026620b5cbc997c2d7d45,/other,ro'\n","stderr":""}]}, -{"name":"run, dry run: several shares with a command line","steps":[{"argv":["run","--mount","/data,{root}/share,rw","--mount","/other,{root}/share2","--cmdline","quiet","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}/share,rw --mount-child 1-bf2faee2596026620b5cbc997c2d7d45,{root}/share2,ro --cmdline 'quiet nvx_share=0-bd47413b5c03dfc6e4b5b8143fe205ea,/data,rw nvx_share=1-bf2faee2596026620b5cbc997c2d7d45,/other,ro'\n","stderr":""}]}, -{"name":"run, dry run: one shared file","steps":[{"argv":["run","--mount","/etc/single.txt,{root}/single.txt,ro","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-a80a05e9cb129bc27b7ba103bf2f5ac0,{root}/single.txt,ro,file --cmdline nvx_share=0-a80a05e9cb129bc27b7ba103bf2f5ac0,/etc/single.txt,ro,file\n","stderr":""}]}, -{"name":"run, dry run: one relative shared file","steps":[{"argv":["run","--mount","/etc/single.txt,single.txt","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-a80a05e9cb129bc27b7ba103bf2f5ac0,single.txt,ro,file --cmdline nvx_share=0-a80a05e9cb129bc27b7ba103bf2f5ac0,/etc/single.txt,ro,file\n","stderr":""}]}, -{"name":"run, dry run: a directory and a file","steps":[{"argv":["run","--mount","/work,{root}/share,rw","--mount","/config/single.txt,{root}/single.txt","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-0c9a453fad615c83c57d57c2b2be05fa,{root}/share,rw --mount-child 1-e4a388b9bb5f3ffa9c918a940c785615,{root}/single.txt,ro,file --cmdline 'nvx_share=0-0c9a453fad615c83c57d57c2b2be05fa,/work,rw nvx_share=1-e4a388b9bb5f3ffa9c918a940c785615,/config/single.txt,ro,file'\n","stderr":""}]}, -{"name":"run, dry run: host paths with commas","steps":[{"argv":["run","--mount","/work,{root}/alpha,beta,rw","--mount","/reports,{root}/2026, final,ro","--mount","/config/settings.json,{root}/settings,v2.json,ro","--mount-deny","{root}/alpha,beta/data.txt","--dry-run"],"write":{"alpha,beta/data.txt":"data\n","2026, final/data.txt":"data\n","settings,v2.json":"{}\n"},"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-0c9a453fad615c83c57d57c2b2be05fa,{root}/alpha,beta,rw --mount-child '1-420499c21ee058ef02f65f165f3d41da,{root}/2026, final,ro' --mount-child 2-67287998b6e12c15adb9346817eff41d,{root}/settings,v2.json,ro,file --mount-deny {root}/alpha,beta/data.txt --cmdline 'nvx_share=0-0c9a453fad615c83c57d57c2b2be05fa,/work,rw nvx_share=1-420499c21ee058ef02f65f165f3d41da,/reports,ro nvx_share=2-67287998b6e12c15adb9346817eff41d,/config/settings.json,ro,file'\n","stderr":""}]}, -{"name":"run, dry run: one directory with commas","steps":[{"argv":["run","--mount","/work,{root}/alpha,beta,rw","--dry-run"],"write":{"alpha,beta/data.txt":"data\n","2026, final/data.txt":"data\n","settings,v2.json":"{}\n"},"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount /work,{root}/alpha,beta,rw\n","stderr":""}]}, -{"name":"run, dry run: host path ending in a mode","steps":[{"argv":["run","--mount","/data,{root}/share,rw,ro","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount /data,{root}/share,rw,ro\n","stderr":""}]}, -{"name":"run, dry run: host path ending in a comma","steps":[{"argv":["run","--mount","/data,{root}/share,,rw","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount /data,{root}/share,,rw\n","stderr":""}]}, -{"name":"run, dry run: vmm owner","steps":[{"argv":["run","--mount","/data,{root}/share","--mount-owner","vmm","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount /data,{root}/share,ro --mount-owner vmm\n","stderr":""}]}, -{"name":"run, dry run: vmm owner of several shares","steps":[{"argv":["run","--mount","/data,{root}/share,rw","--mount","/other,{root}/share2","--mount-owner","vmm","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}/share,rw --mount-child 1-bf2faee2596026620b5cbc997c2d7d45,{root}/share2,ro --mount-owner vmm --cmdline 'nvx_share=0-bd47413b5c03dfc6e4b5b8143fe205ea,/data,rw nvx_share=1-bf2faee2596026620b5cbc997c2d7d45,/other,ro'\n","stderr":""}]}, -{"name":"run, dry run: restore with shares","steps":[{"argv":["run","--restore-snapshot","{root}/snapshot","--mount","/data,{root}/share,rw","--mount","/other,{root}/share2","--mount","/etc/single.txt,{root}/single.txt","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --restore-snapshot {root}/snapshot --mount-aggregate /run/nvx/shares --mount-child 0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}/share,rw --mount-child 1-bf2faee2596026620b5cbc997c2d7d45,{root}/share2,ro --mount-child 2-a80a05e9cb129bc27b7ba103bf2f5ac0,{root}/single.txt,ro,file\n","stderr":""}]}, -{"name":"run, dry run: restore with shares and a command line","steps":[{"argv":["run","--restore-snapshot","{root}/snapshot","--mount","/data,{root}/share,rw","--mount","/other,{root}/share2","--cmdline","quiet","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --restore-snapshot {root}/snapshot --mount-aggregate /run/nvx/shares --mount-child 0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}/share,rw --mount-child 1-bf2faee2596026620b5cbc997c2d7d45,{root}/share2,ro --cmdline quiet\n","stderr":""}]}, -{"name":"run, dry run: network","steps":[{"argv":["run","--net","10.0.0.2/24","--network-profile","portable","--network-egress","deny","--network-ingress","allow","--network-egress-allow","10.0.0.0/8:tcp:443","--network-egress-allow","2001:db8::/32","--network-egress-deny","10.1.0.0/16","--host-loopback","allow","--network-proxy","10.0.0.1:3128","--host-loopback-forward","tcp:8080:80","--host-loopback-forward","udp:5353:53","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --net 10.0.0.2/24 --network-profile portable --network-egress deny --network-ingress allow --network-egress-allow 10.0.0.0/8:tcp:443 --network-egress-allow 2001:db8::/32 --network-egress-deny 10.1.0.0/16 --host-loopback allow --network-proxy 10.0.0.1:3128 --host-loopback-forward tcp:8080:80 --host-loopback-forward udp:5353:53\n","stderr":""}]}, -{"name":"run, dry run: egress default","steps":[{"argv":["run","--network-egress","deny","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --network-egress deny\n","stderr":""}]}, -{"name":"run, dry run: host loopback forward","steps":[{"argv":["run","--host-loopback-forward","tcp:8080:80","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --host-loopback-forward tcp:8080:80\n","stderr":""}]}, -{"name":"run, dry run: egress policy file","steps":[{"argv":["run","--network-egress","deny","--network-egress-policy-file","{root}/policy.json","--dry-run"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"except\": [\"192.0.2.128/25\"]}, {\"cidr\": \"2001:db8::/32\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"198.51.100.0/24\", \"protocol\": \"udp\"}]}"},"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --network-egress deny --network-egress-allow 192.0.2.0/25 --network-egress-allow 2001:db8::/32:tcp:443 --network-egress-deny 198.51.100.0/24:udp\n","stderr":""}]}, -{"name":"run, dry run: empty egress policy file","steps":[{"argv":["run","--network-egress","allow","--network-egress-policy-file","{root}/./policy.json","--dry-run"],"write":{"policy.json":"{}"},"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --network-egress allow\n","stderr":""}]}, -{"name":"run, dry run: outcome report path","steps":[{"argv":["run","--outcome-report","reports//./outcome.json","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --microvm-report reports/outcome.json\n","stderr":""}]}, -{"name":"run, dry run: quoted command line","steps":[{"argv":["run","--cmdline","a=\"b c\" d","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --cmdline 'a=\"b c\" d'\n","stderr":""}]}, -{"name":"run, dry run: command line starting with a dash","steps":[{"argv":["run","--cmdline=-x","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --cmdline -x\n","stderr":""}]}, -{"name":"run, dry run: command line of help","steps":[{"argv":["run","--cmdline=--help","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --cmdline --help\n","stderr":""}]}, -{"name":"run, dry run: empty command line","steps":[{"argv":["run","--cmdline","","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz\n","stderr":""}]}, -{"name":"run, dry run: blank command line","steps":[{"argv":["run","--cmdline"," ","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --cmdline ' '\n","stderr":""}]}, -{"name":"run, dry run: last command line","steps":[{"argv":["run","--cmdline","a","--cmdline","b","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --cmdline b\n","stderr":""}]}, -{"name":"run, dry run: long command line of one directory share","steps":[{"argv":["run","--mount","/data,{root}/share","--cmdline","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount /data,{root}/share,ro --cmdline xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n","stderr":""}]}, -{"name":"run, dry run: restore without the budget","steps":[{"argv":["run","--restore-snapshot","{root}/snapshot","--mount","/share/00,{root}/share","--mount","/share/01,{root}/share","--mount","/share/02,{root}/share","--mount","/share/03,{root}/share","--mount","/share/04,{root}/share","--mount","/share/05,{root}/share","--mount","/share/06,{root}/share","--mount","/share/07,{root}/share","--mount","/share/08,{root}/share","--mount","/share/09,{root}/share","--mount","/share/10,{root}/share","--mount","/share/11,{root}/share","--mount","/share/12,{root}/share","--mount","/share/13,{root}/share","--mount","/share/14,{root}/share","--mount","/share/15,{root}/share","--mount","/share/16,{root}/share","--mount","/share/17,{root}/share","--mount","/share/18,{root}/share","--mount","/share/19,{root}/share","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --restore-snapshot {root}/snapshot --mount-aggregate /run/nvx/shares --mount-child 0-704877e89d67577706337193ea7633b4,{root}/share,ro --mount-child 1-932de0c49c6028fcd06c916b12e85dd0,{root}/share,ro --mount-child 2-8fe971438e3c6dc554c24acb8a258e68,{root}/share,ro --mount-child 3-07f68b1ee523306daef281712c084aa1,{root}/share,ro --mount-child 4-213df498e81ccc26ac4af55922a700ef,{root}/share,ro --mount-child 5-42c910809b4f1f69618448eeabb2ae5e,{root}/share,ro --mount-child 6-5023082ea84414bad3b03c04b52810d0,{root}/share,ro --mount-child 7-c1fab5a21a3b346322ba23c2e823471f,{root}/share,ro --mount-child 8-924dd7c11ac4cdf2fad054fad5f660f1,{root}/share,ro --mount-child 9-9e8477038c0405f8315bb3a972cf0b94,{root}/share,ro --mount-child 10-0637273ad7c907a15b9265a330a14394,{root}/share,ro --mount-child 11-085c8b2a421428955a7be66cbdac1217,{root}/share,ro --mount-child 12-7b8b460bdbaed75e2f245c36c494c8da,{root}/share,ro --mount-child 13-c759475ce548cda605edd48ff0349060,{root}/share,ro --mount-child 14-c7604fc1e13e1acaffa49a4fb7baba0a,{root}/share,ro --mount-child 15-f5de35f367fadbf3bfd873291f70902a,{root}/share,ro --mount-child 16-636f3a16dd53675d0d36ecbcfc93ce18,{root}/share,ro --mount-child 17-92813153a4c548a68fb66602ca92779c,{root}/share,ro --mount-child 18-b8f15bc78ddfccd02383fbbec973f623,{root}/share,ro --mount-child 19-482c6e9b01cb3bd040af96260661231d,{root}/share,ro\n","stderr":""}]}, -{"name":"run, dry run: budget fits","steps":[{"argv":["run","--mount","/a,{root}/share","--mount","/b,{root}/share2,rw","--cmdline","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-6a50dc8584134c7de537c0052ff6d236,{root}/share,ro --mount-child 1-9812b0b9d61e09b927d03ff93f64530d,{root}/share2,rw --cmdline 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx nvx_share=0-6a50dc8584134c7de537c0052ff6d236,/a,ro nvx_share=1-9812b0b9d61e09b927d03ff93f64530d,/b,rw'\n","stderr":""}]}, -{"name":"run, dry run: caller owner","steps":[{"argv":["run","--mount","/data,{root}/share","--mount-owner","caller","--dry-run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount /data,{root}/share,ro --mount-owner caller\n","stderr":""}]}, -{"name":"run, launch: boot","steps":[{"argv":["run"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz\nopenvmm: booted the microVM\n","stderr":""}]}, -{"name":"run, launch: exit status","steps":[{"argv":["run","--cmdline","fake_exit_status=7"],"status":7,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --cmdline fake_exit_status=7\nopenvmm: booted the microVM\n","stderr":""}]}, -{"name":"run, launch: failed boot","steps":[{"argv":["run","--cmdline","quiet fake_exit_status=1"],"status":1,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --cmdline 'quiet fake_exit_status=1'\nopenvmm: booted the microVM\n","stderr":""}]}, -{"name":"run, launch: Ubuntu","steps":[{"argv":["run","--guest","ubuntu","--memory-capacity-mib","1024"],"write":{"build/initramfs-ubuntu.cpio.gz":"ubuntu\n"},"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 512M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs-ubuntu.cpio.gz --memory-capacity 1024M\nopenvmm: booted the microVM\n","stderr":""}]}, -{"name":"run, launch: every boot option","steps":[{"argv":["run","--hypervisor","mshv","--processors","8","--cpu-profile","host","--memory-mib","256","--memory-capacity-mib","512"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 8 --hypervisor mshv --memory 256M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --memory-capacity 512M --cpu-profile host\nopenvmm: booted the microVM\n","stderr":""}]}, -{"name":"run, launch: restore","steps":[{"argv":["run","--processors","4","--restore-snapshot","{root}/snapshot","--restore-processors","2","--restore-memory-mib","1024","--restore-ready-path","{root}/ready.sock","--cpu-profile","auto"],"write":{"snapshot/state.bin":"snapshot\n"},"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 4 --hypervisor kvm --restore-snapshot {root}/snapshot --restore-processors 2 --restore-memory 1024M --restore-ready-path {root}/ready.sock --cpu-profile auto\nopenvmm: restored the microVM\n","stderr":""}]}, -{"name":"run, launch: restore without guest artifacts","steps":[{"argv":["run","--restore-snapshot","{root}/snapshot"],"write":{"snapshot/state.bin":"snapshot\n"},"remove":["build/vmlinux","build/initramfs.cpio.gz"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --restore-snapshot {root}/snapshot\nopenvmm: restored the microVM\n","stderr":""}]}, -{"name":"run, launch: missing snapshot","steps":[{"argv":["run","--restore-snapshot","{root}/missing","--cmdline","quiet"],"status":1,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --restore-snapshot {root}/missing --cmdline quiet\n","stderr":"openvmm: cannot restore {root}/missing: no such snapshot directory\n"}]}, -{"name":"run, launch: outcome report","steps":[{"argv":["run","--outcome-report","{root}/reports/openvmm-run.json"],"check":["reports/openvmm-run.json","build/fake-openvmm-reports.json"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --microvm-report {root}/reports/openvmm-run.json\nopenvmm: booted the microVM\n","stderr":"","files":{"reports/openvmm-run.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\": \"run\",\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"},"build/fake-openvmm-reports.json":{"text":"[\"--single-process\",\"--machine\",\"microvm\",\"--processors\",\"1\",\"--hypervisor\",\"kvm\",\"--memory\",\"128M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--microvm-report\",\"{root}/reports/openvmm-run.json\"]"}}}]}, -{"name":"run, launch: restore outcome report","steps":[{"argv":["run","--restore-snapshot","{root}/snapshot","--outcome-report","{root}/reports/openvmm-run.json","--cmdline","fake_exit_status=4"],"write":{"snapshot/state.bin":"snapshot\n"},"check":["reports/openvmm-run.json","fake-openvmm-reports.json"],"status":4,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --restore-snapshot {root}/snapshot --microvm-report {root}/reports/openvmm-run.json --cmdline fake_exit_status=4\nopenvmm: restored the microVM\n","stderr":"","files":{"reports/openvmm-run.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\": \"guest-exit\",\n \"operation\": \"run\",\n \"status_code\": 4\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"},"fake-openvmm-reports.json":{"text":"[\"--single-process\",\"--machine\",\"microvm\",\"--processors\",\"1\",\"--hypervisor\",\"kvm\",\"--restore-snapshot\",\"{root}/snapshot\",\"--microvm-report\",\"{root}/reports/openvmm-run.json\",\"--cmdline\",\"fake_exit_status=4\"]"}}}]}, -{"name":"run, launch: network outcome report","steps":[{"argv":["run","--net","10.0.0.2/24","--network-profile","portable","--network-egress","deny","--network-egress-allow","10.0.0.0/8:tcp:443","--host-loopback","deny","--outcome-report","{root}/reports/openvmm-run.json"],"check":["reports/openvmm-run.json"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --net 10.0.0.2/24 --network-profile portable --network-egress deny --network-egress-allow 10.0.0.0/8:tcp:443 --host-loopback deny --microvm-report {root}/reports/openvmm-run.json\nopenvmm: booted the microVM\n","stderr":"","files":{"reports/openvmm-run.json":{"text":"{\n \"backend\": \"kvm\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 1,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"deny\",\n \"mode\": \"rules\",\n \"status\": \"applied\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"run\",\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"}}}]}, -{"name":"run, launch: one share","steps":[{"argv":["run","--mount","/data,{root}/share,rw","--mount-deny","hidden","--mount-allow","hidden/shown","--mount-write","writable"],"check":["build/fake-openvmm-.json"],"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount /data,{root}/share,rw --mount-deny hidden --mount-allow hidden/shown --mount-write writable\nopenvmm: booted the microVM\n","stderr":"","files":{"build/fake-openvmm-.json":{"text":"[\"--single-process\",\"--machine\",\"microvm\",\"--processors\",\"1\",\"--hypervisor\",\"kvm\",\"--memory\",\"128M\",\"--kernel\",\"{root}/build/vmlinux\",\"--initrd\",\"{root}/build/initramfs.cpio.gz\",\"--mount\",\"/data,{root}/share,rw\",\"--mount-deny\",\"hidden\",\"--mount-allow\",\"hidden/shown\",\"--mount-write\",\"writable\"]"}}}]}, -{"name":"run, launch: several shares and a file","steps":[{"argv":["run","--mount","/data,{root}/share","--mount","/single.txt,{root}/single.txt","--mount-deny","{root}/share/hidden","--cmdline","fake_exit_status=3"],"status":3,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}/share,ro --mount-child 1-aa0054d8b9fab367d76492228c7bb459,{root}/single.txt,ro,file --mount-deny {root}/share/hidden --cmdline 'fake_exit_status=3 nvx_share=0-bd47413b5c03dfc6e4b5b8143fe205ea,/data,ro nvx_share=1-aa0054d8b9fab367d76492228c7bb459,/single.txt,ro,file'\nopenvmm: booted the microVM\n","stderr":""}]}, -{"name":"run, launch: OpenVMM refuses its options","steps":[{"argv":["run","--host-loopback-forward","tcp:8080:80"],"status":2,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz --host-loopback-forward tcp:8080:80\n","stderr":"openvmm: --host-loopback-forward requires explicit --host-loopback allow\n"}]}, -{"name":"run, launch: relative OpenVMM override","steps":[{"argv":["run"],"env":{"NVX_OPENVMM":"openvmm/target/release/openvmm{exe}"},"status":0,"stdout":">> {root}/openvmm/target/release/openvmm --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}/build/vmlinux --initrd {root}/build/initramfs.cpio.gz\nopenvmm: booted the microVM\n","stderr":""}]}, -{"name":"run, launch: missing OpenVMM","steps":[{"argv":["run"],"remove":["openvmm/target/release/openvmm{exe}"],"status":1,"stdout":"","stderr":"error[artifact-missing]: OpenVMM release binary not found: {root}/openvmm/target/release/openvmm\n"}]}, -{"name":"run, launch: missing kernel","steps":[{"argv":["run"],"remove":["build/vmlinux"],"status":1,"stdout":"","stderr":"error[artifact-missing]: Linux direct kernel not found: {root}/build/vmlinux\n"}]}, -{"name":"run, launch: missing initramfs","steps":[{"argv":["run"],"remove":["build/initramfs.cpio.gz"],"status":1,"stdout":"","stderr":"error[artifact-missing]: Alpine Linux initramfs not found: {root}/build/initramfs.cpio.gz\n"}]}, -{"name":"run, launch: missing Ubuntu initramfs","steps":[{"argv":["run","--guest","ubuntu"],"status":1,"stdout":"","stderr":"error[artifact-missing]: Ubuntu Base initramfs not found: {root}/build/initramfs-ubuntu.cpio.gz\n"}]} -], -"windows": [ -{"name":"egress compile: empty","steps":[{"argv":["egress","compile","{root}\\policy.json"],"write":{"policy.json":"{}"},"status":0,"stdout":"{\r\n \"allow\": [],\r\n \"deny\": []\r\n}\r\n","stderr":""}]}, -{"name":"egress compile: allow","steps":[{"argv":["egress","compile","{root}\\policy.json"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\"}]}"},"status":0,"stdout":"{\r\n \"allow\": [\r\n \"192.0.2.0/24\"\r\n ],\r\n \"deny\": []\r\n}\r\n","stderr":""}]}, -{"name":"egress compile: both","steps":[{"argv":["egress","compile","{root}\\policy.json"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"except\": [\"192.0.2.128/25\"]}, {\"to\": [{\"cidr\": \"2001:db8::/32\"}], \"ports\": [{\"protocol\": \"tcp\", \"port\": 80, \"endPort\": 81}]}], \"deny\": [{\"cidr\": \"198.51.100.0/24\", \"protocol\": \"icmp\"}]}"},"status":0,"stdout":"{\r\n \"allow\": [\r\n \"192.0.2.0/25\",\r\n \"2001:db8::/32:tcp:80-81\"\r\n ],\r\n \"deny\": [\r\n \"198.51.100.0/24:icmp\"\r\n ]\r\n}\r\n","stderr":""}]}, -{"name":"egress compile: invalid JSON","steps":[{"argv":["egress","compile","{root}\\policy.json"],"write":{"policy.json":"{"},"status":1,"stdout":"","stderr":"error[unsupported]: egress policy file {root}\\policy.json is not valid JSON: EOF while parsing an object at line 1 column 1\r\n"}]}, -{"name":"egress compile: invalid rule","steps":[{"argv":["egress","compile","{root}\\policy.json"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"port\": 70000}]}"},"status":1,"stdout":"","stderr":"error[unsupported]: allow[0].port requires protocol\r\n"}]}, -{"name":"egress compile: unknown field","steps":[{"argv":["egress","compile","{root}\\policy.json"],"write":{"policy.json":"{\"allow\": [], \"other\": []}"},"status":1,"stdout":"","stderr":"error[unsupported]: egress policy has unknown field \"other\"\r\n"}]}, -{"name":"egress compile: missing file","steps":[{"argv":["egress","compile","{root}\\missing.json"],"status":1,"stdout":"","stderr":"error[io]: failed to read egress policy file: {root}\\missing.json\r\n"}]}, -{"name":"egress compile: directory","steps":[{"argv":["egress","compile","{root}\\share"],"status":1,"stdout":"","stderr":"error[io]: failed to read egress policy file: {root}\\share\r\n"}]}, -{"name":"artifacts: checkout","steps":[{"argv":["artifacts"],"status":0,"stdout":"{\r\n \"guests\": [\r\n {\r\n \"distribution\": \"Alpine Linux\",\r\n \"distro_layer\": null,\r\n \"distro_manifest\": null,\r\n \"initramfs\": \"{root_json}\\\\build\\\\initramfs.cpio.gz\",\r\n \"name\": \"alpine\",\r\n \"package_manifest\": \"{root_json}\\\\build\\\\initramfs.cpio.gz.packages.json\"\r\n },\r\n {\r\n \"distribution\": \"Ubuntu Base\",\r\n \"distro_layer\": \"{root_json}\\\\build\\\\ubuntu-distro.erofs\",\r\n \"distro_manifest\": \"{root_json}\\\\build\\\\ubuntu-distro.erofs.manifest.json\",\r\n \"initramfs\": \"{root_json}\\\\build\\\\initramfs-ubuntu.cpio.gz\",\r\n \"name\": \"ubuntu\",\r\n \"package_manifest\": \"{root_json}\\\\build\\\\initramfs-ubuntu.cpio.gz.packages.json\"\r\n },\r\n {\r\n \"distribution\": \"Azure Linux\",\r\n \"distro_layer\": null,\r\n \"distro_manifest\": null,\r\n \"initramfs\": \"{root_json}\\\\build\\\\initramfs-azurelinux.cpio.gz\",\r\n \"name\": \"azurelinux\",\r\n \"package_manifest\": \"{root_json}\\\\build\\\\initramfs-azurelinux.cpio.gz.packages.json\"\r\n }\r\n ],\r\n \"kernel\": \"{root_json}\\\\build\\\\vmlinux\",\r\n \"layout\": \"repository\",\r\n \"openvmm\": \"{root_json}\\\\openvmm\\\\target\\\\release\\\\openvmm.exe\",\r\n \"root\": \"{root_json}\"\r\n}\r\n","stderr":""}]}, -{"name":"artifacts: OpenVMM override","steps":[{"argv":["artifacts"],"env":{"NVX_OPENVMM":"{root}\\alt\\openvmm{exe}"},"status":0,"stdout":"{\r\n \"guests\": [\r\n {\r\n \"distribution\": \"Alpine Linux\",\r\n \"distro_layer\": null,\r\n \"distro_manifest\": null,\r\n \"initramfs\": \"{root_json}\\\\build\\\\initramfs.cpio.gz\",\r\n \"name\": \"alpine\",\r\n \"package_manifest\": \"{root_json}\\\\build\\\\initramfs.cpio.gz.packages.json\"\r\n },\r\n {\r\n \"distribution\": \"Ubuntu Base\",\r\n \"distro_layer\": \"{root_json}\\\\build\\\\ubuntu-distro.erofs\",\r\n \"distro_manifest\": \"{root_json}\\\\build\\\\ubuntu-distro.erofs.manifest.json\",\r\n \"initramfs\": \"{root_json}\\\\build\\\\initramfs-ubuntu.cpio.gz\",\r\n \"name\": \"ubuntu\",\r\n \"package_manifest\": \"{root_json}\\\\build\\\\initramfs-ubuntu.cpio.gz.packages.json\"\r\n },\r\n {\r\n \"distribution\": \"Azure Linux\",\r\n \"distro_layer\": null,\r\n \"distro_manifest\": null,\r\n \"initramfs\": \"{root_json}\\\\build\\\\initramfs-azurelinux.cpio.gz\",\r\n \"name\": \"azurelinux\",\r\n \"package_manifest\": \"{root_json}\\\\build\\\\initramfs-azurelinux.cpio.gz.packages.json\"\r\n }\r\n ],\r\n \"kernel\": \"{root_json}\\\\build\\\\vmlinux\",\r\n \"layout\": \"repository\",\r\n \"openvmm\": \"{root_json}\\\\alt\\\\openvmm.exe\",\r\n \"root\": \"{root_json}\"\r\n}\r\n","stderr":""}]}, -{"name":"usage: help","steps":[{"argv":["sandbox","-h"],"status":0,"stdout":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\n\r\npositional arguments:\r\n {run,provision,start,exec,stop,deprovision}\r\n\r\noptions:\r\n -h, --help show this help message and exit\r\n --layer ROLE,PATH,EROFS_UUID\r\n --scratch SCRATCH\r\n --state-dir STATE_DIR\r\n --entrypoint ENTRYPOINT\r\n --arg SANDBOX_ARG\r\n --hostname HOSTNAME\r\n --workload-user UID:GID\r\n fixed non-root workload identity (default:\r\n 65534:65534)\r\n --memory-max MEMORY_MAX\r\n --pids-max PIDS_MAX\r\n --memory-mib MEMORY_MIB\r\n --timeout TIMEOUT control operation timeout, and the longest wait for\r\n another lifecycle transition of the sandbox, in\r\n seconds (default: 60)\r\n --exec-timeout-ms EXEC_TIMEOUT_MS\r\n guest workload timeout in milliseconds; zero disables\r\n it\r\n --cwd CWD absolute guest working directory for managed exec\r\n (default: /)\r\n --environment KEY=VALUE\r\n set the exact managed exec environment; repeat for\r\n multiple entries\r\n --environment-file PATH\r\n read the exact managed exec environment from a JSON\r\n string array\r\n --inherit-default-environment\r\n layer the managed exec environment over the guest\r\n default environment instead of replacing it\r\n --hypervisor {auto,whp,kvm,mshv}\r\n --mount GUEST_TARGET,HOST_PATH[,ro|rw]\r\n live-share a host directory, or a single regular host\r\n file without its directory, inside the container\r\n rootfs; the mode follows the last comma, so HOST_PATH\r\n may contain commas when the mode is given; repeat to\r\n attach more shares, each with its own target and mode,\r\n as children of one virtio-fs device\r\n --mount-deny HOST_PATH\r\n hide one existing path inside a --mount host\r\n directory; with several --mount options, it applies to\r\n the --mount before it\r\n --mount-allow HOST_PATH\r\n expose one existing path inside a --mount-deny path of\r\n the same share again; the hidden directories on the\r\n way list only it\r\n --mount-write HOST_PATH\r\n make one existing path one of the only writable parts\r\n of a read-write --mount; the rest of the share is\r\n read-only\r\n --mount-owner {vmm,caller}\r\n host identity of the share's file operations: vmm\r\n (default) or caller, the workload identity with guest\r\n root squashed to the owner of the shared directory or\r\n file (Linux only)\r\n --net IPV4/PREFIX\r\n --network-profile {portable}\r\n --network-egress {allow,deny}\r\n --network-ingress {allow,deny}\r\n --network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]\r\n allow guest egress to an IPv4 or IPv6 CIDR, optionally\r\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\r\n udp only on PORT or on the inclusive range PORT-PORT;\r\n repeat to add rules\r\n --network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]\r\n deny guest egress to an IPv4 or IPv6 CIDR, optionally\r\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\r\n udp only on PORT or on the inclusive range PORT-PORT;\r\n repeat to add rules\r\n --network-egress-policy-file PATH\r\n load bounded IPv4 and IPv6 ranges and rule-local\r\n exclusions for run/provision\r\n --host-loopback {allow,deny}\r\n --network-proxy IPV4:TCP-PORT\r\n --host-loopback-forward HOST_LOOPBACK_FORWARD\r\n --outcome-report OUTCOME_REPORT\r\n write a bounded local JSON outcome report for run or\r\n exec\r\n --cmdline CMDLINE\r\n --dry-run print the one-shot run command without launching it\r\n","stderr":""}]}, -{"name":"usage: help after operation","steps":[{"argv":["sandbox","exec","--help"],"status":0,"stdout":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\n\r\npositional arguments:\r\n {run,provision,start,exec,stop,deprovision}\r\n\r\noptions:\r\n -h, --help show this help message and exit\r\n --layer ROLE,PATH,EROFS_UUID\r\n --scratch SCRATCH\r\n --state-dir STATE_DIR\r\n --entrypoint ENTRYPOINT\r\n --arg SANDBOX_ARG\r\n --hostname HOSTNAME\r\n --workload-user UID:GID\r\n fixed non-root workload identity (default:\r\n 65534:65534)\r\n --memory-max MEMORY_MAX\r\n --pids-max PIDS_MAX\r\n --memory-mib MEMORY_MIB\r\n --timeout TIMEOUT control operation timeout, and the longest wait for\r\n another lifecycle transition of the sandbox, in\r\n seconds (default: 60)\r\n --exec-timeout-ms EXEC_TIMEOUT_MS\r\n guest workload timeout in milliseconds; zero disables\r\n it\r\n --cwd CWD absolute guest working directory for managed exec\r\n (default: /)\r\n --environment KEY=VALUE\r\n set the exact managed exec environment; repeat for\r\n multiple entries\r\n --environment-file PATH\r\n read the exact managed exec environment from a JSON\r\n string array\r\n --inherit-default-environment\r\n layer the managed exec environment over the guest\r\n default environment instead of replacing it\r\n --hypervisor {auto,whp,kvm,mshv}\r\n --mount GUEST_TARGET,HOST_PATH[,ro|rw]\r\n live-share a host directory, or a single regular host\r\n file without its directory, inside the container\r\n rootfs; the mode follows the last comma, so HOST_PATH\r\n may contain commas when the mode is given; repeat to\r\n attach more shares, each with its own target and mode,\r\n as children of one virtio-fs device\r\n --mount-deny HOST_PATH\r\n hide one existing path inside a --mount host\r\n directory; with several --mount options, it applies to\r\n the --mount before it\r\n --mount-allow HOST_PATH\r\n expose one existing path inside a --mount-deny path of\r\n the same share again; the hidden directories on the\r\n way list only it\r\n --mount-write HOST_PATH\r\n make one existing path one of the only writable parts\r\n of a read-write --mount; the rest of the share is\r\n read-only\r\n --mount-owner {vmm,caller}\r\n host identity of the share's file operations: vmm\r\n (default) or caller, the workload identity with guest\r\n root squashed to the owner of the shared directory or\r\n file (Linux only)\r\n --net IPV4/PREFIX\r\n --network-profile {portable}\r\n --network-egress {allow,deny}\r\n --network-ingress {allow,deny}\r\n --network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]\r\n allow guest egress to an IPv4 or IPv6 CIDR, optionally\r\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\r\n udp only on PORT or on the inclusive range PORT-PORT;\r\n repeat to add rules\r\n --network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]\r\n deny guest egress to an IPv4 or IPv6 CIDR, optionally\r\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\r\n udp only on PORT or on the inclusive range PORT-PORT;\r\n repeat to add rules\r\n --network-egress-policy-file PATH\r\n load bounded IPv4 and IPv6 ranges and rule-local\r\n exclusions for run/provision\r\n --host-loopback {allow,deny}\r\n --network-proxy IPV4:TCP-PORT\r\n --host-loopback-forward HOST_LOOPBACK_FORWARD\r\n --outcome-report OUTCOME_REPORT\r\n write a bounded local JSON outcome report for run or\r\n exec\r\n --cmdline CMDLINE\r\n --dry-run print the one-shot run command without launching it\r\n","stderr":""}]}, -{"name":"usage: timeout not a number","steps":[{"argv":["sandbox","--timeout","x"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --timeout: invalid positive_float value: 'x'\r\n"}]}, -{"name":"usage: zero timeout","steps":[{"argv":["sandbox","--timeout","0"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --timeout: must be finite and greater than 0\r\n"}]}, -{"name":"usage: negative timeout","steps":[{"argv":["sandbox","--timeout","-1"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --timeout: must be finite and greater than 0\r\n"}]}, -{"name":"usage: infinite timeout","steps":[{"argv":["sandbox","--timeout","inf"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --timeout: must be finite and greater than 0\r\n"}]}, -{"name":"usage: timeout not finite","steps":[{"argv":["sandbox","--timeout=1e400"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --timeout: must be finite and greater than 0\r\n"}]}, -{"name":"usage: timeout not a number either","steps":[{"argv":["sandbox","--timeout","nan"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --timeout: must be finite and greater than 0\r\n"}]}, -{"name":"usage: exec timeout not an integer","steps":[{"argv":["sandbox","--exec-timeout-ms","1.5"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --exec-timeout-ms: invalid int value: '1.5'\r\n"}]}, -{"name":"usage: memory not an integer","steps":[{"argv":["sandbox","--memory-mib","x"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --memory-mib: invalid int value: 'x'\r\n"}]}, -{"name":"usage: invalid hypervisor","steps":[{"argv":["sandbox","--hypervisor","hyperv"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --hypervisor: invalid choice: 'hyperv' (choose from 'auto', 'whp', 'kvm', 'mshv')\r\n"}]}, -{"name":"usage: invalid operation","steps":[{"argv":["sandbox","restart"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument sandbox_operation: invalid choice: 'restart' (choose from 'run', 'provision', 'start', 'exec', 'stop', 'deprovision')\r\n"}]}, -{"name":"usage: second operation","steps":[{"argv":["sandbox","run","start"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\r\n {artifacts,egress,run,sandbox} ...\r\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: start\r\n"}]}, -{"name":"usage: invalid mount owner","steps":[{"argv":["sandbox","--mount-owner","root"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --mount-owner: invalid choice: 'root' (choose from 'vmm', 'caller')\r\n"}]}, -{"name":"usage: invalid network profile","steps":[{"argv":["sandbox","--network-profile","open"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --network-profile: invalid choice: 'open' (choose from 'portable')\r\n"}]}, -{"name":"usage: invalid egress default","steps":[{"argv":["sandbox","--network-egress","block"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --network-egress: invalid choice: 'block' (choose from 'allow', 'deny')\r\n"}]}, -{"name":"usage: invalid host loopback","steps":[{"argv":["sandbox","--host-loopback","yes"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --host-loopback: invalid choice: 'yes' (choose from 'allow', 'deny')\r\n"}]}, -{"name":"usage: missing value","steps":[{"argv":["sandbox","--layer"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-missing]: argument --layer: expected one argument\r\n"}]}, -{"name":"usage: option as value","steps":[{"argv":["sandbox","--layer","--scratch"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-missing]: argument --layer: expected one argument\r\n"}]}, -{"name":"usage: dash value","steps":[{"argv":["sandbox","--arg","-x"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-missing]: argument --arg: expected one argument\r\n"}]}, -{"name":"usage: flag with value","steps":[{"argv":["sandbox","--dry-run=1"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --dry-run: ignored explicit argument '1'\r\n"}]}, -{"name":"usage: unrecognized option","steps":[{"argv":["sandbox","--bogus"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\r\n {artifacts,egress,run,sandbox} ...\r\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: --bogus\r\n"}]}, -{"name":"usage: unrecognized short option","steps":[{"argv":["sandbox","-x"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\r\n {artifacts,egress,run,sandbox} ...\r\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: -x\r\n"}]}, -{"name":"usage: unrecognized after separator","steps":[{"argv":["sandbox","run","--","extra"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\r\n {artifacts,egress,run,sandbox} ...\r\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: extra\r\n"}]}, -{"name":"validation: dry run outside run","steps":[{"argv":["sandbox","provision","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --dry-run is only valid for sandbox run\r\n"}]}, -{"name":"validation: environment and environment file","steps":[{"argv":["sandbox","exec","--environment","A=1","--environment-file","{root}\\env.json"],"write":{"env.json":"[\"A=1\"]"},"status":1,"stdout":"","stderr":"error[unsupported]: --environment and --environment-file are mutually exclusive\r\n"}]}, -{"name":"validation: cwd outside exec","steps":[{"argv":["sandbox","run","--cwd","/"],"status":1,"stdout":"","stderr":"error[unsupported]: managed execution options require the sandbox exec operation\r\n"}]}, -{"name":"validation: environment outside exec","steps":[{"argv":["sandbox","start","--environment","A=1"],"status":1,"stdout":"","stderr":"error[unsupported]: managed execution options require the sandbox exec operation\r\n"}]}, -{"name":"validation: environment file outside exec","steps":[{"argv":["sandbox","provision","--environment-file","{root}\\env.json"],"write":{"env.json":"[\"A=1\"]"},"status":1,"stdout":"","stderr":"error[unsupported]: managed execution options require the sandbox exec operation\r\n"}]}, -{"name":"validation: inherited environment outside exec","steps":[{"argv":["sandbox","stop","--inherit-default-environment"],"status":1,"stdout":"","stderr":"error[unsupported]: managed execution options require the sandbox exec operation\r\n"}]}, -{"name":"validation: environment file too large","steps":[{"argv":["sandbox","exec","--environment-file","{root}\\env.json"],"write":{"env.json":{"fill":" ","size":1048577}},"status":1,"stdout":"","stderr":"error[unsupported]: managed execution environment file exceeds 1048576-byte limit\r\n"}]}, -{"name":"validation: environment file at the limit","steps":[{"argv":["sandbox","exec","--environment-file","{root}\\env.json"],"write":{"env.json":{"text":"[\"A=1\"]","fill":" ","size":1048576}},"status":1,"stdout":"","stderr":"error[unsupported]: sandbox exec requires --state-dir\r\n"}]}, -{"name":"validation: environment file missing","steps":[{"argv":["sandbox","exec","--environment-file","{root}\\missing.json"],"status":1,"stdout":"","stderr":"error[unsupported]: failed to read managed execution environment: {root}\\missing.json\r\n"}]}, -{"name":"validation: environment file directory","steps":[{"argv":["sandbox","exec","--environment-file","{root}\\share"],"status":1,"stdout":"","stderr":"error[unsupported]: failed to read managed execution environment: {root}\\share\r\n"}]}, -{"name":"validation: environment file not UTF-8","steps":[{"argv":["sandbox","exec","--environment-file","{root}\\env.json"],"write":{"env.json":{"hex":"5b22ff225d"}},"status":1,"stdout":"","stderr":"error[unsupported]: failed to read managed execution environment: {root}\\env.json\r\n"}]}, -{"name":"validation: environment file not JSON","steps":[{"argv":["sandbox","exec","--environment-file","{root}\\env.json"],"write":{"env.json":"[\"A=1\""},"status":1,"stdout":"","stderr":"error[unsupported]: failed to read managed execution environment: {root}\\env.json\r\n"}]}, -{"name":"validation: environment file object","steps":[{"argv":["sandbox","exec","--environment-file","{root}\\env.json"],"write":{"env.json":"{\"A\": \"1\"}"},"status":1,"stdout":"","stderr":"error[unsupported]: managed execution environment file must contain a JSON array of KEY=VALUE strings\r\n"}]}, -{"name":"validation: environment file non-string","steps":[{"argv":["sandbox","exec","--environment-file","{root}\\env.json"],"write":{"env.json":"[\"A=1\", 2]"},"status":1,"stdout":"","stderr":"error[unsupported]: managed execution environment file must contain a JSON array of KEY=VALUE strings\r\n"}]}, -{"name":"validation: environment file entry without equals","steps":[{"argv":["sandbox","exec","--environment-file","{root}\\env.json"],"write":{"env.json":"[\"A\"]"},"status":1,"stdout":"","stderr":"error[unsupported]: managed exec environment entries must be non-empty KEY=VALUE strings of at most 4096 bytes\r\n"}]}, -{"name":"validation: environment file entry with NUL","steps":[{"argv":["sandbox","exec","--environment-file","{root}\\env.json"],"write":{"env.json":"[\"A=\\u0000\"]"},"status":1,"stdout":"","stderr":"error[unsupported]: managed exec environment entries must be non-empty KEY=VALUE strings of at most 4096 bytes\r\n"}]}, -{"name":"validation: environment file duplicate entry","steps":[{"argv":["sandbox","exec","--environment-file","{root}\\env.json"],"write":{"env.json":"[\"A=1\", \"A=2\"]"},"status":1,"stdout":"","stderr":"error[unsupported]: managed exec environment contains duplicate key: A\r\n"}]}, -{"name":"validation: environment entry without name","steps":[{"argv":["sandbox","exec","--environment","=x"],"status":1,"stdout":"","stderr":"error[unsupported]: managed exec environment entries must be non-empty KEY=VALUE strings of at most 4096 bytes\r\n"}]}, -{"name":"validation: environment entry with space","steps":[{"argv":["sandbox","exec","--environment","A B=x"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox exec requires --state-dir\r\n"}]}, -{"name":"validation: network outside run","steps":[{"argv":["sandbox","start","--net","10.0.0.2/24"],"status":1,"stdout":"","stderr":"error[unsupported]: network policy options are only valid for sandbox run or provision\r\n"}]}, -{"name":"validation: egress rule outside run","steps":[{"argv":["sandbox","exec","--network-egress-allow","10.0.0.0/8"],"status":1,"stdout":"","stderr":"error[unsupported]: network policy options are only valid for sandbox run or provision\r\n"}]}, -{"name":"validation: forward outside run","steps":[{"argv":["sandbox","stop","--host-loopback-forward","80"],"status":1,"stdout":"","stderr":"error[unsupported]: network policy options are only valid for sandbox run or provision\r\n"}]}, -{"name":"validation: policy file outside run","steps":[{"argv":["sandbox","deprovision","--network-egress-policy-file","{root}\\policy.json"],"status":1,"stdout":"","stderr":"error[unsupported]: network policy options are only valid for sandbox run or provision\r\n"}]}, -{"name":"validation: systemd entrypoint of run","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--entrypoint","/usr/lib/systemd/systemd"],"status":1,"stdout":"","stderr":"error[unsupported]: systemd entrypoints are unsupported by the sandbox security profile\r\n"}]}, -{"name":"validation: systemd entrypoint of exec","steps":[{"argv":["sandbox","exec","--entrypoint","/lib/systemd/systemd"],"status":1,"stdout":"","stderr":"error[unsupported]: systemd entrypoints are unsupported by the sandbox security profile\r\n"}]}, -{"name":"validation: outcome report outside run","steps":[{"argv":["sandbox","provision","--outcome-report","{root}\\reports\\exec.json"],"status":1,"stdout":"","stderr":"error[unsupported]: --outcome-report is only valid for one-shot run or managed exec\r\n"}]}, -{"name":"validation: deny without mount","steps":[{"argv":["sandbox","run","--mount-deny","{root}\\share\\hidden"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-deny requires --mount\r\n"}]}, -{"name":"validation: allow without mount","steps":[{"argv":["sandbox","run","--mount-allow","{root}\\share\\hidden"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-allow requires --mount\r\n"}]}, -{"name":"validation: write without mount","steps":[{"argv":["sandbox","run","--mount-write","{root}\\share\\writable"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-write requires --mount\r\n"}]}, -{"name":"validation: owner without mount","steps":[{"argv":["sandbox","run","--mount-owner","vmm"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-owner requires --mount\r\n"}]}, -{"name":"validation: mount outside run","steps":[{"argv":["sandbox","start","--mount","/data,{root}\\share"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount is only valid for sandbox run or provision\r\n"}]}, -{"name":"validation: net without profile","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--net","10.0.0.2/24"],"status":1,"stdout":"","stderr":"error[unsupported]: --net and --network-profile must be specified together\r\n"}]}, -{"name":"validation: profile without net","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--network-profile","portable"],"status":1,"stdout":"","stderr":"error[unsupported]: --net and --network-profile must be specified together\r\n"}]}, -{"name":"validation: run without layers","steps":[{"argv":["sandbox","run"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox run requires --layer and --scratch\r\n"}]}, -{"name":"validation: provision without scratch","steps":[{"argv":["sandbox","provision","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox provision requires --layer and --scratch\r\n"}]}, -{"name":"validation: run without layer","steps":[{"argv":["sandbox","run","--scratch","{root}\\scratch.ext4"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox run requires --layer and --scratch\r\n"}]}, -{"name":"validation: policy file with rules","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--network-egress","allow","--network-egress-policy-file","{root}\\policy.json","--network-egress-deny","10.0.0.0/8"],"status":1,"stdout":"","stderr":"error[unsupported]: --network-egress-policy-file cannot be combined with --network-egress-allow or --network-egress-deny\r\n"}]}, -{"name":"validation: policy file without egress","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--network-egress-policy-file","{root}\\policy.json"],"status":1,"stdout":"","stderr":"error[unsupported]: --network-egress is required with --network-egress-policy-file\r\n"}]}, -{"name":"validation: policy file missing","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--network-egress","deny","--network-egress-policy-file","{root}\\missing.json"],"status":1,"stdout":"","stderr":"error[io]: failed to read egress policy file: {root}\\missing.json\r\n"}]}, -{"name":"validation: policy file invalid","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--network-egress","deny","--network-egress-policy-file","{root}\\policy.json"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"10.0.0.0/8\", \"port\": 0}]}"},"status":1,"stdout":"","stderr":"error[unsupported]: allow[0].port requires protocol\r\n"}]}, -{"name":"validation: provision without state directory","steps":[{"argv":["sandbox","provision","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox provision requires --state-dir\r\n"}]}, -{"name":"validation: start without state directory","steps":[{"argv":["sandbox","start"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox start requires --state-dir\r\n"}]}, -{"name":"validation: exec without state directory","steps":[{"argv":["sandbox","exec"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox exec requires --state-dir\r\n"}]}, -{"name":"validation: stop without state directory","steps":[{"argv":["sandbox","stop"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox stop requires --state-dir\r\n"}]}, -{"name":"validation: deprovision without state directory","steps":[{"argv":["sandbox","deprovision"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox deprovision requires --state-dir\r\n"}]}, -{"name":"validation: run with state directory","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--state-dir","{root}\\state"],"status":1,"stdout":"","stderr":"error[unsupported]: one-shot sandbox execution rejects persistent --state-dir settings\r\n"}]}, -{"name":"validation: invalid layer UUID","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,nope","--scratch","{root}\\scratch.ext4"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --layer: distro layer UUID is invalid: 'nope'\r\n"}]}, -{"name":"validation: invalid layer role","steps":[{"argv":["sandbox","run","--layer","base,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --layer: unsupported layer role 'base'; choose distro\r\n"}]}, -{"name":"validation: retired layer role","steps":[{"argv":["sandbox","run","--layer","runtime,{root}\\runtime.erofs,22222222-2222-2222-2222-222222222222"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --layer: unsupported layer role 'runtime'; choose distro\r\n"}]}, -{"name":"validation: missing layer","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\missing.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"status":1,"stdout":"","stderr":"error[unavailable]: distro EROFS layer not found: {root}\\missing.erofs\r\n"}]}, -{"name":"validation: duplicate layer","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"status":1,"stdout":"","stderr":"error[unsupported]: duplicate sandbox layer role(s): distro\r\n"}]}, -{"name":"validation: missing scratch","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\missing.ext4"],"status":1,"stdout":"","stderr":"error[unavailable]: ext4 scratch image not found: {root}\\missing.ext4\r\n"}]}, -{"name":"validation: relative entrypoint","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--entrypoint","bin/sh"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox entrypoint must be an absolute path without spaces or quotes\r\n"}]}, -{"name":"validation: invalid hostname","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--hostname","bad host"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox hostname must be a lowercase RFC 1123 label up to 63 characters\r\n"}]}, -{"name":"validation: argument with space","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--arg","a b"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox arguments must be nonempty and contain no spaces or quotes\r\n"}]}, -{"name":"validation: root workload","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--workload-user","0:0"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --workload-user: --workload-user UID must be between 1 and 4294967295\r\n"}]}, -{"name":"validation: invalid workload user","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--workload-user","x"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --workload-user: --workload-user must be UID:GID\r\n"}]}, -{"name":"validation: invalid memory limit","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--memory-max","x"],"status":2,"stdout":"","stderr":"usage: nvx-rs sandbox [-h] [--layer ROLE,PATH,EROFS_UUID] [--scratch SCRATCH]\r\n [--state-dir STATE_DIR] [--entrypoint ENTRYPOINT]\r\n [--arg SANDBOX_ARG] [--hostname HOSTNAME]\r\n [--workload-user UID:GID] [--memory-max MEMORY_MAX]\r\n [--pids-max PIDS_MAX] [--memory-mib MEMORY_MIB]\r\n [--timeout TIMEOUT] [--exec-timeout-ms EXEC_TIMEOUT_MS]\r\n [--cwd CWD] [--environment KEY=VALUE]\r\n [--environment-file PATH]\r\n [--inherit-default-environment]\r\n [--hypervisor {auto,whp,kvm,mshv}]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny HOST_PATH] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--dry-run]\r\n [{run,provision,start,exec,stop,deprovision}]\r\nnvx-rs sandbox: error[argument-invalid]: argument --memory-max: invalid int value: 'x'\r\n"}]}, -{"name":"validation: invalid process limit","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--pids-max","0"],"status":1,"stdout":"","stderr":"error[unsupported]: --pids-max must be positive\r\n"}]}, -{"name":"validation: relative mount target","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","data,{root}\\share"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid sandbox mount target 'data': expected an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\r\n"}]}, -{"name":"validation: missing mount host","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/data,{root}\\missing"],"status":1,"stdout":"","stderr":"error[unsupported]: sandbox mount host path is not a plain directory: {root}\\missing\r\n"}]}, -{"name":"validation: invalid mount mode","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/data,{root}\\share,rx"],"status":1,"stdout":"","stderr":"error[unsupported]: unsupported --mount mode 'rx'; choose ro or rw (if HOST_PATH contains commas, end the value with ,ro or ,rw)\r\n"}]}, -{"name":"validation: deny outside share","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/data,{root}\\share","--mount-deny","{root}\\share2"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-deny {root}\\share2 is not inside the host directory of --mount /data\r\n"}]}, -{"name":"validation: allow outside denied path","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/data,{root}\\share","--mount-allow","{root}\\share\\hidden\\shown"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-allow exposes a path inside a --mount-deny path of the same share, which has none\r\n"}]}, -{"name":"validation: write in read-only share","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/data,{root}\\share,ro","--mount-write","{root}\\share\\writable"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-write narrows the writes of a read-write share; --mount /data is read-only\r\n"}]}, -{"name":"validation: reserved command-line token","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--cmdline","nvx_sandbox=0"],"status":1,"stdout":"","stderr":"error[unsupported]: nvx_sandbox is owned by the sandbox profile\r\n"}]}, -{"name":"validation: systemd distro image","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"write":{"distro.erofs.manifest.json":"{\"format\": 1, \"artifact\": \"distro.erofs\", \"artifact_sha256\": \"8a475efd5fd711d481a9a19de6d12b88dff0cd81cb8135ffcd5b65b062c7bf04\", \"packages\": [{\"name\": \"busybox\", \"version\": \"1\"}, {\"name\": \"systemd\", \"version\": \"1\"}]}"},"status":1,"stdout":"","stderr":"error[unsupported]: systemd images are unsupported by the sandbox security profile\r\n"}]}, -{"name":"validation: mismatched distro manifest","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"write":{"distro.erofs.manifest.json":"{\"format\": 1, \"artifact\": \"distro.erofs\", \"artifact_sha256\": \"0000000000000000000000000000000000000000000000000000000000000000\", \"packages\": []}"},"status":1,"stdout":"","stderr":"error[unsupported]: sandbox distro manifest does not match its artifact\r\n"}]}, -{"name":"validation: invalid distro manifest","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"write":{"distro.erofs.manifest.json":"{"},"status":1,"stdout":"","stderr":"error[unsupported]: invalid sandbox distro manifest: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)\r\n"}]}, -{"name":"validation: distro manifest without packages","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"write":{"distro.erofs.manifest.json":"{\"format\": 1, \"artifact\": \"distro.erofs\", \"artifact_sha256\": \"8a475efd5fd711d481a9a19de6d12b88dff0cd81cb8135ffcd5b65b062c7bf04\"}"},"status":1,"stdout":"","stderr":"error[unsupported]: sandbox distro manifest has invalid package metadata\r\n"}]}, -{"name":"validation: caller-owned share on Windows","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/data,{root}\\share","--mount-owner","caller"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-owner caller requires a Linux host; Windows has no per-request POSIX identity for OpenVMM to switch to\r\n"}]}, -{"name":"dry run: minimal","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --microvm-lifecycle one-shot --single-process --hypervisor whp --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\"\r\n","stderr":""}]}, -{"name":"dry run: every layer and option","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--entrypoint","/bin/server","--arg=--port","--arg","8080","--hostname","worker","--workload-user","1000:1000","--memory-max","268435456","--pids-max","64","--memory-mib","512","--hypervisor","mshv","--cmdline","quiet loglevel=3","--outcome-report","{root}\\reports\\openvmm-run.json","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:{root}\\scratch.ext4 --microvm-workload-identity 1000:1000 --microvm-lifecycle one-shot --single-process --hypervisor mshv --memory 512M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --cmdline \"quiet loglevel=3 nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/server nvx_hostname=worker nvx_arg=--port nvx_arg=8080 nvx_memory_max=268435456 nvx_pids_max=65\" --microvm-report {root}\\reports\\openvmm-run.json\r\n","stderr":""}]}, -{"name":"dry run: explicit hypervisor","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--hypervisor","kvm","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --microvm-lifecycle one-shot --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\"\r\n","stderr":""}]}, -{"name":"dry run: one share","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/data,{root}\\share","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --mount /data,{root}\\share,ro --microvm-lifecycle one-shot --single-process --hypervisor whp --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\"\r\n","stderr":""}]}, -{"name":"dry run: writable share","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/data,{root}\\share,rw","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --mount /data,{root}\\share,rw --microvm-lifecycle one-shot --single-process --hypervisor whp --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\"\r\n","stderr":""}]}, -{"name":"dry run: file share","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--mount","/etc/single.txt,{root}\\single.txt,ro","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --mount-aggregate /run/nvx/shares --mount-child 0-a80a05e9cb129bc27b7ba103bf2f5ac0,{root}\\single.txt,ro,file --microvm-lifecycle one-shot --single-process --hypervisor whp --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\"\r\n","stderr":""}]}, -{"name":"dry run: several shares with policies","steps":[{"argv":["sandbox","run","--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","--mount","/other,{root}\\share2","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --mount-aggregate /run/nvx/shares --mount-child 0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}\\share,rw --mount-child 1-bf2faee2596026620b5cbc997c2d7d45,{root}\\share2,ro --mount-deny {root}\\share\\hidden --mount-allow {root}\\share\\hidden\\shown --mount-write {root}\\share\\writable --microvm-lifecycle one-shot --single-process --hypervisor whp --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,rw nvx_share=1-bf2faee2596026620b5cbc997c2d7d45,/other,ro\"\r\n","stderr":""}]}, -{"name":"dry run: network","steps":[{"argv":["sandbox","run","--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","--network-ingress","allow","--network-egress-allow","10.0.0.0/8:tcp:443","--network-egress-deny","10.1.0.0/16","--host-loopback","allow","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --net 10.0.0.2/24 --network-profile portable --network-egress deny --network-ingress allow --host-loopback allow --network-egress-allow 10.0.0.0/8:tcp:443 --network-egress-deny 10.1.0.0/16 --microvm-lifecycle one-shot --single-process --hypervisor whp --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\"\r\n","stderr":""}]}, -{"name":"dry run: proxy-only network","steps":[{"argv":["sandbox","run","--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","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:{root}\\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 one-shot --single-process --hypervisor whp --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\"\r\n","stderr":""}]}, -{"name":"dry run: egress policy file","steps":[{"argv":["sandbox","run","--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","--network-egress-policy-file","{root}\\policy.json","--dry-run"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"except\": [\"192.0.2.128/25\"]}, {\"cidr\": \"2001:db8::/32\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"198.51.100.0/24\", \"protocol\": \"udp\"}]}"},"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --net 10.0.0.2/24 --network-profile portable --network-egress deny --network-ingress deny --network-egress-allow 192.0.2.0/25 --network-egress-allow 2001:db8::/32:tcp:443 --network-egress-deny 198.51.100.0/24:udp --microvm-lifecycle one-shot --single-process --hypervisor whp --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\"\r\n","stderr":""}]}, -{"name":"dry run: quoted arguments","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--cmdline","a=\"b c\" d","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --microvm-lifecycle one-shot --single-process --hypervisor whp --memory 256M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --cmdline \"a=\\\"b c\\\" d 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\"\r\n","stderr":""}]}, -{"name":"run: echo","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--entrypoint","/bin/echo","--arg","hello","--arg","world"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:\\\\?\\{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:\\\\?\\{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --microvm-lifecycle one-shot --single-process --hypervisor whp --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/echo nvx_hostname=nvx-sandbox nvx_arg=hello nvx_arg=world\"\r\nhello world\n","stderr":""}]}, -{"name":"run: default operation","steps":[{"argv":["sandbox","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--entrypoint","/bin/echo","--arg","hello","--arg","world"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:\\\\?\\{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:\\\\?\\{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --microvm-lifecycle one-shot --single-process --hypervisor whp --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/echo nvx_hostname=nvx-sandbox nvx_arg=hello nvx_arg=world\"\r\nhello world\n","stderr":""}]}, -{"name":"run: failure","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--entrypoint","/bin/false"],"status":1,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:\\\\?\\{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:\\\\?\\{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --microvm-lifecycle one-shot --single-process --hypervisor whp --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/false nvx_hostname=nvx-sandbox\"\r\n","stderr":""}]}, -{"name":"run: missing program","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--entrypoint","/bin/missing"],"status":127,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:\\\\?\\{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:\\\\?\\{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --microvm-lifecycle one-shot --single-process --hypervisor whp --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/missing nvx_hostname=nvx-sandbox\"\r\n","stderr":"openvmm: /bin/missing: not found\n"}]}, -{"name":"run: exit status","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--entrypoint","/bin/true","--cmdline","fake_exit_status=7"],"status":7,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:\\\\?\\{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:\\\\?\\{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --microvm-lifecycle one-shot --single-process --hypervisor whp --memory 256M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --cmdline \"fake_exit_status=7 nvx_sandbox=1 nvx_layer=distro,0xd0003000,erofs:11111111-1111-1111-1111-111111111111 nvx_scratch=0xd0006000,ext4 nvx_entrypoint=/bin/true nvx_hostname=nvx-sandbox\"\r\n","stderr":""}]}, -{"name":"run: outcome report","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--entrypoint","/bin/echo","--arg","hello","--arg","world","--outcome-report","{root}\\reports\\openvmm-run.json"],"check":["reports/openvmm-run.json","build/fake-openvmm-reports.json"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:\\\\?\\{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:\\\\?\\{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --microvm-lifecycle one-shot --single-process --hypervisor whp --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/echo nvx_hostname=nvx-sandbox nvx_arg=hello nvx_arg=world\" --microvm-report {root}\\reports\\openvmm-run.json\r\nhello world\n","stderr":"","files":{"reports/openvmm-run.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\": \"run\",\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"},"build/fake-openvmm-reports.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\",\"one-shot\",\"--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/echo nvx_hostname=nvx-sandbox nvx_arg=hello nvx_arg=world\",\"--microvm-report\",\"{root_json}\\\\reports\\\\openvmm-run.json\"]"}}}]}, -{"name":"run: network outcome report","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--entrypoint","/bin/true","--net","10.0.0.2/24","--network-profile","portable","--network-egress","deny","--network-egress-allow","10.0.0.0/8:tcp:443","--outcome-report","{root}\\reports\\openvmm-run.json"],"check":["reports/openvmm-run.json"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --machine microvm --microvm-sandbox-block distro:file:\\\\?\\{root}\\distro.erofs,ro --microvm-sandbox-block scratch:file:\\\\?\\{root}\\scratch.ext4 --microvm-workload-identity 65534:65534 --net 10.0.0.2/24 --network-profile portable --network-egress deny --network-ingress deny --network-egress-allow 10.0.0.0/8:tcp:443 --microvm-lifecycle one-shot --single-process --hypervisor whp --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/true nvx_hostname=nvx-sandbox\" --microvm-report {root}\\reports\\openvmm-run.json\r\n","stderr":"","files":{"reports/openvmm-run.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 1,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"allow\",\n \"mode\": \"rules\",\n \"status\": \"applied\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"run\",\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"}}}]}, -{"name":"run: network options without --net","steps":[{"argv":["sandbox","run","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--host-loopback-forward","8080"],"status":1,"stdout":"","stderr":"error[unsupported]: network policy options require --net\r\n"}]}, -{"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[artifact-missing]: 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[artifact-missing]: 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[artifact-missing]: 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","build/fake-openvmm-state-maps.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\"]"},"build/fake-openvmm-state-maps.json":null}},{"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[exec-refused]: 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[unsupported]: 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-exists]: 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[unsupported]: 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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": false,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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","build/fake-openvmm-state-maps.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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": false,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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/hostfs/root\",\"--mount-child\",\"0,{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 nvx_maps=1\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"},"build/fake-openvmm-state-maps.json":{"text":"[{\"source\":\"0\",\"target\":\"/data\",\"read_only\":true,\"directory\":true}]"}}},{"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": false,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": false,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": false,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n },\r\n {\r\n \"child\": 1,\r\n \"readOnly\": false,\r\n \"source\": \"\",\r\n \"target\": \"/other\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": false,\r\n \"write\": []\r\n },\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share2\",\r\n \"writable\": true,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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","build/fake-openvmm-state-maps.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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n },\r\n {\r\n \"child\": 1,\r\n \"readOnly\": false,\r\n \"source\": \"\",\r\n \"target\": \"/other\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": false,\r\n \"write\": []\r\n },\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share2\",\r\n \"writable\": true,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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/hostfs/root\",\"--mount-child\",\"0,{root_json}\\\\share,ro\",\"--mount-child\",\"1,{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_maps=2\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"},"build/fake-openvmm-state-maps.json":{"text":"[{\"source\":\"0\",\"target\":\"/data\",\"read_only\":true,\"directory\":true},{\"source\":\"1\",\"target\":\"/other\",\"read_only\":false,\"directory\":true}]"}}},{"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n },\r\n {\r\n \"child\": 1,\r\n \"readOnly\": false,\r\n \"source\": \"\",\r\n \"target\": \"/other\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": false,\r\n \"write\": []\r\n },\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share2\",\r\n \"writable\": true,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n },\r\n {\r\n \"child\": 1,\r\n \"readOnly\": false,\r\n \"source\": \"\",\r\n \"target\": \"/other\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": false,\r\n \"write\": []\r\n },\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share2\",\r\n \"writable\": true,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n },\r\n {\r\n \"child\": 1,\r\n \"readOnly\": false,\r\n \"source\": \"\",\r\n \"target\": \"/other\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": false,\r\n \"write\": []\r\n },\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"root\": \"{root_json}\\\\share2\",\r\n \"writable\": true,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": false,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"deniedIdentities\": [\r\n null\r\n ],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": true,\r\n \"write\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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","build/fake-openvmm-state-maps.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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": false,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"deniedIdentities\": [\r\n null\r\n ],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": true,\r\n \"write\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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/hostfs/root\",\"--mount-child\",\"0,{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 nvx_maps=1\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"},"build/fake-openvmm-state-maps.json":{"text":"[{\"source\":\"0\",\"target\":\"/data\",\"read_only\":false,\"directory\":true}]"}}},{"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": false,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"deniedIdentities\": [\r\n null\r\n ],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": true,\r\n \"write\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": false,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"deniedIdentities\": [\r\n null\r\n ],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": true,\r\n \"write\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": false,\r\n \"source\": \"\",\r\n \"target\": \"/data\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [\r\n \"{root_json}\\\\share\\\\hidden\\\\shown\"\r\n ],\r\n \"denied\": [\r\n \"{root_json}\\\\share\\\\hidden\"\r\n ],\r\n \"deniedIdentities\": [\r\n null\r\n ],\r\n \"root\": \"{root_json}\\\\share\",\r\n \"writable\": true,\r\n \"write\": [\r\n \"{root_json}\\\\share\\\\writable\"\r\n ]\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/etc/single.txt\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"file\": true,\r\n \"root\": \"{root_json}\\\\single.txt\",\r\n \"writable\": false,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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","build/fake-openvmm-state-maps.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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/etc/single.txt\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"file\": true,\r\n \"root\": \"{root_json}\\\\single.txt\",\r\n \"writable\": false,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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/hostfs/root\",\"--mount-child\",\"0,{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_maps=1\",\"--virtio-console\",\"none\",\"--microvm-control-console\",\"listen=//./pipe/openvmm-microvm-{hex32}\",\"--microvm-control-auth-stdin\",\"--microvm-report\",\"{root_json}\\\\state\\\\outcome.json\"]"},"build/fake-openvmm-state-maps.json":{"text":"[{\"source\":\"0\",\"target\":\"/etc/single.txt\",\"read_only\":true,\"directory\":false}]"}}},{"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/etc/single.txt\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"file\": true,\r\n \"root\": \"{root_json}\\\\single.txt\",\r\n \"writable\": false,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/etc/single.txt\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"file\": true,\r\n \"root\": \"{root_json}\\\\single.txt\",\r\n \"writable\": false,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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 \"export\": {\r\n \"binds\": [\r\n {\r\n \"child\": 0,\r\n \"readOnly\": true,\r\n \"source\": \"\",\r\n \"target\": \"/etc/single.txt\"\r\n }\r\n ],\r\n \"children\": [\r\n {\r\n \"allowed\": [],\r\n \"denied\": [],\r\n \"deniedIdentities\": [],\r\n \"file\": true,\r\n \"root\": \"{root_json}\\\\single.txt\",\r\n \"writable\": false,\r\n \"write\": []\r\n }\r\n ]\r\n },\r\n \"format\": 7,\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 \"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-not-provisioned]: 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-not-provisioned]: 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-not-provisioned]: 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-not-provisioned]: 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-provisioned]: 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-running]: sandbox is already running or has stale runtime state\r\n"},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"status":1,"stdout":"","stderr":"error[sandbox-running]: 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-not-running]: sandbox is not running\r\n"},{"argv":["sandbox","exec","--state-dir","{root}\\state"],"status":1,"stdout":"","stderr":"error[sandbox-not-running]: sandbox is not running\r\n"},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"state: relative and nested state directory","steps":[{"argv":["sandbox","provision","--state-dir","nested/state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"check":["nested/state","nested/state/config.json"],"status":0,"stdout":"","stderr":"","files":{"nested/state":{"entries":["config.json","sandbox.lock"]},"nested/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"}}},{"argv":["sandbox","deprovision","--state-dir","nested/state"],"check":["nested/state"],"status":0,"stdout":"","stderr":"","files":{"nested/state":null}}]}, -{"name":"state: failed start","steps":[{"argv":["sandbox","provision","--state-dir","{root}\\state","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4","--cmdline","fake_exit_on_start=5"],"status":0,"stdout":"","stderr":""},{"argv":["sandbox","start","--state-dir","{root}\\state","--timeout","0.5"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":1,"stdout":"","stderr":"error[exited]: OpenVMM exited during startup with status 5\r\n","files":{"state":{"entries":["config.json","openvmm.log","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"fake_exit_on_start=5\",\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":{"text":"openvmm: failing the launch as requested\n"}}},{"argv":["sandbox","start","--state-dir","{root}\\state","--timeout","0.5"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":1,"stdout":"","stderr":"error[exited]: OpenVMM exited during startup with status 5\r\n","files":{"state":{"entries":["config.json","openvmm.log","sandbox.lock"]},"state/config.json":{"text":"{\r\n \"cmdline\": \"fake_exit_on_start=5\",\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":{"text":"openvmm: failing the launch as requested\n"}}},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}],"interop":true}, -{"name":"state: start without OpenVMM","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","start","--state-dir","{root}\\state"],"remove":["openvmm/target/release/openvmm{exe}"],"check":["state","state/config.json","state/runtime.json","state/control.capability","state/outcome.json","state/openvmm.log"],"status":1,"stdout":"","stderr":"error[artifact-missing]: OpenVMM release binary not found: {root}\\openvmm\\target\\release\\openvmm.exe\r\n","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","deprovision","--state-dir","{root}\\state"],"status":0,"stdout":"","stderr":""}]}, -{"name":"state: malformed configuration","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","start","--state-dir","{root}\\state"],"write":{"state/config.json":"{\"format\": 8}"},"status":1,"stdout":"","stderr":"error[format-unsupported]: sandbox configuration has an unsupported format: {root}\\state\\config.json\r\n"},{"argv":["sandbox","start","--state-dir","{root}\\state"],"write":{"state/config.json":"[]"},"status":1,"stdout":"","stderr":"error[format-unsupported]: sandbox configuration has an unsupported format: {root}\\state\\config.json\r\n"},{"argv":["sandbox","start","--state-dir","{root}\\state"],"write":{"state/config.json":"{\"format\": 1}"},"status":1,"stdout":"","stderr":"error[io]: sandbox configuration is malformed\r\n"},{"argv":["sandbox","deprovision","--state-dir","{root}\\state"],"check":["state"],"status":0,"stdout":"","stderr":"","files":{"state":null}}]}, -{"name":"state: not a directory","steps":[{"argv":["sandbox","start","--state-dir","{root}\\single.txt"],"status":1,"stdout":"","stderr":"error[sandbox-not-provisioned]: sandbox state path is not a plain directory: {root}\\single.txt\r\n"},{"argv":["sandbox","provision","--state-dir","{root}\\single.txt","--layer","distro,{root}\\distro.erofs,11111111-1111-1111-1111-111111111111","--scratch","{root}\\scratch.ext4"],"status":1,"stdout":"","stderr":"error[io]: [WinError 183] Cannot create a file when that file already exists: '{root_json}\\\\single.txt'\r\n"},{"argv":["sandbox","deprovision","--state-dir","{root}\\single.txt"],"status":1,"stdout":"","stderr":"error[sandbox-not-provisioned]: sandbox state path is not a plain directory: {root}\\single.txt\r\n"}]}, -{"name":"state: foreign file","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","deprovision","--state-dir","{root}\\state"],"write":{"state/foreign.txt":"x"},"check":["state"],"status":1,"stdout":"","stderr":"error[foreign-files]: sandbox state directory contains files not owned by NVX: foreign.txt\r\n","files":{"state":{"entries":["foreign.txt"]}}}]}, -{"name":"run, usage: help","steps":[{"argv":["run","-h"],"status":0,"stdout":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\n\r\noptions:\r\n -h, --help show this help message and exit\r\n --guest {alpine,ubuntu,azurelinux}\r\n --hypervisor {auto,whp,kvm,mshv}\r\n --machine {microvm}\r\n --memory-mib MEMORY_MIB\r\n guest RAM in MiB (default by --guest: alpine 128,\r\n ubuntu 512, azurelinux 512)\r\n --memory-capacity-mib MEMORY_CAPACITY_MIB\r\n --processors {1,2,4,8}\r\n --cpu-profile ID OpenVMM CPU profile: auto (OpenVMM's default) for the\r\n built-in profile of the host's CPU, a built-in profile\r\n ID, or host to derive a development profile from this\r\n host (doc/usage.md)\r\n --mount GUEST_TARGET,HOST_PATH[,ro|rw]\r\n live-share a host directory, or a single regular host\r\n file without its directory; the mode follows the last\r\n comma, so HOST_PATH may contain commas when the mode\r\n is given; repeat for more shares, each with its own\r\n guest target and mode, as children of one virtio-fs\r\n device\r\n --mount-deny MOUNT_DENY\r\n --mount-allow HOST_PATH\r\n expose one existing path inside a --mount-deny path\r\n again\r\n --mount-write HOST_PATH\r\n make one existing path one of the only writable parts\r\n of a read-write --mount\r\n --mount-owner {vmm,caller}\r\n host identity of the share's file operations: vmm\r\n (default) or caller, with guest root squashed to the\r\n owner of the shared directory or file (Linux only)\r\n --net IPV4/PREFIX\r\n --network-profile {portable}\r\n --network-egress {allow,deny}\r\n --network-ingress {allow,deny}\r\n --network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]\r\n allow guest egress to an IPv4 or IPv6 CIDR, optionally\r\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\r\n udp only on PORT or on the inclusive range PORT-PORT;\r\n repeat to add rules\r\n --network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]\r\n deny guest egress to an IPv4 or IPv6 CIDR, optionally\r\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\r\n udp only on PORT or on the inclusive range PORT-PORT;\r\n repeat to add rules\r\n --network-egress-policy-file PATH\r\n load bounded MXC-shaped IPv4 and IPv6 egress rules\r\n from JSON\r\n --host-loopback {allow,deny}\r\n --network-proxy IPV4:TCP-PORT\r\n --host-loopback-forward HOST_LOOPBACK_FORWARD\r\n --outcome-report OUTCOME_REPORT\r\n write a bounded local JSON outcome report\r\n --cmdline CMDLINE\r\n --restore-snapshot RESTORE_SNAPSHOT\r\n --restore-processors {1,2,4,8}\r\n --restore-memory-mib RESTORE_MEMORY_MIB\r\n --restore-ready-path RESTORE_READY_PATH\r\n --dry-run\r\n","stderr":""}]}, -{"name":"run, usage: help after options","steps":[{"argv":["run","--guest","ubuntu","--help"],"status":0,"stdout":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\n\r\noptions:\r\n -h, --help show this help message and exit\r\n --guest {alpine,ubuntu,azurelinux}\r\n --hypervisor {auto,whp,kvm,mshv}\r\n --machine {microvm}\r\n --memory-mib MEMORY_MIB\r\n guest RAM in MiB (default by --guest: alpine 128,\r\n ubuntu 512, azurelinux 512)\r\n --memory-capacity-mib MEMORY_CAPACITY_MIB\r\n --processors {1,2,4,8}\r\n --cpu-profile ID OpenVMM CPU profile: auto (OpenVMM's default) for the\r\n built-in profile of the host's CPU, a built-in profile\r\n ID, or host to derive a development profile from this\r\n host (doc/usage.md)\r\n --mount GUEST_TARGET,HOST_PATH[,ro|rw]\r\n live-share a host directory, or a single regular host\r\n file without its directory; the mode follows the last\r\n comma, so HOST_PATH may contain commas when the mode\r\n is given; repeat for more shares, each with its own\r\n guest target and mode, as children of one virtio-fs\r\n device\r\n --mount-deny MOUNT_DENY\r\n --mount-allow HOST_PATH\r\n expose one existing path inside a --mount-deny path\r\n again\r\n --mount-write HOST_PATH\r\n make one existing path one of the only writable parts\r\n of a read-write --mount\r\n --mount-owner {vmm,caller}\r\n host identity of the share's file operations: vmm\r\n (default) or caller, with guest root squashed to the\r\n owner of the shared directory or file (Linux only)\r\n --net IPV4/PREFIX\r\n --network-profile {portable}\r\n --network-egress {allow,deny}\r\n --network-ingress {allow,deny}\r\n --network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]\r\n allow guest egress to an IPv4 or IPv6 CIDR, optionally\r\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\r\n udp only on PORT or on the inclusive range PORT-PORT;\r\n repeat to add rules\r\n --network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]\r\n deny guest egress to an IPv4 or IPv6 CIDR, optionally\r\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\r\n udp only on PORT or on the inclusive range PORT-PORT;\r\n repeat to add rules\r\n --network-egress-policy-file PATH\r\n load bounded MXC-shaped IPv4 and IPv6 egress rules\r\n from JSON\r\n --host-loopback {allow,deny}\r\n --network-proxy IPV4:TCP-PORT\r\n --host-loopback-forward HOST_LOOPBACK_FORWARD\r\n --outcome-report OUTCOME_REPORT\r\n write a bounded local JSON outcome report\r\n --cmdline CMDLINE\r\n --restore-snapshot RESTORE_SNAPSHOT\r\n --restore-processors {1,2,4,8}\r\n --restore-memory-mib RESTORE_MEMORY_MIB\r\n --restore-ready-path RESTORE_READY_PATH\r\n --dry-run\r\n","stderr":""}]}, -{"name":"run, usage: help before an invalid value","steps":[{"argv":["run","--help","--memory-mib","x"],"status":0,"stdout":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\n\r\noptions:\r\n -h, --help show this help message and exit\r\n --guest {alpine,ubuntu,azurelinux}\r\n --hypervisor {auto,whp,kvm,mshv}\r\n --machine {microvm}\r\n --memory-mib MEMORY_MIB\r\n guest RAM in MiB (default by --guest: alpine 128,\r\n ubuntu 512, azurelinux 512)\r\n --memory-capacity-mib MEMORY_CAPACITY_MIB\r\n --processors {1,2,4,8}\r\n --cpu-profile ID OpenVMM CPU profile: auto (OpenVMM's default) for the\r\n built-in profile of the host's CPU, a built-in profile\r\n ID, or host to derive a development profile from this\r\n host (doc/usage.md)\r\n --mount GUEST_TARGET,HOST_PATH[,ro|rw]\r\n live-share a host directory, or a single regular host\r\n file without its directory; the mode follows the last\r\n comma, so HOST_PATH may contain commas when the mode\r\n is given; repeat for more shares, each with its own\r\n guest target and mode, as children of one virtio-fs\r\n device\r\n --mount-deny MOUNT_DENY\r\n --mount-allow HOST_PATH\r\n expose one existing path inside a --mount-deny path\r\n again\r\n --mount-write HOST_PATH\r\n make one existing path one of the only writable parts\r\n of a read-write --mount\r\n --mount-owner {vmm,caller}\r\n host identity of the share's file operations: vmm\r\n (default) or caller, with guest root squashed to the\r\n owner of the shared directory or file (Linux only)\r\n --net IPV4/PREFIX\r\n --network-profile {portable}\r\n --network-egress {allow,deny}\r\n --network-ingress {allow,deny}\r\n --network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]\r\n allow guest egress to an IPv4 or IPv6 CIDR, optionally\r\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\r\n udp only on PORT or on the inclusive range PORT-PORT;\r\n repeat to add rules\r\n --network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]\r\n deny guest egress to an IPv4 or IPv6 CIDR, optionally\r\n only for PROTOCOL tcp, udp, or icmp, and for tcp or\r\n udp only on PORT or on the inclusive range PORT-PORT;\r\n repeat to add rules\r\n --network-egress-policy-file PATH\r\n load bounded MXC-shaped IPv4 and IPv6 egress rules\r\n from JSON\r\n --host-loopback {allow,deny}\r\n --network-proxy IPV4:TCP-PORT\r\n --host-loopback-forward HOST_LOOPBACK_FORWARD\r\n --outcome-report OUTCOME_REPORT\r\n write a bounded local JSON outcome report\r\n --cmdline CMDLINE\r\n --restore-snapshot RESTORE_SNAPSHOT\r\n --restore-processors {1,2,4,8}\r\n --restore-memory-mib RESTORE_MEMORY_MIB\r\n --restore-ready-path RESTORE_READY_PATH\r\n --dry-run\r\n","stderr":""}]}, -{"name":"run, usage: invalid value before help","steps":[{"argv":["run","--memory-mib","x","--help"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --memory-mib: invalid int value: 'x'\r\n"}]}, -{"name":"run, usage: invalid guest","steps":[{"argv":["run","--guest","debian"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --guest: invalid choice: 'debian' (choose from 'alpine', 'ubuntu', 'azurelinux')\r\n"}]}, -{"name":"run, usage: invalid second guest","steps":[{"argv":["run","--guest","alpine","--guest","debian"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --guest: invalid choice: 'debian' (choose from 'alpine', 'ubuntu', 'azurelinux')\r\n"}]}, -{"name":"run, usage: invalid hypervisor","steps":[{"argv":["run","--hypervisor","hyperv"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --hypervisor: invalid choice: 'hyperv' (choose from 'auto', 'whp', 'kvm', 'mshv')\r\n"}]}, -{"name":"run, usage: invalid machine","steps":[{"argv":["run","--machine","microvm-v2"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --machine: invalid choice: 'microvm-v2' (choose from 'microvm')\r\n"}]}, -{"name":"run, usage: memory not an integer","steps":[{"argv":["run","--memory-mib","x"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --memory-mib: invalid int value: 'x'\r\n"}]}, -{"name":"run, usage: memory not a whole number","steps":[{"argv":["run","--memory-mib","1.5"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --memory-mib: invalid int value: '1.5'\r\n"}]}, -{"name":"run, usage: memory with a space","steps":[{"argv":["run","--memory-mib","1 2"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --memory-mib: invalid int value: '1 2'\r\n"}]}, -{"name":"run, usage: memory with other digits","steps":[{"argv":["run","--memory-mib","\u0661\u0662\u0668x"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --memory-mib: invalid int value: '\u0661\u0662\u0668x'\r\n"}]}, -{"name":"run, usage: memory capacity not an integer","steps":[{"argv":["run","--memory-capacity-mib","1e3"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --memory-capacity-mib: invalid int value: '1e3'\r\n"}]}, -{"name":"run, usage: restore memory not an integer","steps":[{"argv":["run","--restore-memory-mib",""],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --restore-memory-mib: invalid int value: ''\r\n"}]}, -{"name":"run, usage: processors not an integer","steps":[{"argv":["run","--processors","two"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --processors: invalid int value: 'two'\r\n"}]}, -{"name":"run, usage: processors not a choice","steps":[{"argv":["run","--processors","3"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --processors: invalid choice: '3' (choose from '1', '2', '4', '8')\r\n"}]}, -{"name":"run, usage: processors converted before the choice","steps":[{"argv":["run","--processors","1_6"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --processors: invalid choice: '16' (choose from '1', '2', '4', '8')\r\n"}]}, -{"name":"run, usage: processors with a leading zero","steps":[{"argv":["run","--processors","03"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --processors: invalid choice: '3' (choose from '1', '2', '4', '8')\r\n"}]}, -{"name":"run, usage: negative processors","steps":[{"argv":["run","--processors","-5"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --processors: invalid choice: '-5' (choose from '1', '2', '4', '8')\r\n"}]}, -{"name":"run, usage: restore processors not an integer","steps":[{"argv":["run","--restore-processors","x"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --restore-processors: invalid int value: 'x'\r\n"}]}, -{"name":"run, usage: restore processors not a choice","steps":[{"argv":["run","--restore-processors","16"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --restore-processors: invalid choice: '16' (choose from '1', '2', '4', '8')\r\n"}]}, -{"name":"run, usage: invalid mount owner","steps":[{"argv":["run","--mount-owner","root"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --mount-owner: invalid choice: 'root' (choose from 'vmm', 'caller')\r\n"}]}, -{"name":"run, usage: invalid network profile","steps":[{"argv":["run","--network-profile","open"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --network-profile: invalid choice: 'open' (choose from 'portable')\r\n"}]}, -{"name":"run, usage: invalid network egress","steps":[{"argv":["run","--network-egress","block"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --network-egress: invalid choice: 'block' (choose from 'allow', 'deny')\r\n"}]}, -{"name":"run, usage: invalid network ingress","steps":[{"argv":["run","--network-ingress","open"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --network-ingress: invalid choice: 'open' (choose from 'allow', 'deny')\r\n"}]}, -{"name":"run, usage: invalid host loopback","steps":[{"argv":["run","--host-loopback","yes"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --host-loopback: invalid choice: 'yes' (choose from 'allow', 'deny')\r\n"}]}, -{"name":"run, usage: missing value","steps":[{"argv":["run","--memory-mib"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-missing]: argument --memory-mib: expected one argument\r\n"}]}, -{"name":"run, usage: missing path","steps":[{"argv":["run","--restore-snapshot"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-missing]: argument --restore-snapshot: expected one argument\r\n"}]}, -{"name":"run, usage: option as value","steps":[{"argv":["run","--cpu-profile","--dry-run"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-missing]: argument --cpu-profile: expected one argument\r\n"}]}, -{"name":"run, usage: dash value","steps":[{"argv":["run","--cmdline","-x"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-missing]: argument --cmdline: expected one argument\r\n"}]}, -{"name":"run, usage: flag with value","steps":[{"argv":["run","--dry-run=1"],"status":2,"stdout":"","stderr":"usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}]\r\n [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}]\r\n [--memory-mib MEMORY_MIB]\r\n [--memory-capacity-mib MEMORY_CAPACITY_MIB]\r\n [--processors {1,2,4,8}] [--cpu-profile ID]\r\n [--mount GUEST_TARGET,HOST_PATH[,ro|rw]]\r\n [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH]\r\n [--mount-write HOST_PATH] [--mount-owner {vmm,caller}]\r\n [--net IPV4/PREFIX] [--network-profile {portable}]\r\n [--network-egress {allow,deny}]\r\n [--network-ingress {allow,deny}]\r\n [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]]\r\n [--network-egress-policy-file PATH]\r\n [--host-loopback {allow,deny}]\r\n [--network-proxy IPV4:TCP-PORT]\r\n [--host-loopback-forward HOST_LOOPBACK_FORWARD]\r\n [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE]\r\n [--restore-snapshot RESTORE_SNAPSHOT]\r\n [--restore-processors {1,2,4,8}]\r\n [--restore-memory-mib RESTORE_MEMORY_MIB]\r\n [--restore-ready-path RESTORE_READY_PATH] [--dry-run]\r\nnvx-rs run: error[argument-invalid]: argument --dry-run: ignored explicit argument '1'\r\n"}]}, -{"name":"run, usage: unrecognized option","steps":[{"argv":["run","--bogus"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\r\n {artifacts,egress,run,sandbox} ...\r\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: --bogus\r\n"}]}, -{"name":"run, usage: unrecognized short option","steps":[{"argv":["run","-x"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\r\n {artifacts,egress,run,sandbox} ...\r\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: -x\r\n"}]}, -{"name":"run, usage: unrecognized positional","steps":[{"argv":["run","extra"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\r\n {artifacts,egress,run,sandbox} ...\r\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: extra\r\n"}]}, -{"name":"run, usage: unrecognized after separator","steps":[{"argv":["run","--","extra"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\r\n {artifacts,egress,run,sandbox} ...\r\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: -- extra\r\n"}]}, -{"name":"run, usage: unrecognized after options","steps":[{"argv":["run","--dry-run","--guest","alpine","extra"],"status":2,"stdout":"","stderr":"usage: nvx-rs [-h] [--root PATH] [--prog PROG]\r\n {artifacts,egress,run,sandbox} ...\r\nnvx-rs: error[argument-unrecognized]: unrecognized arguments: extra\r\n"}]}, -{"name":"run, validation: net without profile","steps":[{"argv":["run","--net","10.0.0.2/24","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --net and --network-profile must be specified together\r\n"}]}, -{"name":"run, validation: profile without net","steps":[{"argv":["run","--network-profile","portable","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --net and --network-profile must be specified together\r\n"}]}, -{"name":"run, validation: ready path without snapshot","steps":[{"argv":["run","--restore-ready-path","{root}\\ready.sock","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --restore-ready-path requires --restore-snapshot\r\n"}]}, -{"name":"run, validation: restore processors without snapshot","steps":[{"argv":["run","--restore-processors","1","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --restore-processors requires --restore-snapshot\r\n"}]}, -{"name":"run, validation: restore memory without snapshot","steps":[{"argv":["run","--restore-memory-mib","1024","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --restore-memory-mib requires --restore-snapshot\r\n"}]}, -{"name":"run, validation: memory capacity of a restore","steps":[{"argv":["run","--restore-snapshot","{root}\\snapshot","--memory-capacity-mib","1024","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --memory-capacity-mib is only valid for a fresh boot\r\n"}]}, -{"name":"run, validation: Ubuntu guest of a restore","steps":[{"argv":["run","--guest","ubuntu","--restore-snapshot","{root}\\snapshot","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --guest is not accepted for restore; the snapshot already fixes the guest\r\n"}]}, -{"name":"run, validation: Azure Linux guest of a restore","steps":[{"argv":["run","--restore-snapshot","{root}\\snapshot","--guest","azurelinux","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --guest is not accepted for restore; the snapshot already fixes the guest\r\n"}]}, -{"name":"run, validation: memory capacity below memory","steps":[{"argv":["run","--memory-mib","512","--memory-capacity-mib","256","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --memory-capacity-mib cannot be below --memory-mib\r\n"}]}, -{"name":"run, validation: memory capacity below the guest default","steps":[{"argv":["run","--guest","ubuntu","--memory-capacity-mib","256","--dry-run"],"write":{"build/initramfs-ubuntu.cpio.gz":"ubuntu\n"},"status":1,"stdout":"","stderr":"error[unsupported]: --memory-capacity-mib cannot be below --memory-mib\r\n"}]}, -{"name":"run, validation: restore processors above processors","steps":[{"argv":["run","--processors","2","--restore-snapshot","{root}\\snapshot","--restore-processors","4","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --restore-processors cannot exceed --processors capacity\r\n"}]}, -{"name":"run, validation: policy file with allow rules","steps":[{"argv":["run","--network-egress","deny","--network-egress-policy-file","{root}\\policy.json","--network-egress-allow","10.0.0.0/8","--dry-run"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"except\": [\"192.0.2.128/25\"]}, {\"cidr\": \"2001:db8::/32\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"198.51.100.0/24\", \"protocol\": \"udp\"}]}"},"status":1,"stdout":"","stderr":"error[unsupported]: --network-egress-policy-file cannot be combined with --network-egress-allow or --network-egress-deny\r\n"}]}, -{"name":"run, validation: policy file with deny rules","steps":[{"argv":["run","--network-egress-deny","10.0.0.0/8","--network-egress-policy-file","{root}\\policy.json","--dry-run"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"except\": [\"192.0.2.128/25\"]}, {\"cidr\": \"2001:db8::/32\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"198.51.100.0/24\", \"protocol\": \"udp\"}]}"},"status":1,"stdout":"","stderr":"error[unsupported]: --network-egress-policy-file cannot be combined with --network-egress-allow or --network-egress-deny\r\n"}]}, -{"name":"run, validation: policy file without egress","steps":[{"argv":["run","--network-egress-policy-file","{root}\\policy.json","--dry-run"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"except\": [\"192.0.2.128/25\"]}, {\"cidr\": \"2001:db8::/32\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"198.51.100.0/24\", \"protocol\": \"udp\"}]}"},"status":1,"stdout":"","stderr":"error[unsupported]: --network-egress is required with --network-egress-policy-file\r\n"}]}, -{"name":"run, validation: policy file missing","steps":[{"argv":["run","--network-egress","deny","--network-egress-policy-file","{root}\\.\\missing.json","--dry-run"],"status":1,"stdout":"","stderr":"error[io]: failed to read egress policy file: {root}\\.\\missing.json\r\n"}]}, -{"name":"run, validation: policy file directory","steps":[{"argv":["run","--network-egress","deny","--network-egress-policy-file","{root}\\share","--dry-run"],"status":1,"stdout":"","stderr":"error[io]: failed to read egress policy file: {root}\\share\r\n"}]}, -{"name":"run, validation: policy file invalid","steps":[{"argv":["run","--network-egress","allow","--network-egress-policy-file","policy.json","--dry-run"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"10.0.0.0/8\", \"port\": 0}]}"},"status":1,"stdout":"","stderr":"error[unsupported]: allow[0].port requires protocol\r\n"}]}, -{"name":"run, validation: policy file not JSON","steps":[{"argv":["run","--network-egress","allow","--network-egress-policy-file","policy.json","--dry-run"],"write":{"policy.json":"{"},"status":1,"stdout":"","stderr":"error[unsupported]: egress policy file policy.json is not valid JSON: EOF while parsing an object at line 1 column 1\r\n"}]}, -{"name":"run, validation: policy errors before missing artifacts","steps":[{"argv":["run","--network-egress-policy-file","{root}\\policy.json","--dry-run"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"except\": [\"192.0.2.128/25\"]}, {\"cidr\": \"2001:db8::/32\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"198.51.100.0/24\", \"protocol\": \"udp\"}]}"},"remove":["openvmm/target/release/openvmm{exe}","build/vmlinux"],"status":1,"stdout":"","stderr":"error[unsupported]: --network-egress is required with --network-egress-policy-file\r\n"}]}, -{"name":"run, validation: missing OpenVMM","steps":[{"argv":["run","--dry-run"],"remove":["openvmm/target/release/openvmm{exe}"],"status":1,"stdout":"","stderr":"error[artifact-missing]: OpenVMM release binary not found: {root}\\openvmm\\target\\release\\openvmm.exe\r\n"}]}, -{"name":"run, validation: missing kernel","steps":[{"argv":["run","--dry-run"],"remove":["build/vmlinux"],"status":1,"stdout":"","stderr":"error[artifact-missing]: Linux direct kernel not found: {root}\\build\\vmlinux\r\n"}]}, -{"name":"run, validation: missing Alpine initramfs","steps":[{"argv":["run","--dry-run"],"remove":["build/initramfs.cpio.gz"],"status":1,"stdout":"","stderr":"error[artifact-missing]: Alpine Linux initramfs not found: {root}\\build\\initramfs.cpio.gz\r\n"}]}, -{"name":"run, validation: missing Ubuntu initramfs","steps":[{"argv":["run","--guest","ubuntu","--dry-run"],"status":1,"stdout":"","stderr":"error[artifact-missing]: Ubuntu Base initramfs not found: {root}\\build\\initramfs-ubuntu.cpio.gz\r\n"}]}, -{"name":"run, validation: missing Azure Linux initramfs","steps":[{"argv":["run","--guest","azurelinux","--dry-run"],"status":1,"stdout":"","stderr":"error[artifact-missing]: Azure Linux initramfs not found: {root}\\build\\initramfs-azurelinux.cpio.gz\r\n"}]}, -{"name":"run, validation: missing artifacts before invalid shares","steps":[{"argv":["run","--mount","/data","--dry-run"],"remove":["openvmm/target/release/openvmm{exe}"],"status":1,"stdout":"","stderr":"error[artifact-missing]: OpenVMM release binary not found: {root}\\openvmm\\target\\release\\openvmm.exe\r\n"}]}, -{"name":"run, validation: mount without host path","steps":[{"argv":["run","--mount","/data","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount must be GUEST_TARGET,HOST_PATH[,ro|rw]\r\n"}]}, -{"name":"run, validation: mount with empty host path","steps":[{"argv":["run","--mount","/data,","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount host path is empty\r\n"}]}, -{"name":"run, validation: mount with empty host path and mode","steps":[{"argv":["run","--mount","/data,,rw","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount host path is empty\r\n"}]}, -{"name":"run, validation: mount with invalid mode","steps":[{"argv":["run","--mount","/data,{root}\\share,rx","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: unsupported --mount mode 'rx'; choose ro or rw (if HOST_PATH contains commas, end the value with ,ro or ,rw)\r\n"}]}, -{"name":"run, validation: mount with commas but no mode","steps":[{"argv":["run","--mount","/data,{root}\\alpha,beta","--dry-run"],"write":{"alpha,beta/data.txt":"data\n","2026, final/data.txt":"data\n","settings,v2.json":"{}\n"},"status":1,"stdout":"","stderr":"error[unsupported]: unsupported --mount mode 'beta'; choose ro or rw (if HOST_PATH contains commas, end the value with ,ro or ,rw)\r\n"}]}, -{"name":"run, validation: invalid second mount","steps":[{"argv":["run","--mount","/a,{root}\\share","--mount","relative","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount must be GUEST_TARGET,HOST_PATH[,ro|rw]\r\n"}]}, -{"name":"run, validation: invalid mount before invalid targets","steps":[{"argv":["run","--mount","a,{root}\\share","--mount","/b","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount must be GUEST_TARGET,HOST_PATH[,ro|rw]\r\n"}]}, -{"name":"run, validation: owner without mount","steps":[{"argv":["run","--mount-owner","vmm","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-owner requires --mount\r\n"}]}, -{"name":"run, validation: relative deny path with several shares","steps":[{"argv":["run","--mount","/a,{root}\\share","--mount","/b,{root}\\share2","--mount-deny","secrets","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: with several --mount shares, or a shared file, --mount-deny secrets must be an absolute host path\r\n"}]}, -{"name":"run, validation: relative allow path with a shared file","steps":[{"argv":["run","--mount","/etc/single.txt,{root}\\single.txt","--mount-allow","secrets","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: with several --mount shares, or a shared file, --mount-allow secrets must be an absolute host path\r\n"}]}, -{"name":"run, validation: relative write path with several shares","steps":[{"argv":["run","--mount","/a,{root}\\share","--mount","/b,{root}\\share2","--mount-write","./out/","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: with several --mount shares, or a shared file, --mount-write out must be an absolute host path\r\n"}]}, -{"name":"run, validation: relative paths in kind order","steps":[{"argv":["run","--mount","/a,{root}\\share","--mount","/b,{root}\\share2","--mount-write","out","--mount-deny","secrets","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: with several --mount shares, or a shared file, --mount-deny secrets must be an absolute host path\r\n"}]}, -{"name":"run, validation: relative target with several shares","steps":[{"argv":["run","--mount","a,{root}\\share","--mount","/b,{root}\\share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target 'a': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\r\n"}]}, -{"name":"run, validation: relative target of a shared file","steps":[{"argv":["run","--mount","single.txt,{root}\\single.txt","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target 'single.txt': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\r\n"}]}, -{"name":"run, validation: root target with several shares","steps":[{"argv":["run","--mount","/,{root}\\share","--mount","/b,{root}\\share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target '/': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\r\n"}]}, -{"name":"run, validation: target with a space","steps":[{"argv":["run","--mount","/a b,{root}\\share","--mount","/b,{root}\\share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target '/a b': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\r\n"}]}, -{"name":"run, validation: target with an equals sign","steps":[{"argv":["run","--mount","/a=b,{root}\\share","--mount","/b,{root}\\share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target '/a=b': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\r\n"}]}, -{"name":"run, validation: target with a backslash","steps":[{"argv":["run","--mount","/a\\b,{root}\\share","--mount","/b,{root}\\share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target '/a\\\\b': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\r\n"}]}, -{"name":"run, validation: target with a dot component","steps":[{"argv":["run","--mount","/a/./b,{root}\\share","--mount","/b,{root}\\share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target '/a/./b': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\r\n"}]}, -{"name":"run, validation: target with a parent component","steps":[{"argv":["run","--mount","/a/../b,{root}\\share","--mount","/c,{root}\\share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target '/a/../b': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\r\n"}]}, -{"name":"run, validation: target with an empty component","steps":[{"argv":["run","--mount","/a//b,{root}\\share","--mount","/c,{root}\\share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: invalid --mount target '/a//b': with several shares, or a shared file, each target must be an absolute non-root path without empty, dot, or parent components, whitespace, '\\', '=', or ','\r\n"}]}, -{"name":"run, validation: equal targets","steps":[{"argv":["run","--mount","/a,{root}\\share","--mount","/a,{root}\\share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount targets /a and /a overlap; a share cannot hide another\r\n"}]}, -{"name":"run, validation: nested targets","steps":[{"argv":["run","--mount","/workspace,{root}\\share","--mount","/workspace/cache,{root}\\share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount targets /workspace and /workspace/cache overlap; a share cannot hide another\r\n"}]}, -{"name":"run, validation: target containing another","steps":[{"argv":["run","--mount","/workspace/cache,{root}\\share","--mount","/workspace,{root}\\share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount targets /workspace/cache and /workspace overlap; a share cannot hide another\r\n"}]}, -{"name":"run, validation: target containing the aggregate","steps":[{"argv":["run","--mount","/run/nvx,{root}\\share","--mount","/b,{root}\\share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount targets /run/nvx/shares and /run/nvx overlap; a share cannot hide another\r\n"}]}, -{"name":"run, validation: target in the aggregate","steps":[{"argv":["run","--mount","/run/nvx/shares/x,{root}\\share","--mount","/b,{root}\\share2","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount targets /run/nvx/shares and /run/nvx/shares/x overlap; a share cannot hide another\r\n"}]}, -{"name":"run, validation: too many shares for the budget","steps":[{"argv":["run","--mount","/share/00,{root}\\share","--mount","/share/01,{root}\\share","--mount","/share/02,{root}\\share","--mount","/share/03,{root}\\share","--mount","/share/04,{root}\\share","--mount","/share/05,{root}\\share","--mount","/share/06,{root}\\share","--mount","/share/07,{root}\\share","--mount","/share/08,{root}\\share","--mount","/share/09,{root}\\share","--mount","/share/10,{root}\\share","--mount","/share/11,{root}\\share","--mount","/share/12,{root}\\share","--mount","/share/13,{root}\\share","--mount","/share/14,{root}\\share","--mount","/share/15,{root}\\share","--mount","/share/16,{root}\\share","--mount","/share/17,{root}\\share","--mount","/share/18,{root}\\share","--mount","/share/19,{root}\\share","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: the --mount shares and --cmdline exceed the 1024-byte budget of the kernel command line; attach fewer shares or use shorter targets\r\n"}]}, -{"name":"run, validation: budget exceeded by a byte","steps":[{"argv":["run","--mount","/a,{root}\\share","--mount","/b,{root}\\share2,rw","--cmdline","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: the --mount shares and --cmdline exceed the 1024-byte budget of the kernel command line; attach fewer shares or use shorter targets\r\n"}]}, -{"name":"run, validation: budget in UTF-8 bytes","steps":[{"argv":["run","--mount","/a,{root}\\share","--mount","/b,{root}\\share2,rw","--cmdline","\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: the --mount shares and --cmdline exceed the 1024-byte budget of the kernel command line; attach fewer shares or use shorter targets\r\n"}]}, -{"name":"run, validation: missing OpenVMM override","steps":[{"argv":["run","--dry-run"],"env":{"NVX_OPENVMM":"{root}\\alt\\openvmm{exe}"},"status":1,"stdout":"","stderr":"error[artifact-missing]: OpenVMM release binary not found: {root}\\alt\\openvmm.exe\r\n"}]}, -{"name":"run, validation: caller owner on Windows","steps":[{"argv":["run","--mount","/data,{root}\\share","--mount-owner","caller","--dry-run"],"status":1,"stdout":"","stderr":"error[unsupported]: --mount-owner caller requires a Linux host; Windows has no per-request POSIX identity for OpenVMM to switch to\r\n"}]}, -{"name":"run, dry run: Alpine default","steps":[{"argv":["run","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz\r\n","stderr":""}]}, -{"name":"run, dry run: Ubuntu default","steps":[{"argv":["run","--guest","ubuntu","--dry-run"],"write":{"build/initramfs-ubuntu.cpio.gz":"ubuntu\n"},"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 512M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs-ubuntu.cpio.gz\r\n","stderr":""}]}, -{"name":"run, dry run: Azure Linux default","steps":[{"argv":["run","--guest","azurelinux","--dry-run"],"write":{"build/initramfs-azurelinux.cpio.gz":"azurelinux\n"},"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 512M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs-azurelinux.cpio.gz\r\n","stderr":""}]}, -{"name":"run, dry run: Alpine with memory","steps":[{"argv":["run","--guest","alpine","--memory-mib","256","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 256M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz\r\n","stderr":""}]}, -{"name":"run, dry run: Ubuntu with memory and capacity","steps":[{"argv":["run","--guest","ubuntu","--memory-mib","1024","--memory-capacity-mib","2048","--dry-run"],"write":{"build/initramfs-ubuntu.cpio.gz":"ubuntu\n"},"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 1024M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs-ubuntu.cpio.gz --memory-capacity 2048M\r\n","stderr":""}]}, -{"name":"run, dry run: Azure Linux with the default capacity","steps":[{"argv":["run","--guest","azurelinux","--memory-capacity-mib","512","--dry-run"],"write":{"build/initramfs-azurelinux.cpio.gz":"azurelinux\n"},"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 512M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs-azurelinux.cpio.gz --memory-capacity 512M\r\n","stderr":""}]}, -{"name":"run, dry run: last guest","steps":[{"argv":["run","--guest","ubuntu","--guest","azurelinux","--dry-run"],"write":{"build/initramfs-azurelinux.cpio.gz":"azurelinux\n"},"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 512M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs-azurelinux.cpio.gz\r\n","stderr":""}]}, -{"name":"run, dry run: every boot option","steps":[{"argv":["run","--hypervisor","mshv","--machine","microvm","--memory-mib","1024","--memory-capacity-mib","2048","--processors","8","--cpu-profile","intel.alderlake.v1","--cmdline","quiet loglevel=3","--outcome-report","{root}\\reports\\openvmm-run.json","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 8 --hypervisor mshv --memory 1024M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --memory-capacity 2048M --cpu-profile intel.alderlake.v1 --microvm-report {root}\\reports\\openvmm-run.json --cmdline \"quiet loglevel=3\"\r\n","stderr":""}]}, -{"name":"run, dry run: auto hypervisor","steps":[{"argv":["run","--hypervisor","auto","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz\r\n","stderr":""}]}, -{"name":"run, dry run: KVM","steps":[{"argv":["run","--hypervisor","kvm","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor kvm --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz\r\n","stderr":""}]}, -{"name":"run, dry run: WHP","steps":[{"argv":["run","--hypervisor","whp","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz\r\n","stderr":""}]}, -{"name":"run, dry run: canonical integers","steps":[{"argv":["run","--memory-mib"," +12_8 ","--memory-capacity-mib","0256","--processors"," 2 ","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 2 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --memory-capacity 256M\r\n","stderr":""}]}, -{"name":"run, dry run: other digits","steps":[{"argv":["run","--processors","\u0664","--memory-mib","\u0665\u0661\u0662","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 4 --hypervisor whp --memory 512M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz\r\n","stderr":""}]}, -{"name":"run, dry run: negative memory","steps":[{"argv":["run","--memory-mib","-5","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory -5M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz\r\n","stderr":""}]}, -{"name":"run, dry run: attached negative memory","steps":[{"argv":["run","--memory-mib=-128","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory -128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz\r\n","stderr":""}]}, -{"name":"run, dry run: equal memory and capacity","steps":[{"argv":["run","--memory-mib","512","--memory-capacity-mib","512","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 512M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --memory-capacity 512M\r\n","stderr":""}]}, -{"name":"run, dry run: last processors","steps":[{"argv":["run","--processors","2","--processors","4","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 4 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz\r\n","stderr":""}]}, -{"name":"run, dry run: cpu profile auto","steps":[{"argv":["run","--cpu-profile","auto","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --cpu-profile auto\r\n","stderr":""}]}, -{"name":"run, dry run: cpu profile host","steps":[{"argv":["run","--cpu-profile","host","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --cpu-profile host\r\n","stderr":""}]}, -{"name":"run, dry run: restore","steps":[{"argv":["run","--restore-snapshot","{root}\\snapshot","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --restore-snapshot {root}\\snapshot\r\n","stderr":""}]}, -{"name":"run, dry run: restore without guest artifacts","steps":[{"argv":["run","--restore-snapshot","{root}\\snapshot","--dry-run"],"remove":["build/vmlinux","build/initramfs.cpio.gz"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --restore-snapshot {root}\\snapshot\r\n","stderr":""}]}, -{"name":"run, dry run: restore with every option","steps":[{"argv":["run","--hypervisor","mshv","--processors","4","--restore-snapshot","{root}\\snapshot","--restore-processors","2","--restore-memory-mib","1024","--restore-ready-path","{root}\\ready.sock","--cpu-profile","host","--outcome-report","{root}\\reports\\restore.json","--cmdline","quiet","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 4 --hypervisor mshv --restore-snapshot {root}\\snapshot --restore-processors 2 --restore-memory 1024M --restore-ready-path {root}\\ready.sock --cpu-profile host --microvm-report {root}\\reports\\restore.json --cmdline quiet\r\n","stderr":""}]}, -{"name":"run, dry run: restore of the Alpine guest","steps":[{"argv":["run","--guest","alpine","--restore-snapshot","{root}\\snapshot","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --restore-snapshot {root}\\snapshot\r\n","stderr":""}]}, -{"name":"run, dry run: restore with equal processors","steps":[{"argv":["run","--processors","2","--restore-processors","2","--restore-snapshot","{root}\\snapshot","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 2 --hypervisor whp --restore-snapshot {root}\\snapshot --restore-processors 2\r\n","stderr":""}]}, -{"name":"run, dry run: restore ignores the memory","steps":[{"argv":["run","--memory-mib","512","--restore-snapshot","{root}\\snapshot","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --restore-snapshot {root}\\snapshot\r\n","stderr":""}]}, -{"name":"run, dry run: restore paths","steps":[{"argv":["run","--restore-snapshot","./snapshot/","--restore-ready-path","run//ready.sock","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --restore-snapshot snapshot --restore-ready-path run\\ready.sock\r\n","stderr":""}]}, -{"name":"run, dry run: one share","steps":[{"argv":["run","--mount","/data,{root}\\share","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount /data,{root}\\share,ro\r\n","stderr":""}]}, -{"name":"run, dry run: one writable share","steps":[{"argv":["run","--mount","/data,{root}\\share,rw","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount /data,{root}\\share,rw\r\n","stderr":""}]}, -{"name":"run, dry run: one relative share","steps":[{"argv":["run","--mount","/data,share","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount /data,share,ro\r\n","stderr":""}]}, -{"name":"run, dry run: one share with relative policy paths","steps":[{"argv":["run","--mount","/data,{root}\\share,rw","--mount-write","writable","--mount-allow","hidden/shown","--mount-deny","./hidden/","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount /data,{root}\\share,rw --mount-deny hidden --mount-allow hidden\\shown --mount-write writable\r\n","stderr":""}]}, -{"name":"run, dry run: policy paths without a share","steps":[{"argv":["run","--mount-deny","{root}\\share\\hidden","--mount-allow","x","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount-deny {root}\\share\\hidden --mount-allow x\r\n","stderr":""}]}, -{"name":"run, dry run: several shares with policy paths","steps":[{"argv":["run","--mount","/data,{root}\\share,rw","--mount","/other,{root}\\share2","--mount-write","{root}\\share\\writable","--mount-allow","{root}\\share\\hidden\\shown","--mount-deny","{root}\\share\\hidden","--mount-deny","{root}\\share2\\.\\data.txt","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}\\share,rw --mount-child 1-bf2faee2596026620b5cbc997c2d7d45,{root}\\share2,ro --mount-deny {root}\\share\\hidden --mount-deny {root}\\share2\\data.txt --mount-allow {root}\\share\\hidden\\shown --mount-write {root}\\share\\writable --cmdline \"nvx_share=0-bd47413b5c03dfc6e4b5b8143fe205ea,/data,rw nvx_share=1-bf2faee2596026620b5cbc997c2d7d45,/other,ro\"\r\n","stderr":""}]}, -{"name":"run, dry run: several shares with a command line","steps":[{"argv":["run","--mount","/data,{root}\\share,rw","--mount","/other,{root}\\share2","--cmdline","quiet","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}\\share,rw --mount-child 1-bf2faee2596026620b5cbc997c2d7d45,{root}\\share2,ro --cmdline \"quiet nvx_share=0-bd47413b5c03dfc6e4b5b8143fe205ea,/data,rw nvx_share=1-bf2faee2596026620b5cbc997c2d7d45,/other,ro\"\r\n","stderr":""}]}, -{"name":"run, dry run: one shared file","steps":[{"argv":["run","--mount","/etc/single.txt,{root}\\single.txt,ro","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-a80a05e9cb129bc27b7ba103bf2f5ac0,{root}\\single.txt,ro,file --cmdline nvx_share=0-a80a05e9cb129bc27b7ba103bf2f5ac0,/etc/single.txt,ro,file\r\n","stderr":""}]}, -{"name":"run, dry run: one relative shared file","steps":[{"argv":["run","--mount","/etc/single.txt,single.txt","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-a80a05e9cb129bc27b7ba103bf2f5ac0,single.txt,ro,file --cmdline nvx_share=0-a80a05e9cb129bc27b7ba103bf2f5ac0,/etc/single.txt,ro,file\r\n","stderr":""}]}, -{"name":"run, dry run: a directory and a file","steps":[{"argv":["run","--mount","/work,{root}\\share,rw","--mount","/config/single.txt,{root}\\single.txt","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-0c9a453fad615c83c57d57c2b2be05fa,{root}\\share,rw --mount-child 1-e4a388b9bb5f3ffa9c918a940c785615,{root}\\single.txt,ro,file --cmdline \"nvx_share=0-0c9a453fad615c83c57d57c2b2be05fa,/work,rw nvx_share=1-e4a388b9bb5f3ffa9c918a940c785615,/config/single.txt,ro,file\"\r\n","stderr":""}]}, -{"name":"run, dry run: host paths with commas","steps":[{"argv":["run","--mount","/work,{root}\\alpha,beta,rw","--mount","/reports,{root}\\2026, final,ro","--mount","/config/settings.json,{root}\\settings,v2.json,ro","--mount-deny","{root}\\alpha,beta\\data.txt","--dry-run"],"write":{"alpha,beta/data.txt":"data\n","2026, final/data.txt":"data\n","settings,v2.json":"{}\n"},"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-0c9a453fad615c83c57d57c2b2be05fa,{root}\\alpha,beta,rw --mount-child \"1-420499c21ee058ef02f65f165f3d41da,{root}\\2026, final,ro\" --mount-child 2-67287998b6e12c15adb9346817eff41d,{root}\\settings,v2.json,ro,file --mount-deny {root}\\alpha,beta\\data.txt --cmdline \"nvx_share=0-0c9a453fad615c83c57d57c2b2be05fa,/work,rw nvx_share=1-420499c21ee058ef02f65f165f3d41da,/reports,ro nvx_share=2-67287998b6e12c15adb9346817eff41d,/config/settings.json,ro,file\"\r\n","stderr":""}]}, -{"name":"run, dry run: one directory with commas","steps":[{"argv":["run","--mount","/work,{root}\\alpha,beta,rw","--dry-run"],"write":{"alpha,beta/data.txt":"data\n","2026, final/data.txt":"data\n","settings,v2.json":"{}\n"},"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount /work,{root}\\alpha,beta,rw\r\n","stderr":""}]}, -{"name":"run, dry run: host path ending in a mode","steps":[{"argv":["run","--mount","/data,{root}\\share,rw,ro","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount /data,{root}\\share,rw,ro\r\n","stderr":""}]}, -{"name":"run, dry run: host path ending in a comma","steps":[{"argv":["run","--mount","/data,{root}\\share,,rw","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount /data,{root}\\share,,rw\r\n","stderr":""}]}, -{"name":"run, dry run: vmm owner","steps":[{"argv":["run","--mount","/data,{root}\\share","--mount-owner","vmm","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount /data,{root}\\share,ro --mount-owner vmm\r\n","stderr":""}]}, -{"name":"run, dry run: vmm owner of several shares","steps":[{"argv":["run","--mount","/data,{root}\\share,rw","--mount","/other,{root}\\share2","--mount-owner","vmm","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}\\share,rw --mount-child 1-bf2faee2596026620b5cbc997c2d7d45,{root}\\share2,ro --mount-owner vmm --cmdline \"nvx_share=0-bd47413b5c03dfc6e4b5b8143fe205ea,/data,rw nvx_share=1-bf2faee2596026620b5cbc997c2d7d45,/other,ro\"\r\n","stderr":""}]}, -{"name":"run, dry run: restore with shares","steps":[{"argv":["run","--restore-snapshot","{root}\\snapshot","--mount","/data,{root}\\share,rw","--mount","/other,{root}\\share2","--mount","/etc/single.txt,{root}\\single.txt","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --restore-snapshot {root}\\snapshot --mount-aggregate /run/nvx/shares --mount-child 0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}\\share,rw --mount-child 1-bf2faee2596026620b5cbc997c2d7d45,{root}\\share2,ro --mount-child 2-a80a05e9cb129bc27b7ba103bf2f5ac0,{root}\\single.txt,ro,file\r\n","stderr":""}]}, -{"name":"run, dry run: restore with shares and a command line","steps":[{"argv":["run","--restore-snapshot","{root}\\snapshot","--mount","/data,{root}\\share,rw","--mount","/other,{root}\\share2","--cmdline","quiet","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --restore-snapshot {root}\\snapshot --mount-aggregate /run/nvx/shares --mount-child 0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}\\share,rw --mount-child 1-bf2faee2596026620b5cbc997c2d7d45,{root}\\share2,ro --cmdline quiet\r\n","stderr":""}]}, -{"name":"run, dry run: network","steps":[{"argv":["run","--net","10.0.0.2/24","--network-profile","portable","--network-egress","deny","--network-ingress","allow","--network-egress-allow","10.0.0.0/8:tcp:443","--network-egress-allow","2001:db8::/32","--network-egress-deny","10.1.0.0/16","--host-loopback","allow","--network-proxy","10.0.0.1:3128","--host-loopback-forward","tcp:8080:80","--host-loopback-forward","udp:5353:53","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --net 10.0.0.2/24 --network-profile portable --network-egress deny --network-ingress allow --network-egress-allow 10.0.0.0/8:tcp:443 --network-egress-allow 2001:db8::/32 --network-egress-deny 10.1.0.0/16 --host-loopback allow --network-proxy 10.0.0.1:3128 --host-loopback-forward tcp:8080:80 --host-loopback-forward udp:5353:53\r\n","stderr":""}]}, -{"name":"run, dry run: egress default","steps":[{"argv":["run","--network-egress","deny","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --network-egress deny\r\n","stderr":""}]}, -{"name":"run, dry run: host loopback forward","steps":[{"argv":["run","--host-loopback-forward","tcp:8080:80","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --host-loopback-forward tcp:8080:80\r\n","stderr":""}]}, -{"name":"run, dry run: egress policy file","steps":[{"argv":["run","--network-egress","deny","--network-egress-policy-file","{root}\\policy.json","--dry-run"],"write":{"policy.json":"{\"allow\": [{\"cidr\": \"192.0.2.0/24\", \"except\": [\"192.0.2.128/25\"]}, {\"cidr\": \"2001:db8::/32\", \"protocol\": \"tcp\", \"port\": 443}], \"deny\": [{\"cidr\": \"198.51.100.0/24\", \"protocol\": \"udp\"}]}"},"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --network-egress deny --network-egress-allow 192.0.2.0/25 --network-egress-allow 2001:db8::/32:tcp:443 --network-egress-deny 198.51.100.0/24:udp\r\n","stderr":""}]}, -{"name":"run, dry run: empty egress policy file","steps":[{"argv":["run","--network-egress","allow","--network-egress-policy-file","{root}\\.\\policy.json","--dry-run"],"write":{"policy.json":"{}"},"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --network-egress allow\r\n","stderr":""}]}, -{"name":"run, dry run: outcome report path","steps":[{"argv":["run","--outcome-report","reports//./outcome.json","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --microvm-report reports\\outcome.json\r\n","stderr":""}]}, -{"name":"run, dry run: quoted command line","steps":[{"argv":["run","--cmdline","a=\"b c\" d","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --cmdline \"a=\\\"b c\\\" d\"\r\n","stderr":""}]}, -{"name":"run, dry run: command line starting with a dash","steps":[{"argv":["run","--cmdline=-x","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --cmdline -x\r\n","stderr":""}]}, -{"name":"run, dry run: command line of help","steps":[{"argv":["run","--cmdline=--help","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --cmdline --help\r\n","stderr":""}]}, -{"name":"run, dry run: empty command line","steps":[{"argv":["run","--cmdline","","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz\r\n","stderr":""}]}, -{"name":"run, dry run: blank command line","steps":[{"argv":["run","--cmdline"," ","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --cmdline \" \"\r\n","stderr":""}]}, -{"name":"run, dry run: last command line","steps":[{"argv":["run","--cmdline","a","--cmdline","b","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --cmdline b\r\n","stderr":""}]}, -{"name":"run, dry run: long command line of one directory share","steps":[{"argv":["run","--mount","/data,{root}\\share","--cmdline","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount /data,{root}\\share,ro --cmdline xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n","stderr":""}]}, -{"name":"run, dry run: restore without the budget","steps":[{"argv":["run","--restore-snapshot","{root}\\snapshot","--mount","/share/00,{root}\\share","--mount","/share/01,{root}\\share","--mount","/share/02,{root}\\share","--mount","/share/03,{root}\\share","--mount","/share/04,{root}\\share","--mount","/share/05,{root}\\share","--mount","/share/06,{root}\\share","--mount","/share/07,{root}\\share","--mount","/share/08,{root}\\share","--mount","/share/09,{root}\\share","--mount","/share/10,{root}\\share","--mount","/share/11,{root}\\share","--mount","/share/12,{root}\\share","--mount","/share/13,{root}\\share","--mount","/share/14,{root}\\share","--mount","/share/15,{root}\\share","--mount","/share/16,{root}\\share","--mount","/share/17,{root}\\share","--mount","/share/18,{root}\\share","--mount","/share/19,{root}\\share","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --restore-snapshot {root}\\snapshot --mount-aggregate /run/nvx/shares --mount-child 0-704877e89d67577706337193ea7633b4,{root}\\share,ro --mount-child 1-932de0c49c6028fcd06c916b12e85dd0,{root}\\share,ro --mount-child 2-8fe971438e3c6dc554c24acb8a258e68,{root}\\share,ro --mount-child 3-07f68b1ee523306daef281712c084aa1,{root}\\share,ro --mount-child 4-213df498e81ccc26ac4af55922a700ef,{root}\\share,ro --mount-child 5-42c910809b4f1f69618448eeabb2ae5e,{root}\\share,ro --mount-child 6-5023082ea84414bad3b03c04b52810d0,{root}\\share,ro --mount-child 7-c1fab5a21a3b346322ba23c2e823471f,{root}\\share,ro --mount-child 8-924dd7c11ac4cdf2fad054fad5f660f1,{root}\\share,ro --mount-child 9-9e8477038c0405f8315bb3a972cf0b94,{root}\\share,ro --mount-child 10-0637273ad7c907a15b9265a330a14394,{root}\\share,ro --mount-child 11-085c8b2a421428955a7be66cbdac1217,{root}\\share,ro --mount-child 12-7b8b460bdbaed75e2f245c36c494c8da,{root}\\share,ro --mount-child 13-c759475ce548cda605edd48ff0349060,{root}\\share,ro --mount-child 14-c7604fc1e13e1acaffa49a4fb7baba0a,{root}\\share,ro --mount-child 15-f5de35f367fadbf3bfd873291f70902a,{root}\\share,ro --mount-child 16-636f3a16dd53675d0d36ecbcfc93ce18,{root}\\share,ro --mount-child 17-92813153a4c548a68fb66602ca92779c,{root}\\share,ro --mount-child 18-b8f15bc78ddfccd02383fbbec973f623,{root}\\share,ro --mount-child 19-482c6e9b01cb3bd040af96260661231d,{root}\\share,ro\r\n","stderr":""}]}, -{"name":"run, dry run: budget fits","steps":[{"argv":["run","--mount","/a,{root}\\share","--mount","/b,{root}\\share2,rw","--cmdline","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","--dry-run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-6a50dc8584134c7de537c0052ff6d236,{root}\\share,ro --mount-child 1-9812b0b9d61e09b927d03ff93f64530d,{root}\\share2,rw --cmdline \"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx nvx_share=0-6a50dc8584134c7de537c0052ff6d236,/a,ro nvx_share=1-9812b0b9d61e09b927d03ff93f64530d,/b,rw\"\r\n","stderr":""}]}, -{"name":"run, launch: boot","steps":[{"argv":["run"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz\r\nopenvmm: booted the microVM\n","stderr":""}]}, -{"name":"run, launch: exit status","steps":[{"argv":["run","--cmdline","fake_exit_status=7"],"status":7,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --cmdline fake_exit_status=7\r\nopenvmm: booted the microVM\n","stderr":""}]}, -{"name":"run, launch: failed boot","steps":[{"argv":["run","--cmdline","quiet fake_exit_status=1"],"status":1,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --cmdline \"quiet fake_exit_status=1\"\r\nopenvmm: booted the microVM\n","stderr":""}]}, -{"name":"run, launch: Ubuntu","steps":[{"argv":["run","--guest","ubuntu","--memory-capacity-mib","1024"],"write":{"build/initramfs-ubuntu.cpio.gz":"ubuntu\n"},"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 512M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs-ubuntu.cpio.gz --memory-capacity 1024M\r\nopenvmm: booted the microVM\n","stderr":""}]}, -{"name":"run, launch: every boot option","steps":[{"argv":["run","--hypervisor","mshv","--processors","8","--cpu-profile","host","--memory-mib","256","--memory-capacity-mib","512"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 8 --hypervisor mshv --memory 256M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --memory-capacity 512M --cpu-profile host\r\nopenvmm: booted the microVM\n","stderr":""}]}, -{"name":"run, launch: restore","steps":[{"argv":["run","--processors","4","--restore-snapshot","{root}\\snapshot","--restore-processors","2","--restore-memory-mib","1024","--restore-ready-path","{root}\\ready.sock","--cpu-profile","auto"],"write":{"snapshot/state.bin":"snapshot\n"},"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 4 --hypervisor whp --restore-snapshot {root}\\snapshot --restore-processors 2 --restore-memory 1024M --restore-ready-path {root}\\ready.sock --cpu-profile auto\r\nopenvmm: restored the microVM\n","stderr":""}]}, -{"name":"run, launch: restore without guest artifacts","steps":[{"argv":["run","--restore-snapshot","{root}\\snapshot"],"write":{"snapshot/state.bin":"snapshot\n"},"remove":["build/vmlinux","build/initramfs.cpio.gz"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --restore-snapshot {root}\\snapshot\r\nopenvmm: restored the microVM\n","stderr":""}]}, -{"name":"run, launch: missing snapshot","steps":[{"argv":["run","--restore-snapshot","{root}\\missing","--cmdline","quiet"],"status":1,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --restore-snapshot {root}\\missing --cmdline quiet\r\n","stderr":"openvmm: cannot restore {root}\\missing: no such snapshot directory\n"}]}, -{"name":"run, launch: outcome report","steps":[{"argv":["run","--outcome-report","{root}\\reports\\openvmm-run.json"],"check":["reports/openvmm-run.json","build/fake-openvmm-reports.json"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --microvm-report {root}\\reports\\openvmm-run.json\r\nopenvmm: booted the microVM\n","stderr":"","files":{"reports/openvmm-run.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\": \"run\",\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"},"build/fake-openvmm-reports.json":{"text":"[\"--single-process\",\"--machine\",\"microvm\",\"--processors\",\"1\",\"--hypervisor\",\"whp\",\"--memory\",\"128M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--microvm-report\",\"{root_json}\\\\reports\\\\openvmm-run.json\"]"}}}]}, -{"name":"run, launch: restore outcome report","steps":[{"argv":["run","--restore-snapshot","{root}\\snapshot","--outcome-report","{root}\\reports\\openvmm-run.json","--cmdline","fake_exit_status=4"],"write":{"snapshot/state.bin":"snapshot\n"},"check":["reports/openvmm-run.json","fake-openvmm-reports.json"],"status":4,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --restore-snapshot {root}\\snapshot --microvm-report {root}\\reports\\openvmm-run.json --cmdline fake_exit_status=4\r\nopenvmm: restored the microVM\n","stderr":"","files":{"reports/openvmm-run.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\": \"guest-exit\",\n \"operation\": \"run\",\n \"status_code\": 4\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"},"fake-openvmm-reports.json":{"text":"[\"--single-process\",\"--machine\",\"microvm\",\"--processors\",\"1\",\"--hypervisor\",\"whp\",\"--restore-snapshot\",\"{root_json}\\\\snapshot\",\"--microvm-report\",\"{root_json}\\\\reports\\\\openvmm-run.json\",\"--cmdline\",\"fake_exit_status=4\"]"}}}]}, -{"name":"run, launch: network outcome report","steps":[{"argv":["run","--net","10.0.0.2/24","--network-profile","portable","--network-egress","deny","--network-egress-allow","10.0.0.0/8:tcp:443","--host-loopback","deny","--outcome-report","{root}\\reports\\openvmm-run.json"],"check":["reports/openvmm-run.json"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --net 10.0.0.2/24 --network-profile portable --network-egress deny --network-egress-allow 10.0.0.0/8:tcp:443 --host-loopback deny --microvm-report {root}\\reports\\openvmm-run.json\r\nopenvmm: booted the microVM\n","stderr":"","files":{"reports/openvmm-run.json":{"text":"{\n \"backend\": \"whp\",\n \"instance_id\": \"{hex32}\",\n \"network_policy\": {\n \"allow_rule_count\": 1,\n \"deny_rule_count\": 0,\n \"host_loopback\": \"deny\",\n \"mode\": \"rules\",\n \"status\": \"applied\",\n \"status_code\": 0\n },\n \"outcome\": {\n \"category\": \"success\",\n \"operation\": \"run\",\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"}}}]}, -{"name":"run, launch: one share","steps":[{"argv":["run","--mount","/data,{root}\\share,rw","--mount-deny","hidden","--mount-allow","hidden/shown","--mount-write","writable"],"check":["build/fake-openvmm-.json"],"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount /data,{root}\\share,rw --mount-deny hidden --mount-allow hidden\\shown --mount-write writable\r\nopenvmm: booted the microVM\n","stderr":"","files":{"build/fake-openvmm-.json":{"text":"[\"--single-process\",\"--machine\",\"microvm\",\"--processors\",\"1\",\"--hypervisor\",\"whp\",\"--memory\",\"128M\",\"--kernel\",\"{root_json}\\\\build\\\\vmlinux\",\"--initrd\",\"{root_json}\\\\build\\\\initramfs.cpio.gz\",\"--mount\",\"/data,{root_json}\\\\share,rw\",\"--mount-deny\",\"hidden\",\"--mount-allow\",\"hidden\\\\shown\",\"--mount-write\",\"writable\"]"}}}]}, -{"name":"run, launch: several shares and a file","steps":[{"argv":["run","--mount","/data,{root}\\share","--mount","/single.txt,{root}\\single.txt","--mount-deny","{root}\\share\\hidden","--cmdline","fake_exit_status=3"],"status":3,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --mount-aggregate /run/nvx/shares --mount-child 0-bd47413b5c03dfc6e4b5b8143fe205ea,{root}\\share,ro --mount-child 1-aa0054d8b9fab367d76492228c7bb459,{root}\\single.txt,ro,file --mount-deny {root}\\share\\hidden --cmdline \"fake_exit_status=3 nvx_share=0-bd47413b5c03dfc6e4b5b8143fe205ea,/data,ro nvx_share=1-aa0054d8b9fab367d76492228c7bb459,/single.txt,ro,file\"\r\nopenvmm: booted the microVM\n","stderr":""}]}, -{"name":"run, launch: OpenVMM refuses its options","steps":[{"argv":["run","--host-loopback-forward","tcp:8080:80"],"status":2,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz --host-loopback-forward tcp:8080:80\r\n","stderr":"openvmm: --host-loopback-forward requires explicit --host-loopback allow\n"}]}, -{"name":"run, launch: relative OpenVMM override","steps":[{"argv":["run"],"env":{"NVX_OPENVMM":"openvmm\\target\\release\\openvmm{exe}"},"status":0,"stdout":">> {root}\\openvmm\\target\\release\\openvmm.exe --single-process --machine microvm --processors 1 --hypervisor whp --memory 128M --kernel {root}\\build\\vmlinux --initrd {root}\\build\\initramfs.cpio.gz\r\nopenvmm: booted the microVM\n","stderr":""}]}, -{"name":"run, launch: missing OpenVMM","steps":[{"argv":["run"],"remove":["openvmm/target/release/openvmm{exe}"],"status":1,"stdout":"","stderr":"error[artifact-missing]: OpenVMM release binary not found: {root}\\openvmm\\target\\release\\openvmm.exe\r\n"}]}, -{"name":"run, launch: missing kernel","steps":[{"argv":["run"],"remove":["build/vmlinux"],"status":1,"stdout":"","stderr":"error[artifact-missing]: Linux direct kernel not found: {root}\\build\\vmlinux\r\n"}]}, -{"name":"run, launch: missing initramfs","steps":[{"argv":["run"],"remove":["build/initramfs.cpio.gz"],"status":1,"stdout":"","stderr":"error[artifact-missing]: Alpine Linux initramfs not found: {root}\\build\\initramfs.cpio.gz\r\n"}]}, -{"name":"run, launch: missing Ubuntu initramfs","steps":[{"argv":["run","--guest","ubuntu"],"status":1,"stdout":"","stderr":"error[artifact-missing]: Ubuntu Base initramfs not found: {root}\\build\\initramfs-ubuntu.cpio.gz\r\n"}]} -] -} diff --git a/nvx-rs/tests/fixtures/run-help.txt b/nvx-rs/tests/fixtures/run-help.txt new file mode 100644 index 000000000..09ce1d629 --- /dev/null +++ b/nvx-rs/tests/fixtures/run-help.txt @@ -0,0 +1,83 @@ +usage: nvx-rs run [-h] [--guest {alpine,ubuntu,azurelinux}] + [--hypervisor {auto,whp,kvm,mshv}] [--machine {microvm}] + [--memory-mib MEMORY_MIB] + [--memory-capacity-mib MEMORY_CAPACITY_MIB] + [--processors {1,2,4,8}] [--cpu-profile ID] + [--mount GUEST_TARGET,HOST_PATH[,ro|rw]] + [--mount-deny MOUNT_DENY] [--mount-allow HOST_PATH] + [--mount-write HOST_PATH] [--mount-owner {vmm,caller}] + [--net IPV4/PREFIX] [--network-profile {portable}] + [--network-egress {allow,deny}] + [--network-ingress {allow,deny}] + [--network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]]] + [--network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]]] + [--network-egress-policy-file PATH] + [--host-loopback {allow,deny}] + [--network-proxy IPV4:TCP-PORT] + [--host-loopback-forward HOST_LOOPBACK_FORWARD] + [--outcome-report OUTCOME_REPORT] [--cmdline CMDLINE] + [--restore-snapshot RESTORE_SNAPSHOT] + [--restore-processors {1,2,4,8}] + [--restore-memory-mib RESTORE_MEMORY_MIB] + [--restore-ready-path RESTORE_READY_PATH] [--dry-run] + +options: + -h, --help show this help message and exit + --guest {alpine,ubuntu,azurelinux} + --hypervisor {auto,whp,kvm,mshv} + --machine {microvm} + --memory-mib MEMORY_MIB + guest RAM in MiB (default by --guest: alpine 128, + ubuntu 512, azurelinux 512) + --memory-capacity-mib MEMORY_CAPACITY_MIB + --processors {1,2,4,8} + --cpu-profile ID OpenVMM CPU profile: auto (OpenVMM's default) for the + built-in profile of the host's CPU, a built-in profile + ID, or host to derive a development profile from this + host (doc/usage.md) + --mount GUEST_TARGET,HOST_PATH[,ro|rw] + live-share a host directory, or a single regular host + file without its directory; the mode follows the last + comma, so HOST_PATH may contain commas when the mode + is given; repeat for more shares, each with its own + guest target and mode, as children of one virtio-fs + device + --mount-deny MOUNT_DENY + --mount-allow HOST_PATH + expose one existing path inside a --mount-deny path + again + --mount-write HOST_PATH + make one existing path one of the only writable parts + of a read-write --mount + --mount-owner {vmm,caller} + host identity of the share's file operations: vmm + (default) or caller, with guest root squashed to the + owner of the shared directory or file (Linux only) + --net IPV4/PREFIX + --network-profile {portable} + --network-egress {allow,deny} + --network-ingress {allow,deny} + --network-egress-allow CIDR[:PROTOCOL[:PORT[-PORT]]] + allow guest egress to an IPv4 or IPv6 CIDR, optionally + only for PROTOCOL tcp, udp, or icmp, and for tcp or + udp only on PORT or on the inclusive range PORT-PORT; + repeat to add rules + --network-egress-deny CIDR[:PROTOCOL[:PORT[-PORT]]] + deny guest egress to an IPv4 or IPv6 CIDR, optionally + only for PROTOCOL tcp, udp, or icmp, and for tcp or + udp only on PORT or on the inclusive range PORT-PORT; + repeat to add rules + --network-egress-policy-file PATH + load bounded MXC-shaped IPv4 and IPv6 egress rules + from JSON + --host-loopback {allow,deny} + --network-proxy IPV4:TCP-PORT + --host-loopback-forward HOST_LOOPBACK_FORWARD + --outcome-report OUTCOME_REPORT + write a bounded local JSON outcome report + --cmdline CMDLINE + --restore-snapshot RESTORE_SNAPSHOT + --restore-processors {1,2,4,8} + --restore-memory-mib RESTORE_MEMORY_MIB + --restore-ready-path RESTORE_READY_PATH + --dry-run diff --git a/nvx-rs/tests/fixtures/state/format-7-without-shares.json b/nvx-rs/tests/fixtures/state/format-7-without-shares.json new file mode 100644 index 000000000..06aec6e6a --- /dev/null +++ b/nvx-rs/tests/fixtures/state/format-7-without-shares.json @@ -0,0 +1,23 @@ +{ + "cmdline": "quiet", + "distro_binding": "{distro_binding}", + "export": null, + "format": 7, + "hostname": "reader", + "hypervisor": "{hypervisor}", + "layers": [ + { + "path": "{root/distro.erofs}", + "role": "distro", + "uuid": "11111111-1111-1111-1111-111111111111" + } + ], + "memory_max": 134217728, + "memory_mib": 320, + "network": null, + "pids_max": 32, + "scratch": "{root/scratch.ext4}", + "scratch_binding": "{scratch_binding}", + "workload_gid": 2000, + "workload_uid": 2000 +} diff --git a/scripts/nvx_rs_coverage.py b/scripts/nvx_rs_coverage.py index 79717f988..9102792f8 100644 --- a/scripts/nvx_rs_coverage.py +++ b/scripts/nvx_rs_coverage.py @@ -82,9 +82,6 @@ class Family: Family( "launch-profile", "Launch profile and options", ("host::sandbox::golden::",) ), - Family( - "cli-scenarios", "CLI scenarios", ("nvx_rs_reproduces_the_recorded_scenarios",) - ), ) diff --git a/scripts/test_guest_binaries.py b/scripts/test_guest_binaries.py index fd7df2633..2a9dd148b 100644 --- a/scripts/test_guest_binaries.py +++ b/scripts/test_guest_binaries.py @@ -520,7 +520,7 @@ def test_build_refuses_inputs_that_the_source_identity_omits(self): ( "directory in the checkout", crate / "tests" / "fixtures", - "source identity omits.*nvx-rs/tests/fixtures/cli.json", + "source identity omits.*nvx-rs/tests/fixtures/root-tokens.json", ), ( "file outside the checkout", diff --git a/scripts/test_nvx_tools.py b/scripts/test_nvx_tools.py index df0747d91..bfbcf1250 100644 --- a/scripts/test_nvx_tools.py +++ b/scripts/test_nvx_tools.py @@ -820,28 +820,14 @@ def test_run_help_and_usage_state_each_guest_memory_default(self): self.assertIn(f"{name} {default}", help_text) self.assertIn(f"{default} for {labels[name]}", row) - def test_run_help_and_memory_defaults_are_those_that_nvx_rs_replays(self): - # nvx.py run runs nvx-rs run, whose golden scenarios replay the help - # and the dry runs that nvx.py run recorded, so they pin its help and - # the default memory of each guest, which guests.py also gives - # test-microvm, to those of nvx-rs. - fixture = json.loads( - (nvx_rs.DIRECTORY / "tests" / "fixtures" / "cli.json").read_text( - encoding="utf-8" - ) - ) - section = "windows" if os.name == "nt" else "posix" - scenarios = { - cast(str, scenario["name"]): cast( - list[dict[str, object]], scenario["steps"] - )[0] - for scenario in cast(list[dict[str, object]], fixture[section]) - } - - def recorded(name: str) -> str: - stdout = cast(str, scenarios[f"run, {name}"]["stdout"]) - return stdout.replace("\r\n", "\n") - + def test_run_help_is_the_help_of_nvx_rs_run(self): + # nvx.py run parses the options of nvx-rs run before it runs it, so it + # prints the help that the scenario tests of nvx-rs pin in + # run-help.txt, which gives the default memory of each guest that + # guests.py also gives test-microvm. + help_of_nvx_rs = ( + nvx_rs.DIRECTORY / "tests" / "fixtures" / "run-help.txt" + ).read_text(encoding="utf-8") stdout = io.StringIO() with ( patch.dict(os.environ, {"COLUMNS": "80", "NO_COLOR": "1"}), @@ -850,22 +836,17 @@ def recorded(name: str) -> str: self.assertRaises(SystemExit), ): nvx.parse_args(["run", "--help"]) - expected = recorded("usage: help").replace("nvx-rs run", "nvx.py run", 1) + expected = help_of_nvx_rs.replace("nvx-rs run", "nvx.py run", 1) if sys.version_info >= (3, 14): self.assertEqual(stdout.getvalue(), expected) else: # Older releases of argparse wrap some of the help differently. self.assertEqual(stdout.getvalue().split(), expected.split()) - labels = { - "alpine": "Alpine", - "ubuntu": "Ubuntu", - "azurelinux": "Azure Linux", - } + help_text = " ".join(help_of_nvx_rs.split()) for name in guests.GUEST_NAMES: default = guests.guest_descriptor(name).default_memory_mib with self.subTest(guest=name): - command = recorded(f"dry run: {labels[name]} default") - self.assertIn(f" --memory {default}M ", command) + self.assertIn(f"{name} {default}", help_text) def test_benchmark_exposes_device_restore_profile(self): args = nvx.parse_args(