# # .gitea/workflows/gitea-main-ci.yaml # # Builds the diskless fleet release: a fleet-generic UKI + erofs/dm-verity # root, packaged as a FROM-scratch OCI artifact image (see CLAUDE.md and # docs/diskless-fleet-design-v2.pdf). Packer kickstart-installs a throwaway # Rocky 9 build VM (qemu), builds the --no-hostonly initramfs, then the # shell-local post-processors extract artifacts, build the UKI (ukify), and # build+push the OCI release image. # # This is an UNSIGNED (lab) build: sb_key/sb_cert are intentionally NOT passed, # so build-oci.sh emits its loud unsigned-UKI warning. A production fleet must # sign in CI/HSM -- see the "TODO: wire SB_KEY/SB_CERT" step below. # # Required Gitea repo secrets: # REGISTRY_USERNAME - registry user for `oci_image` (oci_push=true) # REGISTRY_TOKEN - registry password/token # # SB_KEY, SB_CERT - (future) Secure Boot signing key + cert for signed UKIs # # Runner: needs KVM (qemu accelerator=kvm) and the build-host tooling installed # below (libguestfs, erofs-utils, cryptsetup, jq, ukify, buildah). # name: Build Diskless UKI run-name: ${{ gitea.actor }} builds the diskless fleet UKI on: push: branches: - "main" tags: - "v*" env: PRODUCT_VERSION: "1.15.4" # Packer version PACKER_LOG: "1" OCI_IMAGE: "git.bitasylum.org/audiobuzz/fleet-boot" NIC_DRIVERS: "ice mlx5_core" # =========================================================================== # TEMPORARY: 802.1X + MACsec are DISABLED for this build (rd.dot1x=0) so the # UKI / rootfs / NVMe-oF boot path can be validated on an OPEN switch port. # The resulting UKI has NO link authentication or encryption — test networks # only. Set back to "false" to restore the full secure boot chain. # =========================================================================== DISABLE_DOT1X: "true" jobs: uki-build: name: Diskless UKI Build runs-on: ubuntu-latest container: image: git.bitasylum.org/audiobuzz/ubuntu-act-runner-qemu:main options: --device /dev/kvm steps: - name: Checkout uses: actions/checkout@v6 - name: Derive image version id: vars # Tag push (v1.2.3 -> 1.2.3); otherwise 0.0.0-. run: | ref="${GITHUB_REF#refs/*/}" if [ "${GITHUB_REF#refs/tags/}" != "$GITHUB_REF" ]; then version="${ref#v}" else version="0.0.0-$(echo "${GITHUB_SHA}" | cut -c1-7)" fi echo "image_version=${version}" >> "$GITHUB_OUTPUT" echo "Building image_version=${version}" - name: Install build-host tooling # Tools the shell-local post-processors run on the RUNNER (not the VM): # libguestfs (virt-*), erofs-utils (mkfs.erofs), cryptsetup # (veritysetup), jq, systemd-ukify (ukify), buildah (OCI), plus qemu + # shellcheck for the lint gate. run: | sudo apt-get update sudo apt-get install -y --no-install-recommends \ qemu-system-x86 qemu-utils libguestfs-tools \ erofs-utils cryptsetup-bin jq systemd-ukify buildah shellcheck - name: Setup Packer uses: hashicorp/setup-packer@main with: version: ${{ env.PRODUCT_VERSION }} - name: Shell lint gate # Matches CLAUDE.md conventions; dracut hooks + post-processor scripts. run: | bash -n files/dracut/95dot1x-macsec/*.sh scripts/*.sh # SC1091 (sourced /lib/dracut-lib.sh) and SC2154 (dracut-injected # $moddir) are dracut-module false positives. They're also in # .shellcheckrc, but excluded explicitly here so the gate doesn't # depend on the runner's shellcheck finding that rc file. shellcheck --exclude=SC1091,SC2154 files/dracut/95dot1x-macsec/*.sh scripts/*.sh - name: packer init run: packer init . - name: packer validate run: packer validate . - name: Registry login # Enables oci_push=true in the build step below. run: | buildah login \ --username "${{ secrets.PACKAGE_USER }}" \ --password "${{ secrets.PACKAGE_TOKEN }}" \ git.bitasylum.org - name: packer build (UKI + OCI release image) # UNSIGNED lab build: sb_key/sb_cert deliberately omitted. # TODO: wire SB_KEY/SB_CERT secrets for a signed UKI: # -var sb_key=${{ secrets.SB_KEY }} -var sb_cert=${{ secrets.SB_CERT }} run: | packer build -color=false -on-error=abort \ -var image_version="${{ steps.vars.outputs.image_version }}" \ -var nic_drivers="${{ env.NIC_DRIVERS }}" \ -var oci_image="${{ env.OCI_IMAGE }}" \ -var oci_push=true \ -var disable_dot1x=${{ env.DISABLE_DOT1X }} \ .