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
47 changes: 47 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Changelog

This file lists NVX's breaking releases: those of the
[`nvx` crate](nvx-rs/README.md), with the guest artifacts of the same commit.
CI publishes the crate's other versions every night, as
[crates.io releases](doc/ci.md#cratesio-releases) describes.

## 0.2.0-alpha.1

`nvx` becomes a library of mechanisms and value types for microVMs, on which
NVX's own programs and other users build
([microsoft/nvx#1076](https://github.com/microsoft/nvx/issues/1076)). The
release is not backward compatible: users that need `0.1.0-alpha.7` stay on it.
[Migrating from alpha.7](doc/migrate-from-alpha.7.md) maps each removed or
changed item to its replacement, or to what its caller now does.

### Breaking changes

- **No durable state.** The sandbox and template stores, the instance layer and
the supervisor are gone from `nvx::host`. A caller keeps its own state from the
values that `nvx::host::vm` returns.
- **One launch.** The old configurations and launch paths, such as
`LaunchSpec`, `SandboxPlan` and `ClonePlan`, are gone: `nvx::host::vm::create`
takes a `VmConfig` and, for a restore, a `Snapshot`.
- **No exec.** The exec engine, `nvx::exec`, and the guest's process modules,
`nvx::guest::{exec, spawn, process, cgroup, entry}`, are gone. A guest's init
runs its executions itself.
- **The guest's space is private.** nvx-init's space, `nvx::guest::{root, gpt}`
and the mapper of `nvx::guest::mappings`, is private to `nvx`.
`resolve_guest_path` is gone, and `ExportPlan` holds paths only.
- **NVXC is private.** NVX's own protocol is private to `nvx`, and speaks only
version 2: version 1 and its `FEATURES` request are gone.
- **Errors.** `ErrorCode` and `Error`'s constructors are private: callers tell
errors apart by their `ErrorKind`, which gains `RuntimeMismatch` and
`StillRunning`.
- **NVX's programs are private.** Each binary calls a hidden `main`, which is all
that the programs add to the public API. Artifact discovery (`nvx::Artifacts`),
image staging, the control session and the platform layer are private to them.
- **Features.** The `bundled` feature is gone, with its build script.
- **Fresh state.** The CLI reads a sandbox's configuration only in format 10,
which requires `export_pins`: deprovision each sandbox that an earlier build
provisioned, and provision it again. Nothing reads alpha.7's records, keys or
snapshots, so a deploy captures its snapshots again.
- **The guest's `/init`** fails closed on OpenVMM's workload identity: a command
line with `nvx_workload_uid=` or `nvx_workload_gid=` boots only when
`nvx_identity=` names the same UID and GID.
- **The guest kernel** no longer sets `CONFIG_MAGIC_SYSRQ`.
6 changes: 3 additions & 3 deletions doc/acceptance-case-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ their own. The tests that a step runs have rows of their own where they concern
| `.github/actions/check-nvx-rs` | Test | kept | Runs `nvx-rs/tests/security_checklist.rs` too |
| `.github/actions/check-nvx-rs` | Check artifact bundling | retired | The `bundled` feature, which staged a release at build time, leaves NVX with its build script and `artifacts.json` (SL6.6a, #1122) |
| `.github/actions/check-nvx-rs` | Build documentation | kept | |
| `.github/actions/check-nvx-rs` | Check the public API | kept | |
| `.github/actions/check-nvx-rs` | Check the public API | kept | Since SL8.1, it also fails unless the API's hidden items are one `main` per binary, the entry point that the binary calls, and the modules that hold it |
| `.github/actions/check-nvx-rs` | Check the minimum supported Rust version | kept | |
| `.github/actions/check-nvx-rs` | Check the macOS build | kept | |
| `.github/actions/check-nvx-rs` | Lint and test the guest binaries | kept | Builds `nvx` with `guest` alone, warnings denied, `nvx-rs/examples/guest-workflows.rs` among its targets |
Expand All @@ -441,8 +441,8 @@ their own. The tests that a step runs have rows of their own where they concern
| `.github/workflows/ci.yml` | openvmm-ci: Check OpenVMM's CI of the pinned revision | kept | |
| `.github/workflows/ci.yml` | performance-gate: Gate on performance regressions | kept | |
| `.github/workflows/ci.yml` | required-status-check: Verify required jobs | kept | SL5.2 removes the adapter's job from what it requires |
| `.github/workflows/ci.yml` | crate-package: Package, check, and build the nvx crate | kept | Since SL6.6a, the package holds no build script or `artifacts.json`, and builds once, with every feature |
| `.github/workflows/ci.yml` | crate-release: Check the nvx package | kept | Since SL6.6a, the package holds no build script or `artifacts.json` |
| `.github/workflows/ci.yml` | crate-package: Package, check, and build the nvx crate | kept | Since SL6.6a, the package holds no build script or `artifacts.json`, and builds once, with every feature. Since SL8.1, it holds the public API's snapshots too, and `cargo install` then builds `nvx-ingress` from its files with the `guest` feature and profile, outside the checkout, and runs it |
| `.github/workflows/ci.yml` | crate-release: Check the nvx package | kept | Since SL6.6a, the package holds no build script or `artifacts.json`. Since SL8.1, it holds the public API's snapshots |
| `.github/workflows/ci.yml` | nvx-microvm-adapter-whp: the runtime adapter's job on WHP | retired | The adapter's scenarios, whose fates are above |
| `.github/workflows/run-nvx-microvm-tests.yml` | Run NVX microVM tests on Linux and on Windows | kept | The default suite's scenarios, by shard and on the debug kernel |
| `.github/workflows/run-nvx-microvm-tests.yml` | Run public managed sandbox acceptance on Linux and on Windows | kept | Runs `sandbox-gpt-layer` and `vm-lifecycle` too, since SL5.1b: see [Cold boots](#cold-boots); and `snapshot-core` and `snapshot-tiers`, since SL5.1c: see [Snapshots](#snapshots) |
Expand Down
37 changes: 27 additions & 10 deletions doc/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -2143,12 +2143,14 @@ changes to the crate publishes nothing, and neither does a run of a commit
that the newest version's commit already contains, such as a rerun of an
older nightly run. Such a run skips `Publish nvx crate`.

The versions are pre-releases, such as `0.1.0-alpha.4`. A run takes the
number after the highest that crates.io has in the series that
`nvx-rs/Cargo.toml` declares, yanked versions included, since crates.io never
reuses a version, and at least the declared number, so the declared version is
the floor: a pull request changes it only to start another series, as
[The nvx crate](distribution.md#the-nvx-crate) describes. `Package nvx crate`
The versions are pre-releases of the `0.2.0-alpha` series, such as
`0.2.0-alpha.2`, since the breaking release `0.2.0-alpha.1` that the
[changelog](../CHANGELOG.md) records, and of the `0.1.0-alpha` series before
it. A run takes the number after the highest that crates.io has in the series
that `nvx-rs/Cargo.toml` declares, yanked versions included, since crates.io
never reuses a version, and at least the declared number, so the declared
version is the floor: a pull request changes it only to start another series,
as [The nvx crate](distribution.md#the-nvx-crate) describes. `Package nvx crate`
fails rather than publish a version that would sort below the newest one on
crates.io. When the number differs from the declared one, each job gives only
its own checkout the new version, in `nvx-rs/Cargo.toml` and in `nvx`'s entry
Expand All @@ -2163,10 +2165,20 @@ the commit's files in the version alone.
- Every file is the commit's byte for byte, which rules out CRLF line endings,
but for the rewritten version and the files that Cargo generates,
`Cargo.toml` and `.cargo_vcs_info.json`, which must hold no CR either.
- It holds the license and the readme.
- It holds the license, the readme, and the snapshots of the public API, with
which its users check the API that it promises. The `nvx-rs` job, which
`Required status check` requires, checked them against the API of the run's
commit, and that its hidden items are one `main` per binary (see
[Rust crates](#rust-crates)).
- Its files build with every feature, as a dependent's build does.

The job outputs the version and the package's SHA-256. Its build runs the
- From the job's work directory, `$RUNNER_TEMP/nvx-crate`, outside the
checkout, `cargo install --locked --path` installs `nvx-ingress` from its
files with `--no-default-features --features guest --profile guest`, as a
user installs the guest tools from the published crate. The installed
program's test mode then reads a snapshot of the socket tables that holds no
socket, and must print one scan that announces no listener.

The job outputs the version and the package's SHA-256. Its builds run the
build scripts and procedural macros of the crate's dependencies, so it holds
no right to publish. `Publish nvx crate` builds nothing: it decides again
whether crates.io needs the version, packs the crate again, and checks that
Expand Down Expand Up @@ -2370,7 +2382,12 @@ list follows re-exports, and leaves trait implementations out. The check,
which `python3 scripts/public_api.py` runs on any host, prints how the API
differs from a snapshot, and fails; a pull request that
changes the public API runs `python3 scripts/public_api.py --update` and
commits the snapshots, so that its diff shows the change. rustdoc's JSON is
commits the snapshots, so that its diff shows the change. The check also fails
unless the API's hidden items are the entry points of NVX's programs alone, one
per binary: the function `main` that the binary's code calls, outside its
comments and literals, such as `nvx::host::cli::main` for `nvx-rs`, which a
snapshot lists as hidden and none lists without hiding it, and the modules that
hold it. rustdoc's JSON is
unstable, so the script reads only the format version of the pinned release,
and a new pin may need a change to the script.

Expand Down
4 changes: 3 additions & 1 deletion doc/contribute.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ python3 scripts/public_api.py --update
```

The script builds rustdoc's JSON with the Rust release that
`rust-toolchain.toml` pins, and adds the musl and MSVC targets to it; see
`rust-toolchain.toml` pins, and adds the musl and MSVC targets to it. It also
fails unless the API's hidden items are one `main` per binary, the entry point
that the binary's source calls, and the modules that hold it; see
[Rust crates](ci.md#rust-crates).

## Test ownership
Expand Down
30 changes: 17 additions & 13 deletions doc/distribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,18 +152,21 @@ released first-parent ancestor.
## The nvx crate

[`nvx-rs/`](../nvx-rs/README.md) is also published on crates.io as the `nvx`
crate, a preview whose versions are pre-releases, `0.1.0-alpha.N`, which Cargo
selects only for a requirement that names a pre-release. The nightly CI run
publishes a new version from `dev` whenever the crate changed, with the next
number, as [crates.io releases](ci.md#cratesio-releases) describes, so a
change reaches crates.io within a day of its merge. The crate holds the files
that Git tracks in `nvx-rs/`, among them the package's license, `LICENSE`, its
README, and its lockfile, `Cargo.lock`; its features, profiles, and binaries
are those that [The nvx package](build.md#the-nvx-package) lists.
crate, a preview whose versions are pre-releases, which Cargo selects only for
a requirement that names a pre-release: `0.2.0-alpha.N` since the breaking
release that the [changelog](../CHANGELOG.md) records, and `0.1.0-alpha.N`
before it. The nightly CI run publishes a new version from `dev` whenever the
crate changed, with the next number, as
[crates.io releases](ci.md#cratesio-releases) describes, so a change reaches
crates.io within a day of its merge. The crate holds the files that Git tracks
in `nvx-rs/`, among them the package's license, `LICENSE`, its README, and its
lockfile, `Cargo.lock`; its features, profiles, and binaries are those that
[The nvx package](build.md#the-nvx-package) lists.

The version that `nvx-rs/Cargo.toml` declares is the lowest that CI
publishes. A pull request changes it to start another series, such as
`0.2.0-alpha.1`. Only `nvx`'s version changes in `nvx-rs/Cargo.lock`.
publishes. A pull request changes it to start another series, as the breaking
release started `0.2.0-alpha.1`. Only `nvx`'s version changes in
`nvx-rs/Cargo.lock`.

When CI cannot publish, as when the newest version on crates.io records no
commit that `dev` holds, a pull request declares the next version as above,
Expand Down Expand Up @@ -206,9 +209,10 @@ cargo install nvx --version VERSION --locked \
--target x86_64-unknown-linux-musl --bin nvx-ingress
```

- `--version VERSION` names a version that crates.io publishes,
`0.1.0-alpha.N`. Every version is a pre-release, which Cargo selects only for
a requirement that names one, so `cargo install nvx` without it finds none.
- `--version VERSION` names a version that crates.io publishes, such as
`0.2.0-alpha.1`, the breaking release, or a later `0.2.0-alpha.N`. Every
version is a pre-release, which Cargo selects only for a requirement that
names one, so `cargo install nvx` without it finds none.
- `--no-default-features --features guest` builds the guest programs without
the default `host` feature, which no guest program uses.
- `--profile guest` builds them with the crate's `guest` profile, where
Expand Down
2 changes: 1 addition & 1 deletion nvx-rs/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions nvx-rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "nvx"
version = "0.1.0-alpha.3"
version = "0.2.0-alpha.1"
edition = "2024"
rust-version = "1.89"
description = "NVX mechanics: the OpenVMM control protocol and the launch, policy lowering, and supervision of NVX microVMs"
description = "NVX's library of mechanisms and value types for OpenVMM microVMs: launch, snapshots and restores, verified connections, and the guest's side of capture and activation"
license = "MIT"
repository = "https://github.com/microsoft/nvx"
readme = "README.md"
Expand Down
8 changes: 4 additions & 4 deletions nvx-rs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ the public API against its snapshots, as [Testing](#testing) describes.
The package and the library are both called `nvx`; the package was called
`nvx-rs`, like the directory that holds it. The crate is published on crates.io
as a preview, whose API can change in any release: the nightly CI run publishes
`dev` as the next pre-release, such as `0.1.0-alpha.4`, whenever the crate
`dev` as the next pre-release, such as `0.2.0-alpha.2`, whenever the crate
changed; see [crates.io releases](../doc/ci.md#cratesio-releases). Cargo
resolves a requirement such as `nvx = "0.1.0-alpha.4"` to the newest
pre-release of `0.1.0`, so require an exact version, such as
`nvx = "=0.1.0-alpha.4"`, to keep one. It has a `Cargo.lock` of its own; a
resolves a requirement such as `nvx = "0.2.0-alpha.1"` to the newest
pre-release of `0.2.0`, so require an exact version, such as
`nvx = "=0.2.0-alpha.1"`, to keep one. It has a `Cargo.lock` of its own; a
workspace at the repository root would interact with the nested `openvmm/`
workspace.

Expand Down
Loading
Loading