Files
scoutfs-build/ci/cache-kernels.sh
William Gill f36e06f545 Switch to self-hosted runner with cached incremental builds
Replaces the ephemeral EL8/EL9/watch-kernels workflows with a single
ScoutFS CI workflow that runs on a self-hosted Gitea Act Runner using
pre-baked builder images and a persistent /var/cache/scoutfs-ci volume.
cache-kernels.sh downloads only new kernel-devel RPMs and diffs against
the Gitea manifest so each run only builds kernels that aren't already
published, dramatically reducing run time for the common case.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 21:55:05 -05:00

97 lines
3.2 KiB
Bash

#!/bin/bash
# Populate the persistent kernel-devel RPM cache and compute the list
# of kernels that still need a ScoutFS kmod build.
#
# Reads:
# /var/cache/scoutfs/el${EL}/kernel-devel/*.rpm (persistent cache)
# Gitea manifest scoutfs-built-kernels/el${EL}/manifest.txt (already-built list)
#
# Writes:
# output/kernels-to-build.txt (one KVER per line, empty if nothing to do)
# /usr/src/kernels/${KVER}/ (installed headers, via rpm -ivh --force --nodeps)
set -euo pipefail
WORK_DIR="$(pwd)"
OUTPUT_DIR="${WORK_DIR}/output"
mkdir -p "${OUTPUT_DIR}"
source /etc/os-release
EL_VERSION="${VERSION_ID%%.*}"
CACHE_ROOT="${SCOUTFS_CACHE_ROOT:-/var/cache/scoutfs}"
CACHE_DIR="${CACHE_ROOT}/el${EL_VERSION}/kernel-devel"
mkdir -p "${CACHE_DIR}"
echo ">>> Kernel cache dir: ${CACHE_DIR}"
# 1. Refresh dnf metadata and list all available kernel-devel versions.
echo ">>> Refreshing dnf metadata..."
dnf -q makecache >/dev/null 2>&1 || true
ALL_KDEV_VERSIONS=$(dnf list --showduplicates kernel-devel 2>/dev/null \
| awk '/kernel-devel/ {print $2}' | sort -V | uniq)
if [[ -z "${ALL_KDEV_VERSIONS}" ]]; then
echo "ERROR: No kernel-devel packages found in configured repos"
exit 1
fi
echo ">>> Available kernel-devel versions:"
echo "${ALL_KDEV_VERSIONS}"
# 2. Download any versions not already cached.
for KVER in ${ALL_KDEV_VERSIONS}; do
# RPM file name format: kernel-devel-${KVER}.rpm (KVER already contains arch)
RPM_GLOB="${CACHE_DIR}/kernel-devel-${KVER}.rpm"
if compgen -G "${RPM_GLOB}" >/dev/null; then
continue
fi
echo ">>> Downloading kernel-devel-${KVER}..."
dnf download --destdir="${CACHE_DIR}" "kernel-devel-${KVER}" 2>&1 \
| grep -v '^$' || true
done
echo ">>> Cached kernel-devel RPMs:"
ls -1 "${CACHE_DIR}" || true
# 3. Install every cached RPM into the ephemeral container rootfs so
# /usr/src/kernels/${KVER}/ is populated for rpmbuild.
if compgen -G "${CACHE_DIR}/*.rpm" >/dev/null; then
echo ">>> Installing cached kernel-devel RPMs..."
rpm -ivh --force --nodeps "${CACHE_DIR}"/*.rpm 2>&1 \
| tail -20 || true
fi
# 4. Download the Gitea manifest of already-built kernels.
BUILT_KERNELS=""
if [[ -n "${GITEA_URL:-}" && -n "${GITEA_TOKEN:-}" && -n "${REPO_OWNER:-}" ]]; then
MANIFEST_URL="${GITEA_URL}/api/packages/${REPO_OWNER}/generic/scoutfs-built-kernels/el${EL_VERSION}/manifest.txt"
echo ">>> Fetching built-kernel manifest: ${MANIFEST_URL}"
BUILT_KERNELS=$(curl -sf \
-H "Authorization: token ${GITEA_TOKEN}" \
"${MANIFEST_URL}" 2>/dev/null || echo "")
else
echo ">>> Gitea env not set; treating all kernels as unbuilt"
fi
echo ">>> Already-built kernels:"
echo "${BUILT_KERNELS:- (none)}"
# 5. Diff: available kernels present in /usr/src/kernels that are NOT in the manifest.
TO_BUILD_FILE="${OUTPUT_DIR}/kernels-to-build.txt"
: > "${TO_BUILD_FILE}"
for KSRC in /usr/src/kernels/*/; do
[[ -d "${KSRC}" ]] || continue
KVER=$(basename "${KSRC}")
if echo "${BUILT_KERNELS}" | grep -qFx "${KVER}" 2>/dev/null; then
echo " skip (already built): ${KVER}"
else
echo " build: ${KVER}"
echo "${KVER}" >> "${TO_BUILD_FILE}"
fi
done
COUNT=$(wc -l < "${TO_BUILD_FILE}" | tr -d ' ')
echo ">>> ${COUNT} kernel(s) queued for build"