-
Notifications
You must be signed in to change notification settings - Fork 222
guide: document standalone OpenVMM releases #3988
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Ben Hillis (benhillis)
wants to merge
27
commits into
microsoft:main
from
benhillis:user/benhill/openvmm-tag-release-guide
+731
−19
Closed
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
5c88319
guide: define standalone OpenVMM releases
f4377e6
guide: document tag-derived OpenVMM releases
029e1b9
guide: clarify dirty tagged versions
0853143
guide: remove duplicate release introduction
5571d4c
guide: align with minimal release identity
9d75ae3
guide: distinguish planned release artifacts
ed4d516
guide: clarify OpenVMM release identity
0eadea0
guide: align the OpenHCL release link
e6a725a
guide: rewrap release prose
ca56149
guide: mark tag-derived version output as under development
e25988f
guide: clarify SHA256SUMS is a separate checksum file
7ad261d
guide: add source build step and security reporting to OpenVMM releas…
b4cf3a3
guide: frame OpenVMM patch releases and servicing branches as post-1.0
c848a7e
guide: document packaging OpenVMM for a Linux distribution
e8b9341
guide: drop cloud-hypervisor reference from packaging example
a87569f
guide: address review feedback on OpenVMM release docs
benhillis 34022d5
guide: reconcile release policy on security fixes and version resources
0bcc33a
guide: separate the OpenHCL warning admonition from the next paragraph
9049fd1
docs: tighten OpenVMM release model page flow
6172810
docs: phase OpenVMM releases source-first
a4c0397
docs: correct packaging details from a measured distribution build
8fd8e56
guide: note that CI covers the distribution build configuration
0da88f2
guide: correct the release runbook for a draft, two-job workflow
2050c45
guide: a rerun leaves an existing release alone
ba680bb
guide: a rerun fails when the tag already has a release
f08f8fa
guide: tell packagers how to verify the source release
e01ff36
docs: name why the two release archives are identical
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,228 @@ | ||
| # Packaging OpenVMM for a Linux Distribution | ||
|
|
||
| This page describes building the `openvmm` binary as a Linux distribution | ||
| package, from public source only. It is aimed at downstream packagers (for | ||
| example, an RPM or `.deb` maintainer) who build from the official OpenVMM source | ||
| release rather than from the in-repo `cargo xflowey` provisioning flow. | ||
|
|
||
| The examples target [Azure Linux](https://github.com/microsoft/azurelinux), but | ||
| the requirements generalize to any glibc distribution. | ||
|
|
||
| ```admonish note title="See also" | ||
| [OpenVMM Release Model and Support](./openvmm_release.md) describes the source | ||
| release archive and version identity that a distribution package builds from. | ||
| [Crypto Backends](./crypto_backends.md) explains the backend selection that | ||
| determines the native dependencies below. | ||
| ``` | ||
|
|
||
| ## What a distribution package builds | ||
|
|
||
| A distribution package builds the host `x86_64-unknown-linux-gnu` target: | ||
| dynamically linked against the system glibc and OpenSSL. Building from the | ||
| official source release is the supported way to consume OpenVMM today, and this | ||
| is the configuration to use. It differs from the statically linked `musl` | ||
| binaries that the repository's own provisioning tooling produces, which is what | ||
| the project will ship if and when it publishes prebuilt Linux archives. | ||
|
|
||
| The gnu build deliberately avoids the repository's `.packages/` provisioning | ||
| (`cargo xflowey restore-packages`), which fetches prebuilt native libraries a | ||
| distribution build cannot consume. A packager instead supplies every native | ||
| dependency from distribution packages and overrides the few build settings that | ||
| otherwise point into `.packages/`. | ||
|
|
||
| ```admonish tip title="Only two overrides are required" | ||
| Building the `openvmm` binary for the gnu target needs no source patches. It | ||
| needs the distribution build packages below, plus two environment overrides | ||
| (`PROTOC` and `OPENSSL_NO_VENDOR`). | ||
| ``` | ||
|
|
||
| OpenVMM's CI builds this configuration on every change and checks that the | ||
| resulting binary links the distribution's OpenSSL, so a change that only works | ||
| against `.packages/` is caught upstream rather than by a packager. The CI job is | ||
| the executable form of this page: if the two descriptions ever disagree, the job | ||
| is the one that is right. | ||
|
|
||
| ## Obtaining and verifying the source release | ||
|
|
||
| Each OpenVMM release publishes `openvmm-<VERSION>-source.tar.gz` together with a | ||
| `SHA256SUMS` file covering it. Download both, and verify the archive before | ||
| building from it: | ||
|
|
||
| ```bash | ||
| sha256sum -c SHA256SUMS | ||
| ``` | ||
|
|
||
| Every published asset also carries a GitHub build provenance attestation, which | ||
| binds the artifact to the repository, workflow, and commit that produced it. | ||
| Unlike the checksum file, it cannot be regenerated by whoever replaced the | ||
| archive, so verify it as well: | ||
|
|
||
| ```bash | ||
| gh attestation verify openvmm-<VERSION>-source.tar.gz --repo microsoft/openvmm | ||
| ``` | ||
|
|
||
| The archive is assembled reproducibly: the same release tag always produces | ||
| byte-identical bytes, so an independently assembled archive can be compared | ||
| against the published checksum. | ||
|
|
||
| ```admonish warning title="Use the published archive, not GitHub's" | ||
| GitHub generates its own "Source code (tar.gz)" link on every release page. | ||
| That archive is **not** the OpenVMM source release: it omits | ||
| `.openvmm-release.json`, so a build from it cannot recover its release identity, | ||
| and it is not covered by `SHA256SUMS` or the attestation. | ||
| ``` | ||
|
|
||
| ## Toolchain | ||
|
|
||
| The workspace declares a minimum supported Rust version (MSRV) in the root | ||
| `Cargo.toml` (`rust-version`). Building requires a Rust toolchain at least that | ||
| new. The MSRV advances over time, so confirm the current value in the source | ||
| you are packaging and require at least that Rust version in the package. | ||
|
|
||
| ```admonish warning title="Distribution Rust may lag the MSRV" | ||
| If the distribution's packaged `rust` is older than the workspace MSRV, `cargo` | ||
| fails during resolution — for example: | ||
|
|
||
| error: package `x86emu@0.0.0` cannot be built because it requires | ||
| rustc 1.95 or newer, while the currently active rustc version is 1.90.0 | ||
|
|
||
| Target a distribution whose packaged Rust meets the MSRV, or arrange a newer | ||
| toolchain in the package build environment. | ||
| ``` | ||
|
|
||
| ## Native build dependencies | ||
|
|
||
| The `openvmm` gnu binary compiles a small amount of C through build scripts and | ||
| shells out to `protoc`. The native build dependencies are: | ||
|
|
||
| - a C toolchain (`gcc`, the glibc development headers, and `binutils`); | ||
| - the Linux UAPI headers (`kernel-headers`), for the bundled SQLite compiled by | ||
| `libsqlite3-sys`; | ||
| - the OpenSSL development headers, for `openssl-sys`; | ||
| - a Protocol Buffers compiler providing `protoc`, for `prost` / `pbjson`. | ||
|
|
||
| ```admonish note title="SymCrypt is not needed for the gnu build" | ||
| The `crypto` crate selects the OpenSSL backend on `target_os = "linux"` for | ||
| non-`musl` targets, and SymCrypt only on `musl`. The `openvmm` gnu binary | ||
| therefore does not depend on SymCrypt, `ms-tpm-20-ref`, or `mimalloc` — none of | ||
| them appear in `cargo tree -p openvmm` for the host target. Only `musl` | ||
| (OpenHCL) builds link SymCrypt. See [Crypto Backends](./crypto_backends.md). | ||
| ``` | ||
|
|
||
| ### Azure Linux package names | ||
|
|
||
| Package names differ between Azure Linux versions: | ||
|
|
||
| | Need | Azure Linux 3.0 | Azure Linux 4.0 | | ||
| | --- | --- | --- | | ||
| | C toolchain | `gcc`, `glibc-devel`, `binutils` | same | | ||
| | Linux UAPI headers | `kernel-headers` | `kernel-headers` | | ||
| | OpenSSL headers | `openssl-devel` | `openssl-devel` | | ||
| | `protoc` | `protobuf` | `protobuf-compiler`, `protobuf-devel` | | ||
|
|
||
| Azure Linux 3.0 ships a newer `protoc` that embeds the well-known types, so its | ||
| `protobuf` package is sufficient. Azure Linux 4.0 ships an older `protoc`, so | ||
| `protobuf-devel` is also required to supply `google/protobuf/*.proto` on disk. | ||
|
|
||
| ## Environment overrides | ||
|
|
||
| The in-repo `.cargo/config.toml` sets `PROTOC` to a path under `.packages/` | ||
| unconditionally. A distribution build must point it at the system `protoc`. | ||
| Setting `OPENSSL_NO_VENDOR` makes `openssl-sys` link the system OpenSSL rather | ||
| than building a vendored copy: | ||
|
|
||
| ```bash | ||
| export PROTOC="$(command -v protoc)" | ||
| export OPENSSL_NO_VENDOR=1 | ||
| ``` | ||
|
|
||
| ## Offline vendored build | ||
|
|
||
| A package build should be reproducible and offline. The OpenVMM source release | ||
| is a source archive only: it does not carry the crate dependency tree, so the | ||
| packager produces the vendored tarball and covers it with the distribution's | ||
| own integrity metadata alongside the source archive. | ||
|
|
||
| Vendor all dependencies — including the Git dependencies and the | ||
| `[patch.crates-io]` pins — into a tarball alongside the source archive: | ||
|
|
||
| ```bash | ||
| cargo vendor vendor/ > vendor-config.toml | ||
| ``` | ||
|
|
||
| `cargo vendor` captures the Git dependencies and their Git submodule C sources | ||
| (for example the `ms-tpm-20-ref` and SymCrypt submodules), so the vendored tree | ||
| is self-contained. Append the generated `[source]` redirection to | ||
| `.cargo/config.toml`, then build without network access: | ||
|
|
||
| ```bash | ||
| cargo build --release -p openvmm --offline | ||
| ``` | ||
|
|
||
| ```admonish note title="Vendoring covers the whole workspace" | ||
| `cargo vendor` has no per-package scoping: it vendors every dependency in the | ||
| workspace, not just the ones the `openvmm` binary needs. A measured run | ||
| vendored 498 crates where the binary requires 254, and a large share of the | ||
| resulting tree is Windows-only crates that a Linux package never compiles. | ||
| Expect the vendored tree to be substantially larger than the build requires. | ||
| ``` | ||
|
|
||
| ## Runtime dependencies | ||
|
|
||
| The resulting binary links a small, stable set of shared libraries. Confirm the | ||
| exact set for your build with `ldd`: | ||
|
|
||
| - glibc (`libc`, `libm`); | ||
| - OpenSSL (`libssl`, `libcrypto`); | ||
| - `libgcc_s`. | ||
|
|
||
| Depending on the OpenSSL build, `libz` may also appear transitively; a measured | ||
| Ubuntu build did not link it. The bundled SQLite is linked statically and adds | ||
| no runtime dependency. RPM automatic dependency generation derives these from | ||
| the ELF `NEEDED` entries, so confirm the set for your own build rather than | ||
| copying a fixed list. | ||
|
|
||
| ## Worked example: Azure Linux RPM | ||
|
|
||
| This uses a common Rust-packaging pattern: a source tarball, a `cargo vendor` | ||
| tarball, and an offline build. The distribution package version is independent | ||
| from the OpenVMM product version (see | ||
| [Independent version spaces](./openvmm_release.md#independent-version-spaces)). | ||
|
|
||
| Use `openvmm-<VERSION>-source.tar.gz` from the release as `Source0` so the build | ||
| retains its release identity through `.openvmm-release.json` — see | ||
| [Obtaining and verifying the source release](#obtaining-and-verifying-the-source-release). | ||
|
|
||
| Declare the build and runtime dependencies. Require a Rust toolchain at least as | ||
| new as the workspace MSRV — read the current value from `rust-version` in the | ||
| source you are packaging rather than copying the one below: | ||
|
|
||
| ```spec | ||
| BuildRequires: rust >= <MSRV> | ||
| BuildRequires: cargo >= <MSRV> | ||
| BuildRequires: gcc glibc-devel binutils kernel-headers | ||
| BuildRequires: openssl-devel | ||
| BuildRequires: protobuf-compiler protobuf-devel | ||
|
|
||
| Requires: glibc | ||
| Requires: openssl-libs | ||
| ``` | ||
|
|
||
| Build offline and install the single binary: | ||
|
|
||
| ```spec | ||
| %build | ||
| export PROTOC="$(command -v protoc)" | ||
| export OPENSSL_NO_VENDOR=1 | ||
| cargo build --release --offline -p openvmm \ | ||
| --target x86_64-unknown-linux-gnu | ||
|
|
||
| %install | ||
| install -D -m0755 \ | ||
| target/x86_64-unknown-linux-gnu/release/openvmm \ | ||
| %{buildroot}%{_bindir}/openvmm | ||
| ``` | ||
|
|
||
| On Azure Linux 3.0, replace `protobuf-compiler protobuf-devel` with `protobuf`, | ||
| and confirm the packaged `rust` meets the workspace MSRV before adopting a base | ||
| version. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.