Refactor dnsmasq to build as a container. Add signed iPXE image build
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
#
|
||||
# .gitea/workflows/ipxe-image.yaml
|
||||
#
|
||||
# Builds the fleet-ipxe image: the iPXE network bootloader (snponly.efi) for the
|
||||
# PXE-only chainload path (firmware without UEFI HTTP boot, e.g. EliteBook 820
|
||||
# G4), SIGNED with the fleet `db` key and packaged as a tiny FROM-scratch OCI
|
||||
# image. The dnsmasq serving container mounts it at /ipxe and copies snponly.efi
|
||||
# into its TFTP root — so the serving host never carries a loose, unsigned .efi
|
||||
# and the bootloader is digest-pinned + signed exactly like the UKI.
|
||||
#
|
||||
# Kept separate from the (generic) dnsmasq image so the daemon image stays
|
||||
# key-agnostic and this one is the only per-Secure-Boot-environment artifact.
|
||||
# See scripts/build-ipxe-oci.sh, docs/secure-boot-keys.md, CLAUDE.md invariant #9.
|
||||
#
|
||||
# Runs only when the iPXE inputs change (path filter) or on demand.
|
||||
#
|
||||
# Required Gitea repo secrets: PACKAGE_USER, PACKAGE_TOKEN (registry creds).
|
||||
# Optional: SB_KEY, SB_CERT (db PRIVATE key + cert, PEM). Unset => UNSIGNED lab
|
||||
# image (loud warning; Secure-Boot-enforcing hosts will reject it). PK/KEK
|
||||
# never come near CI — only `db` signs (docs/secure-boot-keys.md).
|
||||
#
|
||||
|
||||
name: Build fleet-ipxe image
|
||||
run-name: ${{ gitea.actor }} builds the signed fleet-ipxe bootloader image
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
paths:
|
||||
- "scripts/build-ipxe-oci.sh"
|
||||
- ".gitea/workflows/ipxe-image.yaml"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ipxe_version:
|
||||
description: "Override the image tag (default: sanitized ipxe package version)"
|
||||
required: false
|
||||
|
||||
env:
|
||||
IPXE_IMAGE: "git.bitasylum.org/audiobuzz/fleet-ipxe"
|
||||
|
||||
jobs:
|
||||
ipxe-build:
|
||||
name: Build & push fleet-ipxe image
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: git.bitasylum.org/audiobuzz/ubuntu-act-runner-qemu:main
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
-
|
||||
name: Install tooling
|
||||
# buildah (OCI build), sbsigntool (sbsign/sbverify — Debian singular), and
|
||||
# the ipxe package which ships the prebuilt snponly.efi.
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends buildah sbsigntool ipxe
|
||||
|
||||
-
|
||||
name: Locate snponly.efi + derive tag
|
||||
id: src
|
||||
run: |
|
||||
# snponly.efi: UEFI x64 iPXE that rides the firmware's NIC driver (SNP),
|
||||
# so it binds where iPXE's native driver won't (e.g. I219-LM). Ubuntu's
|
||||
# ipxe package installs it under /usr/lib/ipxe.
|
||||
SNP=$(find /usr/lib/ipxe /usr/share/ipxe -name 'snponly.efi' 2>/dev/null | head -1)
|
||||
[ -n "$SNP" ] || { echo "snponly.efi not found in the ipxe package" >&2; exit 1; }
|
||||
echo "snponly=$SNP" >> "$GITHUB_OUTPUT"
|
||||
# Tag: dispatch override, else the ipxe package version sanitized to the
|
||||
# OCI tag charset ([A-Za-z0-9_.-]).
|
||||
RAW=$(dpkg-query -W -f='${Version}' ipxe 2>/dev/null || echo unknown)
|
||||
VER="${{ inputs.ipxe_version }}"
|
||||
[ -n "$VER" ] || VER=$(printf '%s' "$RAW" | sed 's/[^A-Za-z0-9_.-]/-/g')
|
||||
echo "version=$VER" >> "$GITHUB_OUTPUT"
|
||||
echo "Using snponly.efi=$SNP tag=$VER (ipxe pkg $RAW)"
|
||||
|
||||
-
|
||||
name: Materialize Secure Boot signing material
|
||||
# Same db key that signs the UKI; written to a runner-temp file and passed
|
||||
# to build-ipxe-oci.sh as a path. If SB_KEY is unset this no-ops and the
|
||||
# build produces an UNSIGNED (lab) image with its loud warning.
|
||||
if: ${{ secrets.SB_KEY != '' }}
|
||||
env:
|
||||
SB_KEY: ${{ secrets.SB_KEY }}
|
||||
SB_CERT: ${{ secrets.SB_CERT }}
|
||||
run: |
|
||||
umask 077
|
||||
d="$RUNNER_TEMP/sb"; mkdir -p "$d"
|
||||
printf '%s\n' "$SB_KEY" > "$d/db.key"
|
||||
printf '%s\n' "$SB_CERT" > "$d/db.crt"
|
||||
echo "SB_KEY_FILE=$d/db.key" >> "$GITHUB_ENV"
|
||||
echo "SB_CERT_FILE=$d/db.crt" >> "$GITHUB_ENV"
|
||||
echo "Secure Boot signing material staged (signed fleet-ipxe build)."
|
||||
|
||||
-
|
||||
name: Registry login
|
||||
run: |
|
||||
buildah login \
|
||||
--username "${{ secrets.PACKAGE_USER }}" \
|
||||
--password "${{ secrets.PACKAGE_TOKEN }}" \
|
||||
git.bitasylum.org
|
||||
|
||||
-
|
||||
name: Build & push
|
||||
env:
|
||||
STORAGE_DRIVER: vfs
|
||||
run: |
|
||||
VER="${{ steps.src.outputs.version }}"
|
||||
bash scripts/build-ipxe-oci.sh \
|
||||
"${{ steps.src.outputs.snponly }}" \
|
||||
"${IPXE_IMAGE}" \
|
||||
"$VER" \
|
||||
"${SB_KEY_FILE:-}" \
|
||||
"${SB_CERT_FILE:-}" \
|
||||
true
|
||||
# also publish :latest for lab convenience (pin by digest in production)
|
||||
buildah tag "${IPXE_IMAGE}:${VER}" "${IPXE_IMAGE}:latest"
|
||||
buildah push "${IPXE_IMAGE}:latest"
|
||||
|
||||
-
|
||||
name: Shred Secure Boot signing key
|
||||
if: always()
|
||||
run: shred -u "$RUNNER_TEMP/sb/db.key" 2>/dev/null || rm -f "$RUNNER_TEMP/sb/db.key" 2>/dev/null || true
|
||||
Reference in New Issue
Block a user