Skip to content

ci: pass the qemu tests only the secrets they use #4444

ci: pass the qemu tests only the secrets they use

ci: pass the qemu tests only the secrets they use #4444

Workflow file for this run

name: Build UKI images
on:
pull_request:
push:
branches:
- master
permissions:
contents: write
security-events: write
id-token: write
actions: read
concurrency:
group: ci-uki-${{ github.head_ref || github.ref }}-${{ github.repository }}
cancel-in-progress: true
jobs:
build:
name: ${{ matrix.image_name }}
uses: kairos-io/kairos-factory-action/.github/workflows/reusable-factory.yaml@8952c3a5f4f6255cc63af88cb3637a9684970c8d # v1.1.3
secrets:
registry_username: ${{ secrets.QUAY_USERNAME }}
registry_password: ${{ secrets.QUAY_PASSWORD }}
with:
auroraboot_version: "v0.26.2"
dockerfile_path: "images/Dockerfile"
base_image: ${{ matrix.base_image }}
kubernetes_distro: ${{ matrix.kubernetes_distro }}
model: "generic"
arch: "amd64"
trusted_boot: true
keys_dir: "$PWD/tests/assets/keys"
sysext_dir: "$PWD/tests/assets/sysext"
single_efi_cmdline: "testentry: nothing"
version: "auto"
iso: true
grype: false
security_scan_mode: "enforce"
registry_domain: "quay.io"
registry_namespace: "kairos"
registry_repository: "ci-temp-images"
custom_tag_format: "$FLAVOR-$FLAVOR_RELEASE-$VARIANT-$ARCH-$MODEL-$COMMIT_SHA-uki"
custom_artifact_format: "kairos-$FLAVOR-$FLAVOR_RELEASE-$VARIANT-$ARCH-$MODEL-uki"
custom_job_name_format: ${{ matrix.custom_job_name_format }}
image_labels: "quay.expires-after=6h"
summary_artifacts: true
strategy:
matrix:
include:
- image_name: "hadron-trusted"
base_image: "ghcr.io/kairos-io/hadron-trusted:v0.5.1"
kubernetes_distro: ""
custom_job_name_format: "core-amd64-generic-uki"
- image_name: "hadron-trusted"
base_image: "ghcr.io/kairos-io/hadron-trusted:v0.5.1"
kubernetes_distro: "k3s"
custom_job_name_format: "standard-amd64-generic-k3s-uki"
test_generic:
name: test_generic (${{ matrix.image_label }}, ${{ matrix.arch }}, ${{ matrix.model }}, ${{ matrix.variant }})
needs: build
runs-on: kvm
strategy:
fail-fast: false
matrix:
image_label: ["hadron-trusted"]
base_image:
- "ghcr.io/kairos-io/hadron-trusted:v0.5.1"
arch: ["amd64"]
model: ["generic"]
variant: ["standard"]
steps:
- name: Split base image
id: split
run: |
# Split base image for tag generation
BASE_IMAGE=$(echo "${{ matrix.base_image }}" | cut -d ':' -f 1)
BASE_TAG=$(echo "${{ matrix.base_image }}" | cut -d ':' -f 2 || echo 'latest')
# Handle special cases for base images with slashes
# Handle base images with slashes (registry paths)
# Examples:
# - ubuntu:24.04 -> FLAVOR=ubuntu, FLAVOR_RELEASE=24.04
# - opensuse/leap:15.6 -> FLAVOR=opensuse, FLAVOR_RELEASE=leap-15.6
# - ghcr.io/kairos-io/hadron:main -> FLAVOR=hadron, FLAVOR_RELEASE=main
if [[ "$BASE_IMAGE" == *"/"* ]]; then
DISTRO=$(echo "$BASE_IMAGE" | cut -d '/' -f 1)
SUB_DISTRO=$(echo "$BASE_IMAGE" | cut -d '/' -f 2)
FLAVOR="$DISTRO"
FLAVOR_RELEASE="$SUB_DISTRO-$BASE_TAG"
# Count number of slashes to determine if it's a registry path
SLASH_COUNT=$(echo "$BASE_IMAGE" | tr -cd '/' | wc -c)
if [[ $SLASH_COUNT -eq 1 ]]; then
# Simple case: distro/subdistro (preserve existing behavior)
DISTRO=$(echo "$BASE_IMAGE" | cut -d '/' -f 1)
SUB_DISTRO=$(echo "$BASE_IMAGE" | cut -d '/' -f 2)
FLAVOR="$DISTRO"
FLAVOR_RELEASE="$SUB_DISTRO-$BASE_TAG"
else
# Registry path with multiple slashes: extract last component as FLAVOR
# e.g., ghcr.io/kairos-io/hadron -> FLAVOR=hadron
FLAVOR=$(echo "$BASE_IMAGE" | awk -F'/' '{print $NF}')
FLAVOR_RELEASE="$BASE_TAG"
fi
else
# No slashes: simple image name
FLAVOR="$BASE_IMAGE"
FLAVOR_RELEASE="$BASE_TAG"
fi
echo "Base Image: $BASE_IMAGE"
echo "Determined Flavor: $FLAVOR"
echo "Determined Flavor Release: $FLAVOR_RELEASE"
echo "flavor=$FLAVOR" >> $GITHUB_OUTPUT
echo "flavor_release=$FLAVOR_RELEASE" >> $GITHUB_OUTPUT
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: '0'
- name: Set Version
run: echo "VERSION=$(git describe --tags --dirty )" >> $GITHUB_ENV
- name: Install Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
timeout-minutes: 5
with:
go-version-file: tests/go.mod
cache-dependency-path: tests/go.sum
cache: ${{ runner.environment == 'self-hosted' && 'false' || 'true' }}
- name: Enable KVM group perms and install deps
run: |
sudo apt-get update
sudo apt-get install -y libvirt-clients libvirt-daemon-system libvirt-daemon virtinst bridge-utils qemu-system-x86 qemu-utils acl udev mkisofs swtpm ovmf
# https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/
# echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
# sudo udevadm control --reload-rules
# sudo udevadm trigger --name-match=kvm
# sudo usermod -a -G kvm,libvirt $USER
#
# TODO: Switch back to the above solution when we switch to the github runners
# https://askubuntu.com/a/1081326
sudo setfacl -m u:runner:rwx /dev/kvm
- name: Login to Quay Registry
uses: docker/login-action@c99871dec2022cc055c062a10cc1a1310835ceb4 # v4
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
- name: Download artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: kairos-${{ steps.split.outputs.flavor }}-${{ steps.split.outputs.flavor_release }}-${{ matrix.variant }}-${{ matrix.arch }}-${{ matrix.model }}-uki.iso.zip
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
with:
driver-opts: network=host
- name: Build uki upgrade image 🔧
run: |
echo "Building upgrade image for generic test"
docker buildx build --load -t upgrade-image - <<EOF
FROM quay.io/kairos/ci-temp-images:${{ steps.split.outputs.flavor }}-${{ steps.split.outputs.flavor_release }}-${{ matrix.variant }}-${{ matrix.arch }}-${{ matrix.model }}-${{ github.sha }}-uki
RUN echo "Current release info: \$(cat /etc/kairos-release)"
RUN sed -i 's/^KAIROS_VERSION=.*/KAIROS_VERSION="mynewversion"/' /etc/kairos-release
RUN echo "New release info: \$(cat /etc/kairos-release)"
EOF
mkdir -p $PWD/build
docker run --rm --network=host -v /var/run/docker.sock:/var/run/docker.sock \
-v $PWD/build:/result \
-v $PWD/tests/assets/keys:/keys \
quay.io/kairos/auroraboot:v0.26.2 --debug build-uki \
--output-dir /result --output-type container \
--public-keys /keys \
--tpm-pcr-private-key /keys/tpm2-pcr-private.pem \
--sb-key /keys/db.key --sb-cert /keys/db.pem \
docker:upgrade-image
image=$(docker load -i build/*.tar | grep "Loaded image" | awk -F: '{ st = index($0,":");print substr($0,st+1)}' | sed 's/+/-/g' | xargs)
echo "Image: $image"
rand=$(head /dev/urandom | tr -dc a-z0-9 | head -c 7)
temp_image=quay.io/kairos/ci-temp-images:$(echo $image | sed "s/:latest/-${rand}/")
# Use docker build with DOCKER_BUILDKIT=1 instead of buildx for this simple label addition
# since buildx doesn't have access to locally loaded images from docker load
DOCKER_BUILDKIT=1 docker build --label quay.expires-after="6h" --tag $temp_image - <<EOF
FROM $image
EOF
docker push $temp_image
echo $temp_image > build/upgrade_image_name
- name: Find OVMF firmware
uses: ./.github/actions/find-ovmf-firmware
with:
prefer_secboot: true
id: find_ovmf
- name: Run tests 🔧
env:
MEMORY: 6000
CPUS: 4
FIRMWARE: ${{ steps.find_ovmf.outputs.firmware }}
UKI_TEST: true
run: |
mv $PWD/kairos-*-uki.iso $PWD/build/
export ISO=$(ls $PWD/build/kairos-*-uki.iso)
export UPGRADE_IMAGE=$(cat "${PWD}/build/upgrade_image_name")
export EXPECTED_NEW_VERSION="mynewversion"
export EXPECTED_SINGLE_ENTRY="testentry"
cp tests/go.* .
go run github.com/onsi/ginkgo/v2/ginkgo -v --label-filter "generic" --fail-fast -r ./tests/
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: failure()
with:
name: ${{ steps.split.outputs.flavor }}-${{ steps.split.outputs.flavor_release }}-${{ matrix.variant }}-generic-uki.logs.zip
path: tests/**/logs/*
if-no-files-found: warn
test_boot_assessment:
name: test_boot_assessment (${{ matrix.image_label }}, ${{ matrix.arch }}, ${{ matrix.model }}, ${{ matrix.variant }})
needs: build
runs-on: kvm
strategy:
fail-fast: false
matrix:
image_label: ["hadron-trusted"]
base_image:
- "ghcr.io/kairos-io/hadron-trusted:v0.5.1"
arch: ["amd64"]
model: ["generic"]
variant: ["core"]
steps:
- name: Split base image
id: split
run: |
# Split base image for tag generation
BASE_IMAGE=$(echo "${{ matrix.base_image }}" | cut -d ':' -f 1)
BASE_TAG=$(echo "${{ matrix.base_image }}" | cut -d ':' -f 2 || echo 'latest')
# Handle special cases for base images with slashes
# Handle base images with slashes (registry paths)
# Examples:
# - ubuntu:24.04 -> FLAVOR=ubuntu, FLAVOR_RELEASE=24.04
# - opensuse/leap:15.6 -> FLAVOR=opensuse, FLAVOR_RELEASE=leap-15.6
# - ghcr.io/kairos-io/hadron:main -> FLAVOR=hadron, FLAVOR_RELEASE=main
if [[ "$BASE_IMAGE" == *"/"* ]]; then
DISTRO=$(echo "$BASE_IMAGE" | cut -d '/' -f 1)
SUB_DISTRO=$(echo "$BASE_IMAGE" | cut -d '/' -f 2)
FLAVOR="$DISTRO"
FLAVOR_RELEASE="$SUB_DISTRO-$BASE_TAG"
# Count number of slashes to determine if it's a registry path
SLASH_COUNT=$(echo "$BASE_IMAGE" | tr -cd '/' | wc -c)
if [[ $SLASH_COUNT -eq 1 ]]; then
# Simple case: distro/subdistro (preserve existing behavior)
DISTRO=$(echo "$BASE_IMAGE" | cut -d '/' -f 1)
SUB_DISTRO=$(echo "$BASE_IMAGE" | cut -d '/' -f 2)
FLAVOR="$DISTRO"
FLAVOR_RELEASE="$SUB_DISTRO-$BASE_TAG"
else
# Registry path with multiple slashes: extract last component as FLAVOR
# e.g., ghcr.io/kairos-io/hadron -> FLAVOR=hadron
FLAVOR=$(echo "$BASE_IMAGE" | awk -F'/' '{print $NF}')
FLAVOR_RELEASE="$BASE_TAG"
fi
else
# No slashes: simple image name
FLAVOR="$BASE_IMAGE"
FLAVOR_RELEASE="$BASE_TAG"
fi
echo "Base Image: $BASE_IMAGE"
echo "Determined Flavor: $FLAVOR"
echo "Determined Flavor Release: $FLAVOR_RELEASE"
echo "flavor=$FLAVOR" >> $GITHUB_OUTPUT
echo "flavor_release=$FLAVOR_RELEASE" >> $GITHUB_OUTPUT
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: '0'
- name: Set Version
run: echo "VERSION=$(git describe --tags --dirty )" >> $GITHUB_ENV
- name: Install Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
timeout-minutes: 5
with:
go-version-file: tests/go.mod
cache-dependency-path: tests/go.sum
cache: ${{ runner.environment == 'self-hosted' && 'false' || 'true' }}
- name: Enable KVM group perms and install deps
run: |
sudo apt-get update
sudo apt-get install -y libvirt-clients libvirt-daemon-system libvirt-daemon virtinst bridge-utils qemu-system-x86 qemu-utils acl udev mkisofs swtpm ovmf
# https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/
# echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
# sudo udevadm control --reload-rules
# sudo udevadm trigger --name-match=kvm
# sudo usermod -a -G kvm,libvirt $USER
#
# TODO: Switch back to the above solution when we switch to the github runners
# https://askubuntu.com/a/1081326
sudo setfacl -m u:runner:rwx /dev/kvm
- name: Login to Quay Registry
uses: docker/login-action@c99871dec2022cc055c062a10cc1a1310835ceb4 # v4
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
- name: Download artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: kairos-${{ steps.split.outputs.flavor }}-${{ steps.split.outputs.flavor_release }}-${{ matrix.variant }}-${{ matrix.arch }}-${{ matrix.model }}-uki.iso.zip
- name: Find OVMF firmware
uses: ./.github/actions/find-ovmf-firmware
with:
prefer_secboot: true
id: find_ovmf_boot
- name: Run tests 🔧
env:
MEMORY: 6000
CPUS: 4
FIRMWARE: ${{ steps.find_ovmf_boot.outputs.firmware }}
UKI_TEST: true
run: |
mkdir -p $PWD/build
mv $PWD/kairos-*-uki.iso $PWD/build/
export ISO=$(ls $PWD/build/kairos-*-uki.iso)
cp tests/go.* .
go run github.com/onsi/ginkgo/v2/ginkgo -v --label-filter "boot-assessment" --fail-fast -r ./tests/
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: failure()
with:
name: ${{ steps.split.outputs.flavor }}-${{ steps.split.outputs.flavor_release }}-${{ inputs.variant }}-generic-uki.logs.zip
path: tests/**/logs/*
if-no-files-found: warn