mirror of
https://github.com/vhaudiquet/ecrou.git
synced 2026-11-12 22:22:44 +00:00
All consumers live in packaging already: the formula codesigns at install, and the CI and release workflows codesign the built binary. The macOS dir held nothing else.
209 lines
7.1 KiB
YAML
209 lines
7.1 KiB
YAML
name: ci
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: ci-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
|
|
jobs:
|
|
test:
|
|
name: fmt, clippy, test
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
components: clippy, rustfmt
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
# Same order as the pre-commit list in AGENTS.md.
|
|
- name: cargo fmt
|
|
run: cargo fmt --all -- --check
|
|
|
|
- name: cargo clippy
|
|
run: cargo clippy --all-targets -- -D warnings
|
|
|
|
- name: cargo test
|
|
run: cargo test
|
|
|
|
macos:
|
|
name: macos — fmt, clippy, test, boot
|
|
runs-on: macos-26
|
|
timeout-minutes: 45
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
components: clippy, rustfmt
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
# The engine is dlopen'd from the brew kegs at runtime; e2fsprogs
|
|
# supplies mke2fs and libarchive its tar path.
|
|
- name: Install the engine and the image tooling
|
|
run: brew install libkrun/homebrew-krun/libkrun e2fsprogs libarchive
|
|
|
|
- name: cargo fmt
|
|
run: cargo fmt --all -- --check
|
|
|
|
- name: cargo clippy
|
|
run: cargo clippy --all-targets -- -D warnings
|
|
|
|
- name: cargo test
|
|
run: cargo test
|
|
|
|
- name: Build the CLI
|
|
run: cargo build --release -p ecrou-cli
|
|
|
|
# HVF grants VM creation only to binaries carrying the hypervisor
|
|
# entitlement on current macOS; packaging signs the same way.
|
|
- name: Sign the binary with the hypervisor entitlement
|
|
run: codesign --force --sign - --entitlements packaging/homebrew/ecrou.entitlements target/release/ecrou
|
|
|
|
- name: Probe
|
|
run: ./target/release/ecrou probe
|
|
|
|
- name: Boot alpine
|
|
run: |
|
|
set -euo pipefail
|
|
guest="$(./target/release/ecrou run --quiet alpine -- uname -r | tail -n 1)"
|
|
echo "guest kernel: $guest"
|
|
test -n "$guest"
|
|
|
|
t6:
|
|
name: T6 strace audit
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
|
|
- name: Install strace and the image tooling
|
|
run: |
|
|
sudo apt-get update -qq
|
|
# mke2fs populates from a tarball through a runtime dlopen of
|
|
# libarchive; the runner has e2fsprogs but not the lib.
|
|
sudo apt-get install -y -qq strace libarchive13t64 \
|
|
|| sudo apt-get install -y -qq strace libarchive13
|
|
|
|
# The runner exposes nested KVM; the runner user needs rw on the
|
|
# device node for the probe to pass.
|
|
- name: Open /dev/kvm
|
|
run: |
|
|
test -c /dev/kvm || { echo "::error::no /dev/kvm on this runner"; exit 1; }
|
|
test -w /dev/kvm || sudo chmod 666 /dev/kvm
|
|
|
|
# The engine is dlopen'd at runtime: build libkrun from the same
|
|
# tag the snap bundles, and take libkrunfw from the pool the way
|
|
# the snap's libkrunfw part does.
|
|
- name: Build the engine
|
|
run: |
|
|
curl -fsSL -o /tmp/libkrunfw5.deb \
|
|
https://archive.ubuntu.com/ubuntu/pool/universe/libk/libkrunfw/libkrunfw5_5.5.0+ds-1_amd64.deb
|
|
echo "924cd545080aaf5da66740d12a51b7a5cbd9a5c0b502d21cbef9bc82bf1c8b6b /tmp/libkrunfw5.deb" | sha256sum -c
|
|
dpkg -x /tmp/libkrunfw5.deb /tmp/libkrunfw
|
|
git clone --depth 1 --branch v1.19.7 https://github.com/containers/libkrun /tmp/libkrun
|
|
cargo build --release --manifest-path /tmp/libkrun/Cargo.toml -p libkrun --features net,blk
|
|
mkdir /tmp/engine
|
|
cp /tmp/libkrun/target/release/libkrun.so /tmp/engine/libkrun.so.1
|
|
cp /tmp/libkrunfw/usr/lib/x86_64-linux-gnu/libkrunfw.so.5.5.0 /tmp/engine/
|
|
ln -s libkrunfw.so.5.5.0 /tmp/engine/libkrunfw.so.5
|
|
|
|
- name: Build the CLI
|
|
run: cargo build --release -p ecrou-cli
|
|
|
|
- name: T6 — no denied syscalls in the host process tree
|
|
env:
|
|
ECROU_BIN: ${{ github.workspace }}/target/release/ecrou
|
|
LD_LIBRARY_PATH: /tmp/engine
|
|
run: cargo test -p ecrou-cli -- --ignored
|
|
|
|
snap:
|
|
name: snap build
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
# The same pack the release workflow publishes. Building it on
|
|
# every change keeps the snap from rotting between tags: the
|
|
# cargo part, the libkrun build, and the libkrunfw digest pins
|
|
# all break here first.
|
|
- uses: snapcore/action-build@v1
|
|
id: build
|
|
|
|
- uses: actions/upload-artifact@v4
|
|
with:
|
|
name: snap-amd64
|
|
path: ${{ steps.build.outputs.snap }}
|
|
|
|
e2e:
|
|
name: snap e2e — apt install
|
|
needs: snap
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
steps:
|
|
- uses: actions/download-artifact@v4
|
|
with:
|
|
name: snap-amd64
|
|
path: snap
|
|
|
|
- name: Install the snap
|
|
run: |
|
|
test -c /dev/kvm || { echo "::error::no /dev/kvm on this runner"; exit 1; }
|
|
test -w /dev/kvm || sudo chmod 666 /dev/kvm
|
|
sudo snap install --dangerous ./snap/*.snap
|
|
sudo snap connect ecrou:kvm
|
|
|
|
# Diagnostics for whatever fails below: KVM state, the engine
|
|
# load from the snap's staged libraries, the cache directory.
|
|
- name: Probe
|
|
run: ecrou probe || true
|
|
|
|
# T8's first half, on the packaged binary: a guest kernel that
|
|
# differs from the host's, inside strict confinement. Fast, so a
|
|
# broken environment fails here instead of deep in the apt run.
|
|
- name: Smoke — boot alpine under confinement
|
|
run: |
|
|
set -euo pipefail
|
|
guest="$(timeout 10m ecrou run --quiet alpine -- uname -r | tail -n 1)"
|
|
host="$(uname -r)"
|
|
echo "guest kernel: $guest / host kernel: $host"
|
|
test -n "$guest" && test "$guest" != "$host"
|
|
|
|
# T8's second half: a real package install end to end — apt
|
|
# through the TSI proxy, mkfs and debugfs through the snap's
|
|
# staged e2fsprogs, the payload's exit code back through the
|
|
# control file. The ln driver's known throughput limit makes
|
|
# this the long pole; how long it takes is the standing
|
|
# re-measurement the Networking section calls for on every
|
|
# engine update.
|
|
- name: apt update && install fastfetch
|
|
run: |
|
|
set -euo pipefail
|
|
# --pipe --logo none: the payload's stdout is a serial
|
|
# console, which fastfetch reads as a tty and decorates with
|
|
# cursor escapes (a first local run grepped nothing); plain
|
|
# output keeps the receipt readable.
|
|
timeout 35m ecrou run --quiet -e DEBIAN_FRONTEND=noninteractive ubuntu -- \
|
|
"apt update && apt install -y fastfetch && fastfetch --pipe --logo none" \
|
|
| tee /tmp/e2e.log
|
|
# Insurance, not the primary check: strip any escape
|
|
# sequences before anchoring on the fastfetch key.
|
|
sed -e 's/\x1b\[[0-9;?]*[A-Za-z]//g' /tmp/e2e.log | grep -E "^OS:"
|