Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/run-nvx-microvm-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ jobs:
--scenario sandbox-lifecycle
--scenario sandbox-proxy-only
--scenario sandbox-ram-upper
--scenario sandbox-gpt-layer
--scenario vm-lifecycle
--output-dir "build/test-results/public-exec-${{ inputs.backend }}"

- name: Run public managed sandbox acceptance on Windows
Expand All @@ -249,6 +251,8 @@ jobs:
--scenario sandbox-lifecycle
--scenario sandbox-proxy-only
--scenario sandbox-ram-upper
--scenario sandbox-gpt-layer
--scenario vm-lifecycle
--output-dir "build/test-results/public-exec-${{ inputs.backend }}"

- name: Run Ubuntu guest smoke tests on Linux
Expand Down
65 changes: 48 additions & 17 deletions doc/acceptance-case-matrix.md

Large diffs are not rendered by default.

18 changes: 11 additions & 7 deletions doc/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -545,8 +545,8 @@ such an execution: the fixed identity, empty capability sets and
overlay root over read-only image layers with its upper directory on scratch.
The live-share runs below repeat the profile checks. Each
backend also runs the public `managed-exec-config`, `sandbox-lifecycle`,
`sandbox-proxy-only`, and `sandbox-ram-upper` scenarios of `test-microvm`,
which drive `nvx-rs sandbox run`, `provision`, `start`,
`sandbox-proxy-only`, `sandbox-ram-upper`, and `sandbox-gpt-layer` scenarios
of `test-microvm`, which drive `nvx-rs sandbox run`, `provision`, `start`,
`exec`, `stop`, and `deprovision` as subprocesses (see
[Run](run.md#managed-lifecycle)): request-scoped working directories and
environments, timeouts, nonzero exits, stdout and stderr, bounded output and
Expand All @@ -555,8 +555,12 @@ refusal, fail-closed lifecycle transitions, a crashed OpenVMM's stale runtime
state, teardown that leaves no OpenVMM process, control endpoint,
capability, or runtime record while the layer and scratch artifacts survive,
a proxy-only network, whose guest reaches a test proxy on host loopback at
its gateway and no other destination, and sandboxes whose overlay upper is a
tmpfs in guest memory, with no scratch image.
its gateway and no other destination, sandboxes whose overlay upper is a
tmpfs in guest memory, with no scratch image, and sandboxes whose root is a
GPT disk, over either upper, so that the three backends run the CLI's twelve
cold cells (see the [case matrix](acceptance-case-matrix.md#cold-boots)). The
public `vm-lifecycle` scenario then creates, spawns, reattaches to, and stops
a VM through the public API of `nvx`.
Their bounded evidence is part of the backend's failure logs. The same
entrypoint then verifies a live virtio-fs
share inside the container: a read-write `/workspace` share with a denied
Expand Down Expand Up @@ -687,9 +691,9 @@ platform jobs don't take it, but the package job of each platform downloads
both through the
[`package-release`](../.github/actions/package-release/action.yml) action,
the provenance into `build/`, so that each package ships the `nvx-rs` of its
operating system. The `managed-lifecycle` scenario also builds
and runs the ignored `nvx-rs` test `tests/managed_lifecycle.rs` with Cargo on
the runner.
operating system. The `managed-lifecycle` and `vm-lifecycle` scenarios also
build and run the ignored `nvx-rs` tests `tests/managed_lifecycle.rs` and
`tests/vm_lifecycle.rs` with Cargo on the runner.

Once the required artifacts are
ready, benchmarks run in parallel with the NVX test layer, each on its backend's
Expand Down
8 changes: 5 additions & 3 deletions doc/contribute.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,16 @@ devices. Add those scenarios to
The scenarios that drive the public `nvx-rs sandbox` commands live in
`scripts/nvx_tools/managed_exec_tests.py`,
`scripts/nvx_tools/sandbox_lifecycle_tests.py`,
`scripts/nvx_tools/sandbox_proxy_tests.py`, and
`scripts/nvx_tools/sandbox_ram_upper_tests.py`, and `microvm_tests.py`
`scripts/nvx_tools/sandbox_proxy_tests.py`,
`scripts/nvx_tools/sandbox_ram_upper_tests.py`, and `microvm_tests.py`, which
registers them. `sandbox` and the control protocol belong to `nvx-rs`
([microsoft/nvx#359](https://github.com/microsoft/nvx/issues/359)), so the
scenarios drive them as commands, compile egress policies with
`nvx-rs egress compile`, and leave the control session to `nvx-rs`: the
`managed-lifecycle` scenario builds OpenVMM's command line and runs the ignored
`nvx-rs` test `tests/managed_lifecycle.rs`, which drives the guest. Add no
`nvx-rs` test `tests/managed_lifecycle.rs`, which drives the guest, and the
`vm-lifecycle` scenario runs the ignored test `tests/vm_lifecycle.rs`, which
drives a VM through the public API of `nvx`. Add no
Python client of the control protocol, lifecycle, or egress logic.

Unit tests for the host tooling live in `scripts/test_*.py`. The `nvx` crate
Expand Down
2 changes: 1 addition & 1 deletion doc/project-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ nvx/
| | |-- guest/ Programs that run in Linux guests, the guest's NVXS connection, the libraries through which any guest init or agent opens the terminal on which it serves its session, starts a program, collects its children's statuses, settles its executions' cgroups, drives each execution, mounts host mappings beneath the descriptors of the roots that it names, assembles and tears down a layered root, and reads a GPT disk's partition table through its block device, and the typed calls through which it runs the time ABI's steps and the reseed (feature `guest`)
| | `-- bin/ nvx-rs CLI, nvx-fake-openvmm test double, and the guest binaries
| |-- examples/ The external-launch example, and the documented host and guest workflows, which only compile
| |-- tests/ Fake-OpenVMM instance lifecycle, sandbox store, CLI scenario, NVXS session, guest-binary, and hypervisor managed-lifecycle tests, the security checklist, the store's record fixtures and sandbox configurations of every format, the cases of the export and root boot tokens, and the conformance vectors of the wire formats
| |-- tests/ Fake-OpenVMM instance lifecycle, sandbox store, CLI scenario, NVXS session, guest-binary, and hypervisor managed-lifecycle and public-API VM lifecycle tests, the security checklist, the store's record fixtures and sandbox configurations of every format, the cases of the export and root boot tokens, and the conformance vectors of the wire formats
| |-- public-api/ The crate's public API on Linux and on Windows, which CI checks
| |-- build.rs Stages the bundled artifacts (feature `bundled`)
| `-- artifacts.json Release package pinned for the bundled artifacts
Expand Down
26 changes: 26 additions & 0 deletions doc/run.md
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,32 @@ bounded command observations, the runtime record, the output of the run, of
the probe, and of the guest's view, and the outcome reports of the run and of
both stops.

The `sandbox-gpt-layer` scenario of `test-microvm --backend BACKEND` is the
acceptance for a GPT disk, over either upper. It writes a GPT disk in its
temporary directory, whose first partition holds a few bytes and whose second,
its one layer, a guest of the Alpine control initramfs formats as ext4 and
fills with a copy of the tree of the Ubuntu EROFS layer. Then, over a scratch
upper and then a RAM upper, a run of `/sbin/nvx-sandbox-smoke` with
`--layer-format gpt` must print an OpenVMM command with the disk as its
read-only distro block device, and a scratch block device for a scratch upper
alone, whose kernel command line names the disk's GUID,
`nvx_layer=distro,0xd0003000,gpt:GUID`, the upper's token alone,
`nvx_sandbox=1`, and `nvx_mode=managed`. The probe must pass its checks of an
execution of nvx-init, and the run's `--outcome-report` must report the
success of the VM's stop and a complete teardown. A managed sandbox must record
the disk's format and GUID and the upper, pass the probe's managed checks, and
show its guest the same tokens, one virtio block device more for a scratch
upper, and the disk's layer partition as the lower directory of its root,
`/run/nvx/layers/p2`, before it stops with a successful outcome report and a
complete teardown and is deprovisioned. The disk keeps its digest throughout.
The scenario's evidence, with a `sandbox-gpt-layer-` prefix, holds the console
of the guest that wrote the disk, the bounded command observations, the runtime
record, the output of each run, probe, and view of the guest, and the outcome
reports of each run and stop. With `sandbox-lifecycle` and
`managed-exec-config`, which boot the EROFS layer over a scratch upper, and
`sandbox-ram-upper`, CI runs it on KVM, MSHV, and WHP: the CLI's twelve cold
cells, which the [case matrix](acceptance-case-matrix.md#cold-boots) lists.

### Live host shares

`sandbox run` and `sandbox provision` accept repeatable
Expand Down
18 changes: 13 additions & 5 deletions doc/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ this order:

Without `NVX_RS`, a built executable, or Cargo, they fail and name these
choices. They rebuild nothing once the executable exists. The
`managed-lifecycle` scenario also needs Cargo, which runs its `nvx-rs` test.
`managed-lifecycle` and `vm-lifecycle` scenarios also need Cargo, which runs
their `nvx-rs` tests.

The provenance of a checkout's `nvx-rs`, `build/nvx-rs.provenance.json`, binds
the SHA-256 of its executable to a digest of the `nvx-rs` sources that built
Expand Down Expand Up @@ -1251,9 +1252,10 @@ against the public OpenVMM CLI. Repeat `--scenario` to select a subset; without
it, every scenario supported by the selected guest runs, except `smp-lapic`,
which runs only when named: it repeats `smp` and also asserts that every CPU
uses the one-shot counting LAPIC. `managed-exec-config`, `sandbox-lifecycle`,
`sandbox-proxy-only`, and `sandbox-ram-upper`, the public sandbox scenarios,
drive the public `nvx-rs sandbox` lifecycle commands (see
[Run](run.md#managed-lifecycle)) and also read the Ubuntu distro layer, its
`sandbox-proxy-only`, `sandbox-ram-upper`, and `sandbox-gpt-layer`, the public
sandbox scenarios, drive the public `nvx-rs sandbox` lifecycle commands (see
[Run](run.md#managed-lifecycle)), and `vm-lifecycle` drives a VM through the
public API of `nvx`; they also read the Ubuntu distro layer, its
manifest, and the sandbox scratch template, which
[`download`](#download) installs and the guest-artifact build makes; a run
that selects one of them fails before its first scenario when one of those
Expand All @@ -1264,7 +1266,8 @@ and `virtio-features` scenarios and
the sandbox-control-dependent `snapshot-tiers`, `platform-restore-processors`,
`platform-zero-fill`, `platform-filesystem`, `platform-aggregate-export`,
`platform-network-policy`, `managed-exec-config`, `sandbox-lifecycle`,
`sandbox-proxy-only`, and `sandbox-ram-upper` scenarios. Ubuntu also rejects
`sandbox-proxy-only`, `sandbox-ram-upper`, `sandbox-gpt-layer`, and
`vm-lifecycle` scenarios. Ubuntu also rejects
the Alpine-prompt-specific `console-snapshot` scenario. `--debug-kernel` boots
the CI debug kernel, `build/vmlinux-debug`, whose soft-lockup and hung-task
detectors the guest's time ABI watcher reports; without `--scenario`, it runs
Expand Down Expand Up @@ -1303,6 +1306,11 @@ the boot to the managed agent, and runs the ignored `nvx-rs` test
`tests/managed_lifecycle.rs` with Cargo, which starts OpenVMM with the
scenario's command line and drives the guest's control session; the scenario
then checks OpenVMM's outcome report and the guest console. The
`vm-lifecycle` scenario runs the ignored `nvx-rs` test
`tests/vm_lifecycle.rs` with Cargo, which creates and spawns a VM of nvx-init
over the Ubuntu layer and a scratch copy through the public API of `nvx`,
reattaches to it from the values that it saved, and stops it through its
guest; the scenario then checks OpenVMM's outcome report. The
`virtio-features` scenario boots a guest with every fixed virtio device: the
NIC, the dormant host filesystem slot, both consoles, and both sandbox blocks.
The guest reports, for each device, the base of its MMIO window, its virtio
Expand Down
11 changes: 11 additions & 0 deletions nvx-rs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3621,6 +3621,17 @@ that it leaves:
python3 ../scripts/nvx.py test-microvm --backend kvm --scenario managed-lifecycle
```

`tests/vm_lifecycle.rs` is an ignored test of a cold VM's lifecycle through
the public API alone, on a real hypervisor: `host::vm::create`, `spawn`,
`reattach` from the values that the caller saved, once the launch is gone,
and `stop`, through a request to the guest, nvx-init, over the Ubuntu layer
and a scratch upper. `nvx.py test-microvm --scenario vm-lifecycle` gives it
its inputs, runs it with Cargo, and checks the outcome report that it leaves:

```bash
python3 ../scripts/nvx.py test-microvm --backend kvm --scenario vm-lifecycle
```

### Specification tests

The tests take their expectations from what this README and the documents
Expand Down
Loading
Loading