Files
securityonion/salt/common/tools/sbin/so-kernel-upgrade
T
Mike Reeves 5fd5df54b4 Install UEK8 in so-kernel-upgrade when no UEK kernel is present
The script assumed the UEK8 kernel was already installed and only switched
the boot default to it. On a node running the EL9 stock kernel (RHCK 5.14)
there is no kernel-uek* package at all, so `dnf update` has nothing to
upgrade and UEK8 never lands -- the script just logged "nothing to do" and
exited 0.

When no 6.x UEK boot entry exists, install the kernel-uek metapackage (it
pulls kernel-uek-core plus the module subpackages, including
kernel-uek-modules-extra-netfilter) and then proceed with the grubby
switch. Fail loudly if securityonionkernel is not an enabled repo, since
that assignment is gated on the NIC-pin marker and the salt version match
and a silent no-op there is hard to diagnose.

Also point DEFAULTKERNEL at kernel-uek-core so later kernel updates stay on
the UEK line rather than falling back to RHCK.

Still idempotent and still never reboots.
2026-07-09 13:47:50 -04:00

99 lines
4.5 KiB
Bash
Executable File

#!/bin/bash
#
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.
#
# so-kernel-upgrade — install the UEK8 (6.x) kernel if needed and make it the boot default.
#
# Security Onion is moving off the EL9 stock kernel (RHCK, 5.14) / UEK7 (5.15) onto UEK8 (6.x).
# Two separate things have to happen, and neither is automatic:
#
# 1. Install it. A node running RHCK has no kernel-uek* package at all, so 'dnf update'
# never pulls UEK8 in — there is nothing to upgrade. The kernel-uek metapackage has to
# be installed explicitly from the securityonionkernel repo.
# 2. Boot it. Installing kernel-uek-core adds a UEK8 boot entry but does NOT make it the
# default: kernel-install/grubby only auto-promote a new kernel within the running
# kernel's flavor lineage, and we're crossing from a 5.x kernel to the new 6.x UEK
# flavor. So even with UPDATEDEFAULT=yes and DEFAULTKERNEL=kernel-uek-core the box
# keeps booting the old kernel until grubby is told otherwise.
#
# This tool does both, then points DEFAULTKERNEL at kernel-uek-core so later kernel updates
# stay on the UEK line.
#
# Idempotent: an already-installed, already-default UEK8 kernel is left alone. It only sets
# the boot default; it does NOT reboot — the admin reboots the node on their own schedule.
KERNEL_REPO="securityonionkernel"
KERNEL_PKG="kernel-uek"
log() { echo "[so-kernel-upgrade] $*"; }
[ "$(id -u)" -eq 0 ] || { log "must run as root"; exit 1; }
command -v grubby >/dev/null 2>&1 || { log "grubby not found"; exit 1; }
command -v dnf >/dev/null 2>&1 || { log "dnf not found"; exit 1; }
# Newest installed UEK8 (6.x) kernel known to the bootloader. UEK8 vmlinuz paths look like
# /boot/vmlinuz-6.12.0-203.76.7.5.el9uek.x86_64; the 5.15 UEK7 and 5.14 RHCK won't match.
find_uek8() {
grubby --info=ALL 2>/dev/null \
| sed -n 's/^kernel="\(.*\)"$/\1/p' \
| grep -E '/vmlinuz-6\.[0-9]+.*uek' \
| sort -V | tail -1
}
target="$(find_uek8)"
if [ -z "$target" ]; then
log "no UEK8 kernel installed — installing $KERNEL_PKG from $KERNEL_REPO"
# The repo is assigned by the repo.client highstate, and only once NICs are pinned by MAC
# (/opt/so/state/nic_names_pinned) so the kernel swap can't renumber interfaces SO binds
# by name. Without the repo we'd silently pull nothing, so fail loudly instead.
if ! dnf -q repolist --enabled 2>/dev/null | awk '{print $1}' | grep -qx "$KERNEL_REPO"; then
log "ERROR: repo '$KERNEL_REPO' is not enabled on this node."
log "Run a highstate first; it is skipped until /opt/so/state/nic_names_pinned exists"
log "(run so-nic-pin) and this node's salt matches the version this release ships."
exit 1
fi
dnf -y install "$KERNEL_PKG" || { log "ERROR: failed to install $KERNEL_PKG"; exit 1; }
target="$(find_uek8)"
if [ -z "$target" ]; then
log "ERROR: $KERNEL_PKG installed but no 6.x UEK boot entry appeared — check 'grubby --info=ALL'"
exit 1
fi
log "installed UEK8 kernel: $target"
fi
# Keep future kernel updates on the UEK line rather than falling back to RHCK. Oracle ships
# this file; only rewrite it when it's actually pointing somewhere else.
if [ -f /etc/sysconfig/kernel ] && ! grep -q '^DEFAULTKERNEL=kernel-uek-core$' /etc/sysconfig/kernel; then
log "setting DEFAULTKERNEL=kernel-uek-core in /etc/sysconfig/kernel"
sed -i 's/^DEFAULTKERNEL=.*/DEFAULTKERNEL=kernel-uek-core/' /etc/sysconfig/kernel
fi
current="$(grubby --default-kernel 2>/dev/null)"
if [ "$current" = "$target" ]; then
log "UEK8 kernel is already the boot default: $target"
[ "$(uname -r)" = "$(basename "$target" | sed 's/^vmlinuz-//')" ] \
|| log "REBOOT REQUIRED to start using it (currently running $(uname -r))."
exit 0
fi
log "current default kernel: ${current:-unknown}"
log "switching boot default to UEK8 kernel: $target"
grubby --set-default="$target" || { log "ERROR: grubby --set-default failed for $target"; exit 1; }
# Verify the change actually took before claiming success.
now="$(grubby --default-kernel 2>/dev/null)"
if [ "$now" != "$target" ]; then
log "ERROR: default kernel is still '${now:-unknown}' after set-default"
exit 1
fi
log "boot default is now $target"
log "REBOOT REQUIRED to start using the UEK8 kernel (currently running $(uname -r))."