BetterFrame/deploy/rauc/build-bundle.sh

53 lines
1.5 KiB
Bash
Raw Normal View History

feat(os-ota): build + sign + auto-import .raucb bundles in CI Phase 1 of the OS OTA pipeline. Three pieces: scripts/gen-rauc-signing-keys.sh — one-shot helper that issues an Ed25519 X.509 CA + signing cert pair. Operator runs locally, commits the CA cert (for embedding in kiosk image at /etc/rauc/keyring.pem), stores the signing pair as GitHub Actions secrets (BF_RAUC_SIGNING_CERT + BF_RAUC_SIGNING_KEY), keeps the CA private key offline. RAUC verifies bundles against the keyring in the image. deploy/rauc/build-bundle.sh — takes the pi-gen .img.xz, parses its partition table with sfdisk, dd-extracts bootfs (vfat) + rootfs (ext4) into a staging dir, renders manifest.raucm.in with version + git sha, runs `rauc bundle --cert= --key=` to produce a signed .raucb. Verifies the bundle round-trips with `rauc info`. build.yml gains two gated steps: - "Build RAUC bundle": runs only when both signing secrets are set, uploads .raucb as a release asset alongside the .img.xz. - "Auto-import OS bundle into BF server": POSTs the GH release asset URL to ${BF_AUTOIMPORT_URL}/api/admin/os/import so the server pulls + stores the bundle. Mirrors the kiosk-binary auto-import flow that already worked. Compatibility string is `betterframe-rpi5-aarch64` (matches the value already declared in deploy/rauc/system.conf). Channel passed through from inputs (dev for master pushes, stable/beta for tags). What's NOT in this commit: - Pi image A/B partition layout (custom genimage / pi-gen patch) - rauc package install + keyring drop in pi-gen stage - Kiosk-side os_update.rs Rust consumer that polls /api/kiosk/os/check - Admin UI for releases + rollouts A bundle built today reaches /api/admin/os/import on the server but isn't installable yet — kiosks have no consumer and no A/B layout. That's the next 3 phases. Bundle production needs to be solid first so the kiosk side can be tested against real artifacts.
2026-05-21 08:44:24 +00:00
#!/usr/bin/env bash
feat(os-ota): A/B image repartition + bigger Blacksmith binary runners Phase 2a of OS OTA: post-process pi-gen output into a RAUC-compatible A/B layout. New deploy/rauc/repartition-image.sh: - Decompresses the stock pi-gen 2-partition image - Extracts bootfs (vfat) + rootfs (ext4) blobs - Compacts rootfs with resize2fs -M and grows back with 25% headroom - Patches /etc/fstab inside rootfs to use LABEL=BF_BOOT_A / LABEL=BF_ROOT_A / LABEL=BF_DATA (slot-agnostic; RAUC re-labels per slot on install) - Stamps /etc/betterframe/{os-version,os-compatibility} for the kiosk's os_update.rs to read at runtime - Builds two bootfs copies, each with cmdline.txt root= rewritten to the matching ROOT slot - Lays out 6 GPT partitions: BF_BOOTSEL (autoboot.txt with tryboot pointing at boot_partition=2 / [tryboot] boot_partition=3), BF_BOOT_A, BF_BOOT_B, BF_ROOT_A (populated), BF_ROOT_B (empty, RAUC fills on first install), BF_DATA - Recompresses with xz -T0 build-bundle.sh now takes the already-extracted slot images so the .raucb bundle re-uses the exact same blobs that ship inside the A/B initial-flash image — no duplication, no drift. CI wires the repartition step between pi-gen output and the GitHub Release upload. Ships the A/B image (not the stock pi-gen one). Also: bump Blacksmith binary builders from 2/4 vCPU to 8 vCPU each. Image job stays on GitHub's ubuntu-24.04-arm (Blacksmith arm kernel 6.5 doesn't ship binfmt_misc as a loadable module, which pi-gen-action's defensive modprobe step still requires). What's still pending: - In-image RAUC install (rauc package + drop system.conf + CA cert at /etc/rauc/keyring.pem). Without this, the image boots A/B-laid- out but rauc install commands have no daemon to talk to. - Admin UI for OS releases + rollouts (task #4).
2026-05-21 08:57:00 +00:00
# Build a signed RAUC .raucb bundle from pre-extracted slot images.
feat(os-ota): build + sign + auto-import .raucb bundles in CI Phase 1 of the OS OTA pipeline. Three pieces: scripts/gen-rauc-signing-keys.sh — one-shot helper that issues an Ed25519 X.509 CA + signing cert pair. Operator runs locally, commits the CA cert (for embedding in kiosk image at /etc/rauc/keyring.pem), stores the signing pair as GitHub Actions secrets (BF_RAUC_SIGNING_CERT + BF_RAUC_SIGNING_KEY), keeps the CA private key offline. RAUC verifies bundles against the keyring in the image. deploy/rauc/build-bundle.sh — takes the pi-gen .img.xz, parses its partition table with sfdisk, dd-extracts bootfs (vfat) + rootfs (ext4) into a staging dir, renders manifest.raucm.in with version + git sha, runs `rauc bundle --cert= --key=` to produce a signed .raucb. Verifies the bundle round-trips with `rauc info`. build.yml gains two gated steps: - "Build RAUC bundle": runs only when both signing secrets are set, uploads .raucb as a release asset alongside the .img.xz. - "Auto-import OS bundle into BF server": POSTs the GH release asset URL to ${BF_AUTOIMPORT_URL}/api/admin/os/import so the server pulls + stores the bundle. Mirrors the kiosk-binary auto-import flow that already worked. Compatibility string is `betterframe-rpi5-aarch64` (matches the value already declared in deploy/rauc/system.conf). Channel passed through from inputs (dev for master pushes, stable/beta for tags). What's NOT in this commit: - Pi image A/B partition layout (custom genimage / pi-gen patch) - rauc package install + keyring drop in pi-gen stage - Kiosk-side os_update.rs Rust consumer that polls /api/kiosk/os/check - Admin UI for releases + rollouts A bundle built today reaches /api/admin/os/import on the server but isn't installable yet — kiosks have no consumer and no A/B layout. That's the next 3 phases. Bundle production needs to be solid first so the kiosk side can be tested against real artifacts.
2026-05-21 08:44:24 +00:00
#
feat(os-ota): A/B image repartition + bigger Blacksmith binary runners Phase 2a of OS OTA: post-process pi-gen output into a RAUC-compatible A/B layout. New deploy/rauc/repartition-image.sh: - Decompresses the stock pi-gen 2-partition image - Extracts bootfs (vfat) + rootfs (ext4) blobs - Compacts rootfs with resize2fs -M and grows back with 25% headroom - Patches /etc/fstab inside rootfs to use LABEL=BF_BOOT_A / LABEL=BF_ROOT_A / LABEL=BF_DATA (slot-agnostic; RAUC re-labels per slot on install) - Stamps /etc/betterframe/{os-version,os-compatibility} for the kiosk's os_update.rs to read at runtime - Builds two bootfs copies, each with cmdline.txt root= rewritten to the matching ROOT slot - Lays out 6 GPT partitions: BF_BOOTSEL (autoboot.txt with tryboot pointing at boot_partition=2 / [tryboot] boot_partition=3), BF_BOOT_A, BF_BOOT_B, BF_ROOT_A (populated), BF_ROOT_B (empty, RAUC fills on first install), BF_DATA - Recompresses with xz -T0 build-bundle.sh now takes the already-extracted slot images so the .raucb bundle re-uses the exact same blobs that ship inside the A/B initial-flash image — no duplication, no drift. CI wires the repartition step between pi-gen output and the GitHub Release upload. Ships the A/B image (not the stock pi-gen one). Also: bump Blacksmith binary builders from 2/4 vCPU to 8 vCPU each. Image job stays on GitHub's ubuntu-24.04-arm (Blacksmith arm kernel 6.5 doesn't ship binfmt_misc as a loadable module, which pi-gen-action's defensive modprobe step still requires). What's still pending: - In-image RAUC install (rauc package + drop system.conf + CA cert at /etc/rauc/keyring.pem). Without this, the image boots A/B-laid- out but rauc install commands have no daemon to talk to. - Admin UI for OS releases + rollouts (task #4).
2026-05-21 08:57:00 +00:00
# The repartition-image.sh script (run earlier in CI) already extracts
# rootfs.ext4 + bootfs.vfat from the pi-gen output, so this script just
# stages them with a rendered manifest + runs `rauc bundle`.
feat(os-ota): build + sign + auto-import .raucb bundles in CI Phase 1 of the OS OTA pipeline. Three pieces: scripts/gen-rauc-signing-keys.sh — one-shot helper that issues an Ed25519 X.509 CA + signing cert pair. Operator runs locally, commits the CA cert (for embedding in kiosk image at /etc/rauc/keyring.pem), stores the signing pair as GitHub Actions secrets (BF_RAUC_SIGNING_CERT + BF_RAUC_SIGNING_KEY), keeps the CA private key offline. RAUC verifies bundles against the keyring in the image. deploy/rauc/build-bundle.sh — takes the pi-gen .img.xz, parses its partition table with sfdisk, dd-extracts bootfs (vfat) + rootfs (ext4) into a staging dir, renders manifest.raucm.in with version + git sha, runs `rauc bundle --cert= --key=` to produce a signed .raucb. Verifies the bundle round-trips with `rauc info`. build.yml gains two gated steps: - "Build RAUC bundle": runs only when both signing secrets are set, uploads .raucb as a release asset alongside the .img.xz. - "Auto-import OS bundle into BF server": POSTs the GH release asset URL to ${BF_AUTOIMPORT_URL}/api/admin/os/import so the server pulls + stores the bundle. Mirrors the kiosk-binary auto-import flow that already worked. Compatibility string is `betterframe-rpi5-aarch64` (matches the value already declared in deploy/rauc/system.conf). Channel passed through from inputs (dev for master pushes, stable/beta for tags). What's NOT in this commit: - Pi image A/B partition layout (custom genimage / pi-gen patch) - rauc package install + keyring drop in pi-gen stage - Kiosk-side os_update.rs Rust consumer that polls /api/kiosk/os/check - Admin UI for releases + rollouts A bundle built today reaches /api/admin/os/import on the server but isn't installable yet — kiosks have no consumer and no A/B layout. That's the next 3 phases. Bundle production needs to be solid first so the kiosk side can be tested against real artifacts.
2026-05-21 08:44:24 +00:00
#
feat(os-ota): A/B image repartition + bigger Blacksmith binary runners Phase 2a of OS OTA: post-process pi-gen output into a RAUC-compatible A/B layout. New deploy/rauc/repartition-image.sh: - Decompresses the stock pi-gen 2-partition image - Extracts bootfs (vfat) + rootfs (ext4) blobs - Compacts rootfs with resize2fs -M and grows back with 25% headroom - Patches /etc/fstab inside rootfs to use LABEL=BF_BOOT_A / LABEL=BF_ROOT_A / LABEL=BF_DATA (slot-agnostic; RAUC re-labels per slot on install) - Stamps /etc/betterframe/{os-version,os-compatibility} for the kiosk's os_update.rs to read at runtime - Builds two bootfs copies, each with cmdline.txt root= rewritten to the matching ROOT slot - Lays out 6 GPT partitions: BF_BOOTSEL (autoboot.txt with tryboot pointing at boot_partition=2 / [tryboot] boot_partition=3), BF_BOOT_A, BF_BOOT_B, BF_ROOT_A (populated), BF_ROOT_B (empty, RAUC fills on first install), BF_DATA - Recompresses with xz -T0 build-bundle.sh now takes the already-extracted slot images so the .raucb bundle re-uses the exact same blobs that ship inside the A/B initial-flash image — no duplication, no drift. CI wires the repartition step between pi-gen output and the GitHub Release upload. Ships the A/B image (not the stock pi-gen one). Also: bump Blacksmith binary builders from 2/4 vCPU to 8 vCPU each. Image job stays on GitHub's ubuntu-24.04-arm (Blacksmith arm kernel 6.5 doesn't ship binfmt_misc as a loadable module, which pi-gen-action's defensive modprobe step still requires). What's still pending: - In-image RAUC install (rauc package + drop system.conf + CA cert at /etc/rauc/keyring.pem). Without this, the image boots A/B-laid- out but rauc install commands have no daemon to talk to. - Admin UI for OS releases + rollouts (task #4).
2026-05-21 08:57:00 +00:00
# Usage:
# build-bundle.sh <rootfs.ext4> <bootfs.vfat> <out.raucb> \
# <version> <git_sha> <signing_cert.pem> <signing_key.pem>
feat(os-ota): build + sign + auto-import .raucb bundles in CI Phase 1 of the OS OTA pipeline. Three pieces: scripts/gen-rauc-signing-keys.sh — one-shot helper that issues an Ed25519 X.509 CA + signing cert pair. Operator runs locally, commits the CA cert (for embedding in kiosk image at /etc/rauc/keyring.pem), stores the signing pair as GitHub Actions secrets (BF_RAUC_SIGNING_CERT + BF_RAUC_SIGNING_KEY), keeps the CA private key offline. RAUC verifies bundles against the keyring in the image. deploy/rauc/build-bundle.sh — takes the pi-gen .img.xz, parses its partition table with sfdisk, dd-extracts bootfs (vfat) + rootfs (ext4) into a staging dir, renders manifest.raucm.in with version + git sha, runs `rauc bundle --cert= --key=` to produce a signed .raucb. Verifies the bundle round-trips with `rauc info`. build.yml gains two gated steps: - "Build RAUC bundle": runs only when both signing secrets are set, uploads .raucb as a release asset alongside the .img.xz. - "Auto-import OS bundle into BF server": POSTs the GH release asset URL to ${BF_AUTOIMPORT_URL}/api/admin/os/import so the server pulls + stores the bundle. Mirrors the kiosk-binary auto-import flow that already worked. Compatibility string is `betterframe-rpi5-aarch64` (matches the value already declared in deploy/rauc/system.conf). Channel passed through from inputs (dev for master pushes, stable/beta for tags). What's NOT in this commit: - Pi image A/B partition layout (custom genimage / pi-gen patch) - rauc package install + keyring drop in pi-gen stage - Kiosk-side os_update.rs Rust consumer that polls /api/kiosk/os/check - Admin UI for releases + rollouts A bundle built today reaches /api/admin/os/import on the server but isn't installable yet — kiosks have no consumer and no A/B layout. That's the next 3 phases. Bundle production needs to be solid first so the kiosk side can be tested against real artifacts.
2026-05-21 08:44:24 +00:00
set -euo pipefail
feat(os-ota): A/B image repartition + bigger Blacksmith binary runners Phase 2a of OS OTA: post-process pi-gen output into a RAUC-compatible A/B layout. New deploy/rauc/repartition-image.sh: - Decompresses the stock pi-gen 2-partition image - Extracts bootfs (vfat) + rootfs (ext4) blobs - Compacts rootfs with resize2fs -M and grows back with 25% headroom - Patches /etc/fstab inside rootfs to use LABEL=BF_BOOT_A / LABEL=BF_ROOT_A / LABEL=BF_DATA (slot-agnostic; RAUC re-labels per slot on install) - Stamps /etc/betterframe/{os-version,os-compatibility} for the kiosk's os_update.rs to read at runtime - Builds two bootfs copies, each with cmdline.txt root= rewritten to the matching ROOT slot - Lays out 6 GPT partitions: BF_BOOTSEL (autoboot.txt with tryboot pointing at boot_partition=2 / [tryboot] boot_partition=3), BF_BOOT_A, BF_BOOT_B, BF_ROOT_A (populated), BF_ROOT_B (empty, RAUC fills on first install), BF_DATA - Recompresses with xz -T0 build-bundle.sh now takes the already-extracted slot images so the .raucb bundle re-uses the exact same blobs that ship inside the A/B initial-flash image — no duplication, no drift. CI wires the repartition step between pi-gen output and the GitHub Release upload. Ships the A/B image (not the stock pi-gen one). Also: bump Blacksmith binary builders from 2/4 vCPU to 8 vCPU each. Image job stays on GitHub's ubuntu-24.04-arm (Blacksmith arm kernel 6.5 doesn't ship binfmt_misc as a loadable module, which pi-gen-action's defensive modprobe step still requires). What's still pending: - In-image RAUC install (rauc package + drop system.conf + CA cert at /etc/rauc/keyring.pem). Without this, the image boots A/B-laid- out but rauc install commands have no daemon to talk to. - Admin UI for OS releases + rollouts (task #4).
2026-05-21 08:57:00 +00:00
ROOTFS_IN="${1:?rootfs.ext4 path required}"
BOOTFS_IN="${2:?bootfs.vfat path required}"
OUT_RAUCB="${3:?output .raucb path required}"
VERSION="${4:?version required}"
GIT_SHA="${5:?git sha required}"
SIGNING_CERT="${6:?signing cert path required}"
SIGNING_KEY="${7:?signing key path required}"
feat(os-ota): build + sign + auto-import .raucb bundles in CI Phase 1 of the OS OTA pipeline. Three pieces: scripts/gen-rauc-signing-keys.sh — one-shot helper that issues an Ed25519 X.509 CA + signing cert pair. Operator runs locally, commits the CA cert (for embedding in kiosk image at /etc/rauc/keyring.pem), stores the signing pair as GitHub Actions secrets (BF_RAUC_SIGNING_CERT + BF_RAUC_SIGNING_KEY), keeps the CA private key offline. RAUC verifies bundles against the keyring in the image. deploy/rauc/build-bundle.sh — takes the pi-gen .img.xz, parses its partition table with sfdisk, dd-extracts bootfs (vfat) + rootfs (ext4) into a staging dir, renders manifest.raucm.in with version + git sha, runs `rauc bundle --cert= --key=` to produce a signed .raucb. Verifies the bundle round-trips with `rauc info`. build.yml gains two gated steps: - "Build RAUC bundle": runs only when both signing secrets are set, uploads .raucb as a release asset alongside the .img.xz. - "Auto-import OS bundle into BF server": POSTs the GH release asset URL to ${BF_AUTOIMPORT_URL}/api/admin/os/import so the server pulls + stores the bundle. Mirrors the kiosk-binary auto-import flow that already worked. Compatibility string is `betterframe-rpi5-aarch64` (matches the value already declared in deploy/rauc/system.conf). Channel passed through from inputs (dev for master pushes, stable/beta for tags). What's NOT in this commit: - Pi image A/B partition layout (custom genimage / pi-gen patch) - rauc package install + keyring drop in pi-gen stage - Kiosk-side os_update.rs Rust consumer that polls /api/kiosk/os/check - Admin UI for releases + rollouts A bundle built today reaches /api/admin/os/import on the server but isn't installable yet — kiosks have no consumer and no A/B layout. That's the next 3 phases. Bundle production needs to be solid first so the kiosk side can be tested against real artifacts.
2026-05-21 08:44:24 +00:00
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MANIFEST_IN="${SCRIPT_DIR}/manifest.raucm.in"
WORK_DIR="$(mktemp -d)"
trap 'rm -rf "$WORK_DIR"' EXIT
STAGE="${WORK_DIR}/bundle"
mkdir -p "$STAGE"
feat(os-ota): A/B image repartition + bigger Blacksmith binary runners Phase 2a of OS OTA: post-process pi-gen output into a RAUC-compatible A/B layout. New deploy/rauc/repartition-image.sh: - Decompresses the stock pi-gen 2-partition image - Extracts bootfs (vfat) + rootfs (ext4) blobs - Compacts rootfs with resize2fs -M and grows back with 25% headroom - Patches /etc/fstab inside rootfs to use LABEL=BF_BOOT_A / LABEL=BF_ROOT_A / LABEL=BF_DATA (slot-agnostic; RAUC re-labels per slot on install) - Stamps /etc/betterframe/{os-version,os-compatibility} for the kiosk's os_update.rs to read at runtime - Builds two bootfs copies, each with cmdline.txt root= rewritten to the matching ROOT slot - Lays out 6 GPT partitions: BF_BOOTSEL (autoboot.txt with tryboot pointing at boot_partition=2 / [tryboot] boot_partition=3), BF_BOOT_A, BF_BOOT_B, BF_ROOT_A (populated), BF_ROOT_B (empty, RAUC fills on first install), BF_DATA - Recompresses with xz -T0 build-bundle.sh now takes the already-extracted slot images so the .raucb bundle re-uses the exact same blobs that ship inside the A/B initial-flash image — no duplication, no drift. CI wires the repartition step between pi-gen output and the GitHub Release upload. Ships the A/B image (not the stock pi-gen one). Also: bump Blacksmith binary builders from 2/4 vCPU to 8 vCPU each. Image job stays on GitHub's ubuntu-24.04-arm (Blacksmith arm kernel 6.5 doesn't ship binfmt_misc as a loadable module, which pi-gen-action's defensive modprobe step still requires). What's still pending: - In-image RAUC install (rauc package + drop system.conf + CA cert at /etc/rauc/keyring.pem). Without this, the image boots A/B-laid- out but rauc install commands have no daemon to talk to. - Admin UI for OS releases + rollouts (task #4).
2026-05-21 08:57:00 +00:00
cp "$ROOTFS_IN" "${STAGE}/rootfs.ext4"
cp "$BOOTFS_IN" "${STAGE}/bootfs.vfat"
feat(os-ota): build + sign + auto-import .raucb bundles in CI Phase 1 of the OS OTA pipeline. Three pieces: scripts/gen-rauc-signing-keys.sh — one-shot helper that issues an Ed25519 X.509 CA + signing cert pair. Operator runs locally, commits the CA cert (for embedding in kiosk image at /etc/rauc/keyring.pem), stores the signing pair as GitHub Actions secrets (BF_RAUC_SIGNING_CERT + BF_RAUC_SIGNING_KEY), keeps the CA private key offline. RAUC verifies bundles against the keyring in the image. deploy/rauc/build-bundle.sh — takes the pi-gen .img.xz, parses its partition table with sfdisk, dd-extracts bootfs (vfat) + rootfs (ext4) into a staging dir, renders manifest.raucm.in with version + git sha, runs `rauc bundle --cert= --key=` to produce a signed .raucb. Verifies the bundle round-trips with `rauc info`. build.yml gains two gated steps: - "Build RAUC bundle": runs only when both signing secrets are set, uploads .raucb as a release asset alongside the .img.xz. - "Auto-import OS bundle into BF server": POSTs the GH release asset URL to ${BF_AUTOIMPORT_URL}/api/admin/os/import so the server pulls + stores the bundle. Mirrors the kiosk-binary auto-import flow that already worked. Compatibility string is `betterframe-rpi5-aarch64` (matches the value already declared in deploy/rauc/system.conf). Channel passed through from inputs (dev for master pushes, stable/beta for tags). What's NOT in this commit: - Pi image A/B partition layout (custom genimage / pi-gen patch) - rauc package install + keyring drop in pi-gen stage - Kiosk-side os_update.rs Rust consumer that polls /api/kiosk/os/check - Admin UI for releases + rollouts A bundle built today reaches /api/admin/os/import on the server but isn't installable yet — kiosks have no consumer and no A/B layout. That's the next 3 phases. Bundle production needs to be solid first so the kiosk side can be tested against real artifacts.
2026-05-21 08:44:24 +00:00
echo "==> Rendering manifest"
sed -e "s|@VERSION@|${VERSION}|g" \
-e "s|@GIT_SHA@|${GIT_SHA}|g" \
"$MANIFEST_IN" > "${STAGE}/manifest.raucm"
ls -la "$STAGE"
cat "${STAGE}/manifest.raucm"
echo "==> Building RAUC bundle"
rm -f "$OUT_RAUCB"
rauc bundle \
--cert="$SIGNING_CERT" \
--key="$SIGNING_KEY" \
"$STAGE" "$OUT_RAUCB"
feat(os-ota): A/B image repartition + bigger Blacksmith binary runners Phase 2a of OS OTA: post-process pi-gen output into a RAUC-compatible A/B layout. New deploy/rauc/repartition-image.sh: - Decompresses the stock pi-gen 2-partition image - Extracts bootfs (vfat) + rootfs (ext4) blobs - Compacts rootfs with resize2fs -M and grows back with 25% headroom - Patches /etc/fstab inside rootfs to use LABEL=BF_BOOT_A / LABEL=BF_ROOT_A / LABEL=BF_DATA (slot-agnostic; RAUC re-labels per slot on install) - Stamps /etc/betterframe/{os-version,os-compatibility} for the kiosk's os_update.rs to read at runtime - Builds two bootfs copies, each with cmdline.txt root= rewritten to the matching ROOT slot - Lays out 6 GPT partitions: BF_BOOTSEL (autoboot.txt with tryboot pointing at boot_partition=2 / [tryboot] boot_partition=3), BF_BOOT_A, BF_BOOT_B, BF_ROOT_A (populated), BF_ROOT_B (empty, RAUC fills on first install), BF_DATA - Recompresses with xz -T0 build-bundle.sh now takes the already-extracted slot images so the .raucb bundle re-uses the exact same blobs that ship inside the A/B initial-flash image — no duplication, no drift. CI wires the repartition step between pi-gen output and the GitHub Release upload. Ships the A/B image (not the stock pi-gen one). Also: bump Blacksmith binary builders from 2/4 vCPU to 8 vCPU each. Image job stays on GitHub's ubuntu-24.04-arm (Blacksmith arm kernel 6.5 doesn't ship binfmt_misc as a loadable module, which pi-gen-action's defensive modprobe step still requires). What's still pending: - In-image RAUC install (rauc package + drop system.conf + CA cert at /etc/rauc/keyring.pem). Without this, the image boots A/B-laid- out but rauc install commands have no daemon to talk to. - Admin UI for OS releases + rollouts (task #4).
2026-05-21 08:57:00 +00:00
echo "==> Verifying bundle"
feat(os-ota): build + sign + auto-import .raucb bundles in CI Phase 1 of the OS OTA pipeline. Three pieces: scripts/gen-rauc-signing-keys.sh — one-shot helper that issues an Ed25519 X.509 CA + signing cert pair. Operator runs locally, commits the CA cert (for embedding in kiosk image at /etc/rauc/keyring.pem), stores the signing pair as GitHub Actions secrets (BF_RAUC_SIGNING_CERT + BF_RAUC_SIGNING_KEY), keeps the CA private key offline. RAUC verifies bundles against the keyring in the image. deploy/rauc/build-bundle.sh — takes the pi-gen .img.xz, parses its partition table with sfdisk, dd-extracts bootfs (vfat) + rootfs (ext4) into a staging dir, renders manifest.raucm.in with version + git sha, runs `rauc bundle --cert= --key=` to produce a signed .raucb. Verifies the bundle round-trips with `rauc info`. build.yml gains two gated steps: - "Build RAUC bundle": runs only when both signing secrets are set, uploads .raucb as a release asset alongside the .img.xz. - "Auto-import OS bundle into BF server": POSTs the GH release asset URL to ${BF_AUTOIMPORT_URL}/api/admin/os/import so the server pulls + stores the bundle. Mirrors the kiosk-binary auto-import flow that already worked. Compatibility string is `betterframe-rpi5-aarch64` (matches the value already declared in deploy/rauc/system.conf). Channel passed through from inputs (dev for master pushes, stable/beta for tags). What's NOT in this commit: - Pi image A/B partition layout (custom genimage / pi-gen patch) - rauc package install + keyring drop in pi-gen stage - Kiosk-side os_update.rs Rust consumer that polls /api/kiosk/os/check - Admin UI for releases + rollouts A bundle built today reaches /api/admin/os/import on the server but isn't installable yet — kiosks have no consumer and no A/B layout. That's the next 3 phases. Bundle production needs to be solid first so the kiosk side can be tested against real artifacts.
2026-05-21 08:44:24 +00:00
rauc info --keyring="$SIGNING_CERT" "$OUT_RAUCB"
echo
feat(os-ota): A/B image repartition + bigger Blacksmith binary runners Phase 2a of OS OTA: post-process pi-gen output into a RAUC-compatible A/B layout. New deploy/rauc/repartition-image.sh: - Decompresses the stock pi-gen 2-partition image - Extracts bootfs (vfat) + rootfs (ext4) blobs - Compacts rootfs with resize2fs -M and grows back with 25% headroom - Patches /etc/fstab inside rootfs to use LABEL=BF_BOOT_A / LABEL=BF_ROOT_A / LABEL=BF_DATA (slot-agnostic; RAUC re-labels per slot on install) - Stamps /etc/betterframe/{os-version,os-compatibility} for the kiosk's os_update.rs to read at runtime - Builds two bootfs copies, each with cmdline.txt root= rewritten to the matching ROOT slot - Lays out 6 GPT partitions: BF_BOOTSEL (autoboot.txt with tryboot pointing at boot_partition=2 / [tryboot] boot_partition=3), BF_BOOT_A, BF_BOOT_B, BF_ROOT_A (populated), BF_ROOT_B (empty, RAUC fills on first install), BF_DATA - Recompresses with xz -T0 build-bundle.sh now takes the already-extracted slot images so the .raucb bundle re-uses the exact same blobs that ship inside the A/B initial-flash image — no duplication, no drift. CI wires the repartition step between pi-gen output and the GitHub Release upload. Ships the A/B image (not the stock pi-gen one). Also: bump Blacksmith binary builders from 2/4 vCPU to 8 vCPU each. Image job stays on GitHub's ubuntu-24.04-arm (Blacksmith arm kernel 6.5 doesn't ship binfmt_misc as a loadable module, which pi-gen-action's defensive modprobe step still requires). What's still pending: - In-image RAUC install (rauc package + drop system.conf + CA cert at /etc/rauc/keyring.pem). Without this, the image boots A/B-laid- out but rauc install commands have no daemon to talk to. - Admin UI for OS releases + rollouts (task #4).
2026-05-21 08:57:00 +00:00
echo "==> Bundle: $(ls -la "$OUT_RAUCB")"