Skip to content

Publish GardenLinux New OCI Image with UKI #47

Publish GardenLinux New OCI Image with UKI

Publish GardenLinux New OCI Image with UKI #47

name: Publish GardenLinux New OCI Image with UKI
on:
workflow_dispatch:
inputs:
version:
description: "Specify the GardenLinux version (e.g., 1877.0)"
required: true
jobs:
publish:
runs-on: ubuntu-latest
env:
VERSION: ${{ github.event.inputs.version }}
GITHUB_TOKEN: ${{ secrets.GHCR_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Dependencies and Build ukify + stub
run: |
sudo apt-get update -qq
sudo apt-get install -y \
jq curl git make meson ninja-build gperf \
python3-pip python3-pyelftools \
libssl-dev liblz4-dev libzstd-dev libacl1-dev \
libblkid-dev libkmod-dev libmount-dev libpam0g-dev \
libcryptsetup-dev libaudit-dev libmicrohttpd-dev \
libcap-dev pkg-config uuid-dev \
libefivar-dev gnu-efi
sudo pip3 install pefile
git clone --depth=1 --branch v256 https://github.com/systemd/systemd.git
cd systemd
meson setup build
ninja -C build
sudo cp build/ukify /usr/local/bin/ukify
sudo mkdir -p /usr/lib/systemd/boot/efi
sudo cp build/src/boot/efi/linuxx64.efi.stub /usr/lib/systemd/boot/efi/
- name: Setup ORAS
uses: oras-project/setup-oras@v1
- name: Authenticate with GHCR
run: |
echo "$GITHUB_TOKEN" | oras login ghcr.io -u github --password-stdin
echo "$GITHUB_TOKEN" | docker login ghcr.io -u ${GITHUB_ACTOR} --password-stdin
- name: Clone Ironcore Image Repo
run: |
git clone https://x-access-token:${GITHUB_TOKEN}@github.com/ironcore-dev/ironcore-image.git
- name: Build and Push OCI Images (Vanilla/Gardener/CAPI)
run: |
set -euo pipefail
cd ironcore-image
make build
for VARIANT in vanilla gardener capi; do
echo "Starting build for variant: $VARIANT"
case "$VARIANT" in
vanilla)
IMAGE_NAME="ghcr.io/ironcore-dev/os-images/gardenlinux"
CNAME_PREFIX="metal_pxe"
;;
gardener)
IMAGE_NAME="ghcr.io/ironcore-dev/os-images/gardener/gardenlinux"
CNAME_PREFIX="metal-gardener_pxe"
;;
capi)
IMAGE_NAME="ghcr.io/ironcore-dev/os-images/capi/gardenlinux"
CNAME_PREFIX="metal-capi"
;;
esac
mkdir -p ../binaries/amd64 ../binaries/arm64
for ARCH in amd64 arm64; do
echo "Fetching layer for $VARIANT $ARCH"
INDEX_JSON=$(oras manifest fetch ghcr.io/gardenlinux/gardenlinux:$VERSION)
echo "$INDEX_JSON" | jq . > index-${ARCH}.json
DIGEST=$(jq -r --arg arch "$ARCH" --arg prefix "$CNAME_PREFIX" \
'.manifests[] | select(.platform.architecture == $arch and ((.annotations.cname? // "") | tostring | startswith($prefix))) | .digest' index-${ARCH}.json)
echo "Found digest: $DIGEST"
oras manifest fetch ghcr.io/gardenlinux/gardenlinux@$DIGEST > manifest-${ARCH}.json
for BIN in initrd vmlinuz root.squashfs; do
DIGEST_BIN=$(jq -r --arg bin "$BIN" '.layers[] | select(.annotations."org.opencontainers.image.title" == $bin).digest' manifest-${ARCH}.json)
oras blob fetch ghcr.io/gardenlinux/gardenlinux@$DIGEST_BIN -o ../binaries/$ARCH/$BIN
done
done
echo "First build (without UKI)"
./bin/ironcore-image build \
--tag $IMAGE_NAME:$VERSION \
--config arch=amd64,squashfs=../binaries/amd64/root.squashfs,initramfs=../binaries/amd64/initrd,kernel=../binaries/amd64/vmlinuz \
--config arch=arm64,squashfs=../binaries/arm64/root.squashfs,initramfs=../binaries/arm64/initrd,kernel=../binaries/arm64/vmlinuz
echo "Inspecting squashfs digest for cmdline"
for ARCH in amd64 arm64; do
REF_TAG="${VERSION}"
DIGEST=$(./bin/ironcore-image inspect $IMAGE_NAME:$REF_TAG \
| jq -r '.manifest.layers[] | select(.mediaType == "application/vnd.ironcore.image.squashfs").digest')
CMDLINE="initrd=initrd gl.ovl=/:tmpfs gl.live=1 ip=any console=ttyS0,115200 console=tty0 earlyprintk=ttyS0,115200 consoleblank=0 ignition.firstboot=1 ignition.config.url=http://boot-operator-service.boot-operator-system.svc.cluster.local:8083/ignition ignition.config.url.append.uuid=true ignition.platform.id=metal gl.url=http://boot-operator-service.boot-operator-system.svc.cluster.local:8083/image?imageName=$IMAGE_NAME&version=${VERSION}&layerDigest=${DIGEST}"
echo "Building UKI for $ARCH with squashfs digest $DIGEST"
ukify build \
--linux ../binaries/$ARCH/vmlinuz \
--initrd ../binaries/$ARCH/initrd \
--stub /usr/lib/systemd/boot/efi/linuxx64.efi.stub \
--cmdline "$CMDLINE" \
--output ../binaries/$ARCH/uki.img
done
echo "Final image build with UKI for $VARIANT"
./bin/ironcore-image build \
--tag $IMAGE_NAME:$VERSION \
--config arch=amd64,squashfs=../binaries/amd64/root.squashfs,initramfs=../binaries/amd64/initrd,kernel=../binaries/amd64/vmlinuz,uki=../binaries/amd64/uki.img \
--config arch=arm64,squashfs=../binaries/arm64/root.squashfs,initramfs=../binaries/arm64/initrd,kernel=../binaries/arm64/vmlinuz,uki=../binaries/arm64/uki.img
echo "Pushing final image with UKI: $IMAGE_NAME:$VERSION"
./bin/ironcore-image push $IMAGE_NAME:$VERSION --push-sub-manifests
echo "Finished $VARIANT"
done