contrib/umber: fix pin_kernel rpm -qf and non-RPM kernels

- Only parse rpm -qf output on success; drop || true that fed error text to versionlock.

- Warn when vmlinuz/modules are not RPM-owned (e.g. make install); README notes.

Made-with: Cursor
This commit is contained in:
Robert McMahon 2026-03-31 15:54:06 -07:00
parent 9bec11eed5
commit ef016695c6
2 changed files with 40 additions and 16 deletions

View File

@ -9,12 +9,17 @@ Fedora-only helper to **pin the kernel you are currently running**: DNF excludes
to keep. Intended as a **manual, one-time (per policy) setup** on lab or edge
hosts—not invoked automatically by the build.
- **How:** `sudo ./contrib/umber/pin_kernel.sh` from a checkout (or copy the
script anywhere); must be root.
script anywhere); must be root. Versionlock targets are discovered with
`rpm -qf` on `/boot/vmlinuz-$(uname -r)` and `/lib/modules/$(uname -r)` so
custom release strings (e.g. `umber.v9`) match real Fedora NEVRAs.
- **Caveats:** Replaces a single `excludepkgs=` line in `/etc/dnf/dnf.conf` if one
already exists. The default list includes `kmod-*,akmod-*`, which blocks updates
to those packages; edit the script if you still want `dnf` to refresh other kmods.
- **Undo:** Narrow or remove `excludepkgs` in `dnf.conf`; run
`dnf versionlock list` and `dnf versionlock delete <entry>` for locked packages.
Requires: Fedora DNF, `grubby`, RPM-based kernel package names matching
`kernel-$(uname -r)`, etc.
Requires: Fedora DNF, `grubby`. **Versionlock** only applies when
`/boot/vmlinuz-$(uname -r)` and `/lib/modules/$(uname -r)` are owned by RPM
(e.g. `dnf install ./kernel-*.rpm`). Kernels installed with **`make install`**
are not in the RPM DB — the script still sets **excludepkgs** and GRUB, but
cannot add versionlock entries until you use RPM-packaged builds.

41
contrib/umber/pin_kernel.sh Normal file → Executable file
View File

@ -45,29 +45,48 @@ grep '^excludepkgs=' "${DNF_CONF}" || true
info "Installing python3-dnf-plugin-versionlock ..."
dnf install -y python3-dnf-plugin-versionlock
info "Locking installed kernel packages for ${CURRENT_KERNEL} ..."
for suffix in kernel kernel-core kernel-modules; do
pattern="${suffix}-${CURRENT_KERNEL}"
if ! nevra=$(rpm -q "${pattern}" 2>/dev/null); then
warn " Not installed: ${pattern}"
continue
# uname -r (e.g. 6.18.16-umber.v9) is NOT the RPM NEVRA (release has .fcNN, epoch, arch).
# Resolve packages that own the running kernel image and module tree.
VMLINUZ="/boot/vmlinuz-${CURRENT_KERNEL}"
MODDIR="/lib/modules/${CURRENT_KERNEL}"
info "Locking RPM packages that own this kernel (rpm -qf) ..."
declare -A LOCK_PKGS=()
for path in "${VMLINUZ}" "${MODDIR}"; do
[[ -e "${path}" ]] || continue
# Do not use `|| true` here: rpm prints "not owned by any package" on stdout
# and exits non-zero; we must only parse output when rpm succeeds.
if out=$(rpm -qf "${path}" 2>/dev/null); then
while IFS= read -r nevra; do
[[ -n "${nevra}" ]] || continue
case "${nevra}" in
*"not owned"*) continue ;;
esac
LOCK_PKGS[${nevra}]=1
done <<< "${out}"
else
warn " Not owned by any RPM: ${path}"
fi
done
if [[ ${#LOCK_PKGS[@]} -eq 0 ]]; then
warn "No RPM-owned vmlinuz/modules — typical of \`make install\` / manual kernel."
warn "excludepkgs in dnf.conf still limits DNF; use RPM-built kernels for versionlock."
else
while IFS= read -r nevra; do
[[ -n "${nevra}" ]] || continue
if dnf versionlock add "${nevra}"; then
info " Locked: ${nevra}"
else
warn " versionlock add failed for ${nevra} (may already be locked)"
fi
done
if rpm -q kernel &>/dev/null; then
dnf versionlock add kernel && info " Locked: kernel (meta)" || true
done < <(printf '%s\n' "${!LOCK_PKGS[@]}" | sort)
fi
info "Checking GRUB default ..."
DEFAULT_KERNEL=$(grubby --default-kernel 2>/dev/null || echo "unknown")
info " grubby default: ${DEFAULT_KERNEL}"
VMLINUZ="/boot/vmlinuz-${CURRENT_KERNEL}"
if [[ -f "${VMLINUZ}" ]]; then
if [[ "${DEFAULT_KERNEL}" != "${VMLINUZ}" ]]; then
warn "Default differs from running kernel — grubby --set-default ..."