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
6 changes: 3 additions & 3 deletions doc/acceptance-case-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ suite in its shards, and the public sandbox scenarios in its guest and sandbox j
| `l3-l4-egress-protocols` | kept | |
| `lifecycle` | kept | |
| `managed-exec-config` | kept | A [cold cell](#cold-boots): the EROFS layer over a scratch upper, through `provision` and `start` |
| `managed-lifecycle` | kept | |
| `managed-lifecycle` | kept | It runs the ignored unit test of the host's private control session in `nvx-rs/src/host/session/tests/managed_lifecycle.rs`, with the `cli` feature, which SL6.12 (#1127) moved there from the crate's integration tests |
| `network-snapshot` | kept | |
| `platform-aggregate-export` | kept | |
| `platform-filesystem` | kept | |
Expand Down Expand Up @@ -504,9 +504,9 @@ this matrix. The README's own code is no doctest.
| `nvx-rs/src/host/template/plan.rs - host::template::plan::TemplatePlan (line 137)` | retired | `TemplatePlan` leaves with the template store (SL6.2a, #1121) |
| `nvx-rs/src/host/template/store.rs - host::template::store::Store (line 473)` | retired | The template store leaves (SL6.2a, #1121) |
| `nvx-rs/src/host/transport.rs - host::transport (line 22)` | kept | |
| `nvx-rs/src/lib.rs - (line 58)` | rewritten | Its `Instance` and sandbox store leave (SL6.1, #1121): `nvx-rs/src/lib.rs - (line 61)` compiles a cold boot and a stop through `host::vm` |
| `nvx-rs/src/lib.rs - (line 58)` | rewritten | Its `Instance` and sandbox store leave (SL6.1, #1121): `nvx-rs/src/lib.rs - (line 62)` compiles a cold boot and a stop through `host::vm` |
| `nvx-rs/src/protocol/nvxs/mod.rs - protocol::nvxs (line 68)` | kept | |
| `nvx-rs/src/host/snapshot/capture.rs - host::snapshot::capture::finish_capture (line 48)` | kept | |
| `nvx-rs/src/host/store/mod.rs - host::store (line 104)` | retired | The sandbox store leaves (SL6.1, #1121) |
| `nvx-rs/README.md`, its Example: an instance through `LaunchSpec` and the sandbox store | rewritten | Nothing compiles it. `nvx-rs/examples/host-workflows.rs` compiles the documented host workflows, and the library's guide (SL6.10a) replaces the example. SL6.1 (#1121) made it the cold boot that `nvx-rs/src/lib.rs - (line 61)` compiles |
| `nvx-rs/README.md`, its Example: an instance through `LaunchSpec` and the sandbox store | rewritten | Nothing compiles it. `nvx-rs/examples/host-workflows.rs` compiles the documented host workflows, and the library's guide (SL6.10a) replaces the example. SL6.1 (#1121) made it the cold boot that `nvx-rs/src/lib.rs - (line 62)` compiles |
| `nvx-rs/examples/external-launch.rs` | kept | Compiled with the crate's targets, and run by hand on a host |
5 changes: 3 additions & 2 deletions doc/adversarial-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ metadata and summary record the absolute target artifact root.
Besides the guest and OpenVMM artifacts, a target needs nvx-rs, the Rust
command-line interface that runs NVX's sandboxes and microVMs
([Usage](usage.md#nvx-rs)). Of the catalogued scenarios, `managed-lifecycle`
runs the nvx-rs test `managed_lifecycle` with Cargo, and
runs the nvx-rs unit test of its host control session,
`host::session::tests::managed_lifecycle`, with Cargo, and
`l3-l4-egress-policy` compiles its egress policy with nvx-rs and runs
`nvx-rs run`. They find nvx-rs at `NVX_RS`, then at
`nvx-rs/target/release/nvx-rs[.exe]`, and otherwise they build it there with
Expand All @@ -177,7 +178,7 @@ of the nvx-rs build:

```bash
cargo build --release --locked --features cli --manifest-path nvx-rs/Cargo.toml --target-dir nvx-rs/target
cargo test --no-run --locked --manifest-path nvx-rs/Cargo.toml --test managed_lifecycle
cargo test --no-run --locked --manifest-path nvx-rs/Cargo.toml --features cli --lib
python3 scripts/nvx.py record-nvx-rs-provenance
```

Expand Down
5 changes: 3 additions & 2 deletions doc/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -697,8 +697,9 @@ 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` 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.
build and run the ignored `nvx-rs` tests
`src/host/session/tests/managed_lifecycle.rs`, a unit test of the library with
the `cli` feature, 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
3 changes: 2 additions & 1 deletion doc/contribute.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ registers them. `sandbox` and the control protocol belong to `nvx-rs`
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, and the
`nvx-rs` unit test `src/host/session/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.
Expand Down
2 changes: 1 addition & 1 deletion doc/project-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,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 behavior, process and VM spawn, CLI scenario, NVXS session, guest-binary, and hypervisor managed-lifecycle and public-API VM lifecycle tests, the security checklist, 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 behavior, process and VM spawn, CLI scenario, NVXS session, guest-binary, and hypervisor public-API VM lifecycle tests, the security checklist, 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
5 changes: 3 additions & 2 deletions doc/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -1303,8 +1303,9 @@ the hooked rate of host UTC, then restores a snapshot with another rate, and
with one beyond Linux's 500 ppm limit, which the guest must hold at the limit
and report. The
`managed-lifecycle` scenario boots a guest whose init hands
the boot to the managed agent, and runs the ignored `nvx-rs` test
`tests/managed_lifecycle.rs` with Cargo, which starts OpenVMM with the
the boot to the managed agent, and runs the ignored `nvx-rs` unit test of the
host's control session, in `src/host/session/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
Expand Down
60 changes: 33 additions & 27 deletions nvx-rs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ changes only when the module's purpose does.

| Module | Purpose |
| --- | --- |
| [`nvx::protocol`](#nvxprotocol) | The codec of the control console's `NVXS` records, `NVXC` frames, and payloads, which the host, the guest agent, and the fake OpenVMM share |
| [`nvx::protocol`](#nvxprotocol) | The codec of the control console's `NVXS` records and the payloads that the host, the guest agent, and the fake OpenVMM share |
| [`nvx::protocol::cmdline`](#nvxprotocolcmdline) | The kernel command line as Linux and the guest's init read it, with the virtio-mmio devices and the guest's DNS server that it names |
| [`nvx::protocol::export`](#nvxprotocolexport) | The boot tokens of the host export, the virtio-fs device from which a guest maps host paths, and the guest's parser of them |
| [`nvx::protocol::nvxs`](#nvxprotocolnvxs) | The NVXS session, independent of any application protocol: its records and the state machines of its host and guest roles |
Expand Down Expand Up @@ -131,7 +131,7 @@ changes only when the module's purpose does.
| [`nvx::host::process`](#nvxhostprocess) | Verified references to OpenVMM processes, through which callers wait for them and end them |
| [`nvx::host::supervisor`](#nvxhostsupervisor) | The transitional public path of the low-level spawn of a VMM, which code that stays uses until SL6.3 (#1122) |
| [`nvx::host::seal`](#nvxhostseal) | `FileSeal`: what the host reports about an open file from its metadata alone, without reading it |
| [`nvx::host::session`, `platform`, `report`](#nvxhostsession-platform-report) | The authenticated control session, Linux and Windows primitives, and OpenVMM's outcome report |
| [`nvx::host::platform`, `report`](#nvxhostplatform-report) | Linux and Windows primitives, and OpenVMM's outcome report |
| [`nvx::host::sandbox`](#nvxhostsandbox) | The launch profile of `nvx-rs sandbox`: its plans, live shares, option checks, bindings, and prepared launches |
| [`nvx::guest`](#nvxguest) | The programs that run in Linux guests; see [Guest binaries](#guest-binaries) |
| [`nvx::guest::mappings`](#nvxguestmappings) | `Mapping` and `MappingTable`: host mappings, and the account of a host's mapping table, for any guest init or agent |
Expand Down Expand Up @@ -163,10 +163,12 @@ fields.

### `nvx::protocol`

The codec of the control console: `NVXS` outer records, `NVXC` application
The codec of the control console: `NVXS` outer records, the `MAPS` payloads of
the host mapping table, and the `nvx_maps=` and `nvx_workload_account=create`
tokens. NVX's own control protocol, `NVXC`, is private to the crate, gated by
the features of its users, `cli`, `guest` and `testing`: its application
frames, the `EXEC` payload that the host encodes and the guest agent decodes,
the `MAPS` payloads of the host mapping table, `GuestFeatures`, and the
`nvx_maps=` and `nvx_workload_account=create` tokens.
and the control features that a guest image advertises.

The [conformance vectors](tests/vectors/README.md) of version 1,
`tests/vectors/nvxc-v1.txt`, and OpenVMM's vectors and cases of the `NVXS`
Expand Down Expand Up @@ -1054,7 +1056,8 @@ and refuses unverifiable peers rather than falling back to a numeric PID.
An indeterminate process check remains an error, never exit proof.

`HostConnection`: the host's role of the NVXS session over a platform transport,
on which `nvx::host::session` and other host applications run their protocols.
on which NVX's own control session and other host applications run their
protocols.
It attaches with the launch capability, waiting while the broker asks it to,
sends application bytes in as many DATA records as they take, and returns each
DATA payload from the guest, with deadlines; a receive that times out keeps a
Expand All @@ -1069,8 +1072,8 @@ remain available as sources.
`Transport` and `TransportHandle` re-export the existing platform types, with
one definition beneath the OS adapters. Timed reads and writes, native-handle
duplication and `unread` are unchanged: Linux reports Unix `SIOCOUTQ` charges,
and Windows reports `None`. The old `host::session::connect` remains a
compatibility wrapper.
and Windows reports `None`. The old `session::connect`, private to the crate
like the session, remains a compatibility wrapper for the CLI.

### `nvx::host::process`

Expand Down Expand Up @@ -1178,11 +1181,12 @@ file ID, the kind, the length, the modification time, and on Linux the change
time, with a versioned serde form. A seal detects accidental change, not
tampering; see [Distro bindings](#distro-bindings).

### `nvx::host::session`, `platform`, `report`
### `nvx::host::platform`, `report`

The authenticated control session, which carries NVX's control protocol, `NVXC`,
one frame per DATA record of a `HostConnection`; Linux and Windows primitives;
and OpenVMM's outcome report.
Linux and Windows primitives, and OpenVMM's outcome report. The authenticated
control session, which carries NVX's own control protocol, `NVXC`, one frame
per DATA record of a `HostConnection`, is private to the crate: the CLI and its
restore driver use it, with the `cli` feature.

`report::read` returns `Ok(None)` for a missing report, and an `Io` error for an
unreadable or malformed report, retaining the underlying error. It keeps today's
Expand Down Expand Up @@ -2640,9 +2644,9 @@ guest agents of NVX advertise bits 0, 4, and 6 in sandbox mode.
treats as one that has not appeared yet, and, on Windows, starts OpenVMM
without a console window, as `nvx::host::vm::spawn` starts it.
- `start` stops waiting for the control endpoint once the OpenVMM that it
launched exits, as `nvx::host::session::connect` does, and fails at once
with `exited`, where `nvx.py` waited until `--timeout` passed before it
reported the exit.
launched exits, as `nvx::host::transport::connect_verified` does, and fails
at once with `exited`, where `nvx.py` waited until `--timeout` passed before
it reported the exit.
- `exec` refuses more than 1 MiB of workload output, which the guest agent
never forwards.
- `provision`, and `start` again, refuse a share whose resolved host path
Expand Down Expand Up @@ -3105,10 +3109,11 @@ simulated workload, transport, and sink on a clock of their own, and, on Linux,
the tests of `nvx::guest::exec::binding` drive real programs through them, two
at once in one loop, one of them with a stalled sink; run as root, one of them
also settles a real cgroup.
On Linux, a loopback test drives
the host `ControlSession` through a broker shim into the real managed agent's
session, dispatch, and execution engine, and `nvx.py` also lints and tests the
guest binaries, and runs their integration tests against a build of them:
On Linux, with the `cli` feature, a loopback test drives
the host's private `ControlSession` through a broker shim into the real managed
agent's session, dispatch, and execution engine, and `nvx.py` also lints and
tests the guest binaries, and runs their integration tests against a build of
them:

```bash
python3 ../scripts/nvx.py check-guest-binaries
Expand Down Expand Up @@ -3202,14 +3207,15 @@ the submodule out, and so does an OpenVMM pin promotion; see
profiles from which [`run`](#run) guides a failed cold boot, with the profiles
that the submodule pins, and runs where that one does.

`tests/managed_lifecycle.rs` is an ignored test of the managed lifecycle of a
guest whose init hands the boot to the managed agent, on a real hypervisor:
authenticated sessions and reconnects, request-scoped working directories and
environments, the workload identity, timeouts, refused working directories,
and stop, which `nvx::host::session` drives. `nvx.py test-microvm --scenario
managed-lifecycle` builds OpenVMM's command line for its guest and backend,
runs the test with Cargo, and checks the outcome report and the guest console
that it leaves:
`src/host/session/tests/managed_lifecycle.rs` is an ignored unit test of the
host's private control session, which the `cli` feature builds: the managed
lifecycle of a guest whose init hands the boot to the managed agent, on a real
hypervisor: authenticated sessions and reconnects, request-scoped working
directories and environments, the workload identity, timeouts, refused working
directories, and stop, which the session drives. `nvx.py test-microvm
--scenario managed-lifecycle` builds OpenVMM's command line for its guest and
backend, runs the test with Cargo, and checks the outcome report and the guest
console that it leaves:

```bash
python3 ../scripts/nvx.py test-microvm --backend kvm --scenario managed-lifecycle
Expand Down
9 changes: 2 additions & 7 deletions nvx-rs/examples/external-launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use nvx::host::network::{Access, NetworkPolicy};
use nvx::host::platform::Transport;
use nvx::host::runtime::{ArtifactIdentity, LaunchOptions, Runtime, RuntimeIdentity};
use nvx::host::supervisor::{self, Inherited};
use nvx::host::{artifacts, report, session, snapshot, vm};
use nvx::host::{artifacts, report, snapshot, transport, vm};
use nvx::protocol::root::RootImage;

/// One byte past OpenVMM's 25-byte restore-ready event, so that a longer event fails to parse.
Expand Down Expand Up @@ -180,12 +180,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let console = outputs.console.as_deref().ok_or_else(|| {
io::Error::new(io::ErrorKind::InvalidInput, "no prepared boot console")
})?;
let mut console = session::connect(
console,
process.reference().pid,
process.reference().start_time,
deadline,
)?;
let mut console = transport::connect_verified(console, process.reference(), deadline)?;
read_until(console.as_mut(), b"NVX-GUEST-BOOT-OK:", deadline)?;
console.write_all(
b"printf 'NVX-EXTERNAL-LAUNCH-OK\\n'; /sbin/nvx-exit 0\n",
Expand Down
Loading
Loading