Repository navigation
Conversation
fwiesel
force-pushed
the
sysext-virt
branch
19 times, most recently
from
November 3, 2026 13:01
2cf3634 to
00a1df9
Compare
fwiesel
force-pushed
the
sysext-virt
branch
4 times, most recently
from
November 4, 2026 08:55
5965725 to
5556255
Compare
Node-local packages belong to the node owner, not to the shared boot root: the engine builds every SCI extension as an EROFS-root GPT image, standalone on the pinned published base, so a package change rebuilds exactly its own extension and the base image stops churning for every host. Seven extensions ship: base identities, compute, network, storage, libvirt and the two hypervisor flavours. Builds are byte-reproducible, so a produced raw traces to its inputs: version-keyed timestamps, per-image seeds and three conscious-bump pins (apt suite, toolchain manifest, resolved configuration). The tools tree is bootstrapped from the pinned suite and accepted only when its manifest digest matches the committed pin. The numeric name prefixes state the merge order systemd-sysext applies, the virt drivers exclude libvirt-owned paths through RemoveFiles= lists because the overlay merge provides them at runtime, and every path has exactly one owning extension. The qemu extension carries the VNC port policy that the legacy image kept in /etc/libvirt/qemu.conf, as a template with a tmpfiles C rule, because /etc is outside the merge. `mkosi/build.sh --bootstrap` prepares sandbox, tools tree and base without building images, for a caller that only needs the toolchain. Signed-off-by: Fabian Wiesel <fabian.wiesel@sap.com>
A delivery is only safe to apply when its raws are intact and were built for the host's base version. The step verifies SHA256SUMS before anything lands, refuses a base-version mismatch through the manifest's TARGET_BASE gate, reconciles idempotently and records pending activation for replay. It runs as a privileged pod with the host root mounted. Image mode takes the staging the image carries. Fetch mode materializes the same staging from a published build: it verifies the detached inventory signature, downloads only the files whose staged hash differs, proves the complete set and prunes files the inventory no longer lists. The manifest lists every deployable, and the step never deploys a raw it does not list. The host tests pin the build, staging, fetch and activation contracts. Signed-off-by: Fabian Wiesel <fabian.wiesel@sap.com>
An unverified layer silently widens the boot root's trust boundary: an unsigned or tampered extension could change what a host runs. Enable the signed build: every raw gets a dm-verity hash tree and a signature partition, the committed certificate is the anchor a merging host checks, and the private key never enters the repository. A three-scenario VM boot test closes the loop: the signed set must boot the merged system, and tampered or unsigned layers must be refused. The tamper scenario corrupts a verity-covered data block, so the guest must fail with the kernel's dm-verity corruption verdict and not with a format-probe error. An artifact is trusted only after the merged system has booted, so the boot evidence is part of the delivery proof. Signed-off-by: Fabian Wiesel <fabian.wiesel@sap.com>
Local-only proof dies with the machine that ran it. The workflow runs the quick suite on every change and, on push, builds the extensions, runs the full suite with the VM boot test and publishes one test artifact: the raws as plain-file staging, including the delivery step and the run certificate. The essential workflow boundaries are pinned structurally on the parsed workflows: the quick tier and its PR gate, producer ordering from base ensure over the signed build to the staged raws upload, the publish gate on the signing secret, and the inventory being regenerated before it is signed while the delivery vehicle is dropped. The integration job consumes a prior run's artifact like a test consumer would: it restores the run certificate, bootstraps the pinned toolchain, builds the shared Ubuntu guest and test SSH identity, exports only the manifest-selected raws, and boots two Garden Linux hypervisors, which mount those raws from a virtiofs share read-only. One guest action serves the build action and the sysext branch, so the two flows cannot drift. The boot activates the seven extensions, and the job then runs the existing real QEMU and Cloud-Hypervisor live migration tests against the produced raws. The hosted runners need explicit accommodations: mkosi's unprivileged sandbox needs the AppArmor user-namespace restriction lifted, qemu-system-x86 provides the virtual qemu-kvm package, virtiofsd provides the virtiofs share, /dev/kvm must be accessible for the VM boot test, the finished qemu scenario's VM is stopped before the cloud-hypervisor stage because its nested I/O starves the staging copy, and the debug collection includes the HV serial consoles. Signed-off-by: Fabian Wiesel <fabian.wiesel@sap.com>
Write down the single-owner layout, the delivery contract and the operating procedures while they are current, so the design doc is the single source of truth. docs/sysext-virt.md states the design as it is: every invariant, gotcha and open item in Simplified Technical English, no change log, no facts restated from tracked files. delivery/README.md is the operational contract of the delivery step and marks the product boundary: the step is the boot-test vehicle, the signed release is the product. Signed-off-by: Fabian Wiesel <fabian.wiesel@sap.com>
This branch has not been deployed
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
SCI preparation: one build, one guest, one transport
Status: draft. Local verification accepted; CI pending. Not a readiness claim.
Shape
Five logical commits; both documentation files arrive only in the last one.
The preparation path collapses two parallel stories — a build/test guest with
mode switches plus sysext-specific setup, and a container-based delivery path
— into one:
sysext branch. The build action takes only
image_tag; itsmode,sysext_key, and validation inputs are gone (eight mode guards removed).is no Docker rebuild/export, SCP tar stream, or
ctrdelivery step. Thedelivery/fetch/signing behavior stays inside its existing tests and product
boundary.
on:triggers are unchanged.Trade-off
Not the absolute minimum. The user accepted the single-source growth: one
added file (
.github/actions/test/integration/guest/action.yml) and 77 netlines against the previous revision.
15e6ae8)1824943)Tests
120 collected: 108 quick, 11 build, 1 VM (original: 152). No new test function
and no parallel VM suite. One extra partial-set case checks that a dropped
extension fails closed before pool, network, and SSH setup. The existing
tamper VM test now requires a real dm-verity failure on valid filesystem data
rather than a format rejection.
Evidence
1824943(treedc8a8d32): 120 passed(108 quick, 11 build, 1 VM), exit 0; seven-image reproducibility; three
fresh guest scenarios (signed, tamper, policy).
tree comparison (content/type/links/modes; ownership on selected paths
only).
15e6ae8producer ran 119 passed(run),
but the GitHub scheduler blocked the dependent jobs; it cannot prove
1824943.Limits
protection. This serves trusted test staging, not a hostile guest or
production.
pre-marker window is unchanged.
re-pin remain deferred, with no owner assigned
(#402).
Pending
VERIFY-FINAL: accepted local verification on1824943(treedc8a8d32).VERIFY-CI: pending for the automatic push run(run).
gardenlinux/gardenlinux-sci#401
remains draft at
1824943; the branch is pushed.