From 698a746d6da370f41ca7f18637b53d1c368a6bf1 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 23 Jun 2026 13:19:56 -0400 Subject: [PATCH 1/5] Add UEK8 kernel repo support across install and grid Mirror the kernel repo to full parity with the main package repo so the grid can pull the Oracle UEK8 kernel: - setup/so-functions: securityonion_repo() emits a [securityonionkernel] section in every branch (mirrorlist on non-airgap, https://$MSRV/kernelrepo for airgap/minion, file:///nsm/kernelrepo/ for manager); repo_sync_local() and create_repo() sync and build /nsm/kernelrepo. - manager/init.sls: create /nsm/kernelrepo and deploy mirror-kernel.txt. - nginx/enabled.sls: serve /nsm/kernelrepo at https:///kernelrepo. - repo/client/oracle.sls: add so_kernel_repo, gated by onlyif test -e /opt/so/state/nic_names_pinned so the kernel repo is only assigned once NICs are pinned by MAC. - update_packages(): run so-nic-pin before the dnf update that pulls the kernel, freezing interface names and dropping the pin marker so the kernel isn't downgraded then re-upgraded on the first highstate. --- salt/manager/files/mirror-kernel.txt | 2 ++ salt/manager/files/repodownload.conf | 7 ++++- salt/manager/init.sls | 17 ++++++++++++ salt/manager/tools/sbin/so-repo-sync | 4 +++ salt/nginx/enabled.sls | 1 + salt/repo/client/oracle.sls | 16 +++++++++++ setup/so-functions | 41 ++++++++++++++++++++++++++++ 7 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 salt/manager/files/mirror-kernel.txt diff --git a/salt/manager/files/mirror-kernel.txt b/salt/manager/files/mirror-kernel.txt new file mode 100644 index 000000000..1d9ce75d2 --- /dev/null +++ b/salt/manager/files/mirror-kernel.txt @@ -0,0 +1,2 @@ +https://repo.securityonion.net/file/so-repo/prod/3/oracle/9-uek8 +https://repo-alt.securityonion.net/prod/3/oracle/9-uek8 diff --git a/salt/manager/files/repodownload.conf b/salt/manager/files/repodownload.conf index 3c156a9db..67ae4b121 100644 --- a/salt/manager/files/repodownload.conf +++ b/salt/manager/files/repodownload.conf @@ -10,4 +10,9 @@ keepcache=0 name=Security Onion Repo repo mirrorlist=file:///opt/so/conf/reposync/mirror.txt enabled=1 -gpgcheck=1 \ No newline at end of file +gpgcheck=1 +[securityonionkernel] +name=Security Onion Repo repo +mirrorlist=file:///opt/so/conf/reposync/mirror-kernel.txt +enabled=1 +gpgcheck=1 diff --git a/salt/manager/init.sls b/salt/manager/init.sls index 2353bb64b..d6c154efa 100644 --- a/salt/manager/init.sls +++ b/salt/manager/init.sls @@ -86,6 +86,16 @@ repo_dir: - group - show_changes: False +kernelrepo_dir: + file.directory: + - name: /nsm/kernelrepo + - user: socore + - group: socore + - recurse: + - user + - group + - show_changes: False + manager_sbin: file.recurse: - name: /usr/sbin @@ -122,6 +132,13 @@ so-repo-mirrorlist: - user: socore - group: socore +so-repo-kernel-mirrorlist: + file.managed: + - name: /opt/so/conf/reposync/mirror-kernel.txt + - source: salt://manager/files/mirror-kernel.txt + - user: socore + - group: socore + so-repo-sync: {% if MANAGERMERGED.reposync.enabled %} cron.present: diff --git a/salt/manager/tools/sbin/so-repo-sync b/salt/manager/tools/sbin/so-repo-sync index a0393a36b..bc90122d3 100755 --- a/salt/manager/tools/sbin/so-repo-sync +++ b/salt/manager/tools/sbin/so-repo-sync @@ -10,5 +10,9 @@ NOROOT=1 set -e curl --retry 5 --retry-delay 60 -A "reposync/$(sync_options)" https://sigs.securityonion.net/checkup --output /tmp/checkup + dnf reposync --norepopath -g --delete -m -c /opt/so/conf/reposync/repodownload.conf --repoid=securityonionsync --download-metadata -p /nsm/repo/ createrepo /nsm/repo + +dnf reposync --norepopath -g --delete -m -c /opt/so/conf/reposync/repodownload.conf --repoid=securityonionkernel --download-metadata -p /nsm/kernelrepo/ +createrepo /nsm/kernelrepo diff --git a/salt/nginx/enabled.sls b/salt/nginx/enabled.sls index 2e4c9631c..40fde5b0e 100644 --- a/salt/nginx/enabled.sls +++ b/salt/nginx/enabled.sls @@ -59,6 +59,7 @@ so-nginx: - /opt/so/conf/navigator/layers/:/opt/socore/html/navigator/assets/so:ro - /opt/so/conf/navigator/config.json:/opt/socore/html/navigator/assets/config.json:ro - /nsm/repo:/opt/socore/html/repo:ro + - /nsm/kernelrepo:/opt/socore/html/kernelrepo:ro - /nsm/rules:/nsm/rules:ro {% if NGINXMERGED.external_suricata %} - /opt/so/rules/nids/suri:/surirules:ro diff --git a/salt/repo/client/oracle.sls b/salt/repo/client/oracle.sls index 70f529830..8c8a1ac0a 100644 --- a/salt/repo/client/oracle.sls +++ b/salt/repo/client/oracle.sls @@ -57,6 +57,22 @@ so_repo: - enabled: 1 - gpgcheck: 1 +so_kernel_repo: + pkgrepo.managed: + - name: securityonionkernel + - humanname: Security Onion Kernel Repo + {% if GLOBALS.is_manager %} + - baseurl: file:///nsm/kernelrepo/ + {% else %} + - baseurl: https://{{ GLOBALS.repo_host }}/kernelrepo + {% endif %} + - enabled: 1 + - gpgcheck: 1 + # Only assign the kernel repo once physical NIC names are pinned by MAC, so the + # UEK8 kernel update can't renumber interfaces SO binds by name (see pin_nic_names + # in salt/common/init.sls, which drops this marker via /usr/sbin/so-nic-pin). + - onlyif: 'test -e /opt/so/state/nic_names_pinned' + {% endif %} # TODO: Add a pillar entry for custom repos diff --git a/setup/so-functions b/setup/so-functions index 2d5181dc1..e8f6eb742 100755 --- a/setup/so-functions +++ b/setup/so-functions @@ -886,6 +886,7 @@ create_repo() { title "Create the repo directory" logCmd "dnf -y install yum-utils createrepo_c" logCmd "createrepo /nsm/repo" + logCmd "createrepo /nsm/kernelrepo" } @@ -1812,6 +1813,13 @@ securityonion_repo() { echo "mirrorlist=file:///etc/yum/mirror.txt" >> /etc/yum.repos.d/securityonion.repo echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo + echo "https://repo.securityonion.net/file/so-repo/prod/3/oracle/9-uek8" > /etc/yum/mirror-kernel.txt + echo "https://so-repo-east.s3.us-east-005.backblazeb2.com/prod/3/oracle/9-uek8" >> /etc/yum/mirror-kernel.txt + echo "[securityonionkernel]" >> /etc/yum.repos.d/securityonion.repo + echo "name=Security Onion Kernel Repo repo" >> /etc/yum.repos.d/securityonion.repo + echo "mirrorlist=file:///etc/yum/mirror-kernel.txt" >> /etc/yum.repos.d/securityonion.repo + echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo + echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo logCmd "dnf repolist" else echo "[securityonion]" > /etc/yum.repos.d/securityonion.repo @@ -1820,6 +1828,12 @@ securityonion_repo() { echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo echo "sslverify=0" >> /etc/yum.repos.d/securityonion.repo + echo "[securityonionkernel]" >> /etc/yum.repos.d/securityonion.repo + echo "name=Security Onion Kernel Repo" >> /etc/yum.repos.d/securityonion.repo + echo "baseurl=https://$MSRV/kernelrepo" >> /etc/yum.repos.d/securityonion.repo + echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo + echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo + echo "sslverify=0" >> /etc/yum.repos.d/securityonion.repo logCmd "dnf repolist" fi elif [[ ! $waitforstate ]]; then @@ -1829,12 +1843,23 @@ securityonion_repo() { echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo echo "sslverify=0" >> /etc/yum.repos.d/securityonion.repo + echo "[securityonionkernel]" >> /etc/yum.repos.d/securityonion.repo + echo "name=Security Onion Kernel Repo" >> /etc/yum.repos.d/securityonion.repo + echo "baseurl=https://$MSRV/kernelrepo" >> /etc/yum.repos.d/securityonion.repo + echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo + echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo + echo "sslverify=0" >> /etc/yum.repos.d/securityonion.repo elif [[ $waitforstate ]]; then echo "[securityonion]" > /etc/yum.repos.d/securityonion.repo echo "name=Security Onion Repo" >> /etc/yum.repos.d/securityonion.repo echo "baseurl=file:///nsm/repo/" >> /etc/yum.repos.d/securityonion.repo echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo + echo "[securityonionkernel]" >> /etc/yum.repos.d/securityonion.repo + echo "name=Security Onion Kernel Repo" >> /etc/yum.repos.d/securityonion.repo + echo "baseurl=file:///nsm/kernelrepo/" >> /etc/yum.repos.d/securityonion.repo + echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo + echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo fi logCmd "dnf repolist all" if [[ $waitforstate ]]; then @@ -1850,9 +1875,12 @@ repo_sync_local() { # Sync the repo from the SO repo locally. info "Adding Repo Download Configuration" mkdir -p /nsm/repo + mkdir -p /nsm/kernelrepo mkdir -p /opt/so/conf/reposync/cache echo "https://repo.securityonion.net/file/so-repo/prod/3/oracle/9" > /opt/so/conf/reposync/mirror.txt echo "https://repo-alt.securityonion.net/prod/3/oracle/9" >> /opt/so/conf/reposync/mirror.txt + echo "https://repo.securityonion.net/file/so-repo/prod/3/oracle/9-uek8" > /opt/so/conf/reposync/mirror-kernel.txt + echo "https://repo-alt.securityonion.net/prod/3/oracle/9-uek8" >> /opt/so/conf/reposync/mirror-kernel.txt echo "[main]" > /opt/so/conf/reposync/repodownload.conf echo "gpgcheck=1" >> /opt/so/conf/reposync/repodownload.conf echo "installonly_limit=3" >> /opt/so/conf/reposync/repodownload.conf @@ -1866,12 +1894,18 @@ repo_sync_local() { echo "mirrorlist=file:///opt/so/conf/reposync/mirror.txt" >> /opt/so/conf/reposync/repodownload.conf echo "enabled=1" >> /opt/so/conf/reposync/repodownload.conf echo "gpgcheck=1" >> /opt/so/conf/reposync/repodownload.conf + echo "[securityonionkernel]" >> /opt/so/conf/reposync/repodownload.conf + echo "name=Security Onion Kernel Repo repo" >> /opt/so/conf/reposync/repodownload.conf + echo "mirrorlist=file:///opt/so/conf/reposync/mirror-kernel.txt" >> /opt/so/conf/reposync/repodownload.conf + echo "enabled=1" >> /opt/so/conf/reposync/repodownload.conf + echo "gpgcheck=1" >> /opt/so/conf/reposync/repodownload.conf logCmd "dnf repolist" if [[ ! $is_airgap ]]; then curl --retry 5 --retry-delay 60 -A "netinstall/$SOVERSION/$OS/$(uname -r)/1" https://sigs.securityonion.net/checkup --output /tmp/install retry 5 60 "dnf reposync --norepopath -g --delete -m -c /opt/so/conf/reposync/repodownload.conf --repoid=securityonionsync --download-metadata -p /nsm/repo/" >> "$setup_log" 2>&1 || fail_setup + retry 5 60 "dnf reposync --norepopath -g --delete -m -c /opt/so/conf/reposync/repodownload.conf --repoid=securityonionkernel --download-metadata -p /nsm/kernelrepo/" >> "$setup_log" 2>&1 || fail_setup # After the download is complete run createrepo create_repo fi @@ -2228,6 +2262,13 @@ update_sudoers_for_testing() { } update_packages() { + # Pin physical NIC names by MAC BEFORE pulling packages, so the UEK8 kernel that + # the update below installs can't renumber the interfaces SO binds by name. Doing + # it here (instead of waiting for the common highstate) also drops the + # /opt/so/state/nic_names_pinned marker that gates the kernel repo, so the kernel + # repo is assigned on the very first highstate and the kernel isn't downgraded and + # then re-upgraded. Run-once: so-nic-pin no-ops if the marker already exists. + logCmd "bash ../salt/common/tools/sbin/so-nic-pin" logCmd "dnf repolist" logCmd "dnf -y update --allowerasing --exclude=salt*,docker*,containerd*" RMREPOFILES=("oracle-linux-ol9.repo" "uek-ol9.repo" "virt-ol9.repo") From 8e2753aeb833de6581c4b1947e071ad9f4cf4e10 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Tue, 23 Jun 2026 13:53:14 -0400 Subject: [PATCH 2/5] Fix duplicate securityonionkernel repo definition The install bootstrap appended the [securityonionkernel] section to the shared /etc/yum.repos.d/securityonion.repo, but the salt state so_kernel_repo (name securityonionkernel) manages its own canonical file /etc/yum.repos.d/securityonionkernel.repo. At highstate both files defined the same repo id, so dnf failed with "repository securityonionkernel is listed more than 1 time". Write the bootstrap kernel repo to /etc/yum.repos.d/securityonionkernel.repo in all four securityonion_repo() branches so the id lives in exactly one file and salt edits it in place. Mirrors how the main repo's runtime id matches its file name. --- setup/so-functions | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/setup/so-functions b/setup/so-functions index e8f6eb742..15856d710 100755 --- a/setup/so-functions +++ b/setup/so-functions @@ -1815,11 +1815,11 @@ securityonion_repo() { echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo echo "https://repo.securityonion.net/file/so-repo/prod/3/oracle/9-uek8" > /etc/yum/mirror-kernel.txt echo "https://so-repo-east.s3.us-east-005.backblazeb2.com/prod/3/oracle/9-uek8" >> /etc/yum/mirror-kernel.txt - echo "[securityonionkernel]" >> /etc/yum.repos.d/securityonion.repo - echo "name=Security Onion Kernel Repo repo" >> /etc/yum.repos.d/securityonion.repo - echo "mirrorlist=file:///etc/yum/mirror-kernel.txt" >> /etc/yum.repos.d/securityonion.repo - echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo - echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo + echo "[securityonionkernel]" > /etc/yum.repos.d/securityonionkernel.repo + echo "name=Security Onion Kernel Repo repo" >> /etc/yum.repos.d/securityonionkernel.repo + echo "mirrorlist=file:///etc/yum/mirror-kernel.txt" >> /etc/yum.repos.d/securityonionkernel.repo + echo "enabled=1" >> /etc/yum.repos.d/securityonionkernel.repo + echo "gpgcheck=1" >> /etc/yum.repos.d/securityonionkernel.repo logCmd "dnf repolist" else echo "[securityonion]" > /etc/yum.repos.d/securityonion.repo @@ -1828,12 +1828,12 @@ securityonion_repo() { echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo echo "sslverify=0" >> /etc/yum.repos.d/securityonion.repo - echo "[securityonionkernel]" >> /etc/yum.repos.d/securityonion.repo - echo "name=Security Onion Kernel Repo" >> /etc/yum.repos.d/securityonion.repo - echo "baseurl=https://$MSRV/kernelrepo" >> /etc/yum.repos.d/securityonion.repo - echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo - echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo - echo "sslverify=0" >> /etc/yum.repos.d/securityonion.repo + echo "[securityonionkernel]" > /etc/yum.repos.d/securityonionkernel.repo + echo "name=Security Onion Kernel Repo" >> /etc/yum.repos.d/securityonionkernel.repo + echo "baseurl=https://$MSRV/kernelrepo" >> /etc/yum.repos.d/securityonionkernel.repo + echo "enabled=1" >> /etc/yum.repos.d/securityonionkernel.repo + echo "gpgcheck=1" >> /etc/yum.repos.d/securityonionkernel.repo + echo "sslverify=0" >> /etc/yum.repos.d/securityonionkernel.repo logCmd "dnf repolist" fi elif [[ ! $waitforstate ]]; then @@ -1843,23 +1843,23 @@ securityonion_repo() { echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo echo "sslverify=0" >> /etc/yum.repos.d/securityonion.repo - echo "[securityonionkernel]" >> /etc/yum.repos.d/securityonion.repo - echo "name=Security Onion Kernel Repo" >> /etc/yum.repos.d/securityonion.repo - echo "baseurl=https://$MSRV/kernelrepo" >> /etc/yum.repos.d/securityonion.repo - echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo - echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo - echo "sslverify=0" >> /etc/yum.repos.d/securityonion.repo + echo "[securityonionkernel]" > /etc/yum.repos.d/securityonionkernel.repo + echo "name=Security Onion Kernel Repo" >> /etc/yum.repos.d/securityonionkernel.repo + echo "baseurl=https://$MSRV/kernelrepo" >> /etc/yum.repos.d/securityonionkernel.repo + echo "enabled=1" >> /etc/yum.repos.d/securityonionkernel.repo + echo "gpgcheck=1" >> /etc/yum.repos.d/securityonionkernel.repo + echo "sslverify=0" >> /etc/yum.repos.d/securityonionkernel.repo elif [[ $waitforstate ]]; then echo "[securityonion]" > /etc/yum.repos.d/securityonion.repo echo "name=Security Onion Repo" >> /etc/yum.repos.d/securityonion.repo echo "baseurl=file:///nsm/repo/" >> /etc/yum.repos.d/securityonion.repo echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo - echo "[securityonionkernel]" >> /etc/yum.repos.d/securityonion.repo - echo "name=Security Onion Kernel Repo" >> /etc/yum.repos.d/securityonion.repo - echo "baseurl=file:///nsm/kernelrepo/" >> /etc/yum.repos.d/securityonion.repo - echo "enabled=1" >> /etc/yum.repos.d/securityonion.repo - echo "gpgcheck=1" >> /etc/yum.repos.d/securityonion.repo + echo "[securityonionkernel]" > /etc/yum.repos.d/securityonionkernel.repo + echo "name=Security Onion Kernel Repo" >> /etc/yum.repos.d/securityonionkernel.repo + echo "baseurl=file:///nsm/kernelrepo/" >> /etc/yum.repos.d/securityonionkernel.repo + echo "enabled=1" >> /etc/yum.repos.d/securityonionkernel.repo + echo "gpgcheck=1" >> /etc/yum.repos.d/securityonionkernel.repo fi logCmd "dnf repolist all" if [[ $waitforstate ]]; then From f45631af3ae03b4e684ac8327a8bdbeabe624356 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 24 Jun 2026 12:15:10 -0400 Subject: [PATCH 3/5] Guard kernel reposync on its config section existing During soup, so-repo-sync runs before the highstate deploys the new repodownload.conf. On the first upgrade to a kernel-aware version the on-disk config lacks the [securityonionkernel] section, so dnf aborts with "Unknown repo: 'securityonionkernel'" (set -e kills soup). Guard the kernel reposync on the section being present; the next sync after the highstate deploys it picks it up. --- salt/manager/tools/sbin/so-repo-sync | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/salt/manager/tools/sbin/so-repo-sync b/salt/manager/tools/sbin/so-repo-sync index bc90122d3..6c1b9d509 100755 --- a/salt/manager/tools/sbin/so-repo-sync +++ b/salt/manager/tools/sbin/so-repo-sync @@ -14,5 +14,12 @@ curl --retry 5 --retry-delay 60 -A "reposync/$(sync_options)" https://sigs.secur dnf reposync --norepopath -g --delete -m -c /opt/so/conf/reposync/repodownload.conf --repoid=securityonionsync --download-metadata -p /nsm/repo/ createrepo /nsm/repo -dnf reposync --norepopath -g --delete -m -c /opt/so/conf/reposync/repodownload.conf --repoid=securityonionkernel --download-metadata -p /nsm/kernelrepo/ -createrepo /nsm/kernelrepo +# The kernel repo section is deployed to repodownload.conf by the manager highstate, which +# runs AFTER this script during soup. On the first upgrade to a kernel-aware version the +# on-disk config still predates the section, so guard on its presence to avoid dnf's +# "Unknown repo: 'securityonionkernel'" aborting the sync (set -e). The next sync after the +# highstate deploys the section will pick it up. +if grep -q '^\[securityonionkernel\]' /opt/so/conf/reposync/repodownload.conf; then + dnf reposync --norepopath -g --delete -m -c /opt/so/conf/reposync/repodownload.conf --repoid=securityonionkernel --download-metadata -p /nsm/kernelrepo/ + createrepo /nsm/kernelrepo +fi From 27c1c35e62e90f6d11ae92817abda2a443ab992f Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 24 Jun 2026 13:20:10 -0400 Subject: [PATCH 4/5] Mark kernel repo skip_if_unavailable so an empty repo can't brick dnf When the kernel repo is assigned but /nsm/kernelrepo isn't populated yet, its missing repomd.xml makes every dnf/pkg operation fail (e.g. pkg.held for salt during highstate). The kernel repo is supplementary, so set skip_if_unavailable=1 in both the salt-managed client repo and the four install-time bootstrap repo files; dnf ignores it until it is populated instead of aborting. The main repo stays strict. --- salt/repo/client/oracle.sls | 4 ++++ setup/so-functions | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/salt/repo/client/oracle.sls b/salt/repo/client/oracle.sls index 8c8a1ac0a..2019a56d1 100644 --- a/salt/repo/client/oracle.sls +++ b/salt/repo/client/oracle.sls @@ -68,6 +68,10 @@ so_kernel_repo: {% endif %} - enabled: 1 - gpgcheck: 1 + # Supplementary kernel repo: tolerate it being empty/unreachable (e.g. before the + # manager has populated /nsm/kernelrepo) so a missing repomd.xml can't make every + # dnf/pkg operation on the grid fail. + - skip_if_unavailable: 1 # Only assign the kernel repo once physical NIC names are pinned by MAC, so the # UEK8 kernel update can't renumber interfaces SO binds by name (see pin_nic_names # in salt/common/init.sls, which drops this marker via /usr/sbin/so-nic-pin). diff --git a/setup/so-functions b/setup/so-functions index 15856d710..b9a061168 100755 --- a/setup/so-functions +++ b/setup/so-functions @@ -1820,6 +1820,9 @@ securityonion_repo() { echo "mirrorlist=file:///etc/yum/mirror-kernel.txt" >> /etc/yum.repos.d/securityonionkernel.repo echo "enabled=1" >> /etc/yum.repos.d/securityonionkernel.repo echo "gpgcheck=1" >> /etc/yum.repos.d/securityonionkernel.repo + # Supplementary kernel repo: tolerate it being empty/unreachable so a missing + # repomd.xml can't make every dnf operation fail before the repo is populated. + echo "skip_if_unavailable=1" >> /etc/yum.repos.d/securityonionkernel.repo logCmd "dnf repolist" else echo "[securityonion]" > /etc/yum.repos.d/securityonion.repo @@ -1834,6 +1837,7 @@ securityonion_repo() { echo "enabled=1" >> /etc/yum.repos.d/securityonionkernel.repo echo "gpgcheck=1" >> /etc/yum.repos.d/securityonionkernel.repo echo "sslverify=0" >> /etc/yum.repos.d/securityonionkernel.repo + echo "skip_if_unavailable=1" >> /etc/yum.repos.d/securityonionkernel.repo logCmd "dnf repolist" fi elif [[ ! $waitforstate ]]; then @@ -1849,6 +1853,7 @@ securityonion_repo() { echo "enabled=1" >> /etc/yum.repos.d/securityonionkernel.repo echo "gpgcheck=1" >> /etc/yum.repos.d/securityonionkernel.repo echo "sslverify=0" >> /etc/yum.repos.d/securityonionkernel.repo + echo "skip_if_unavailable=1" >> /etc/yum.repos.d/securityonionkernel.repo elif [[ $waitforstate ]]; then echo "[securityonion]" > /etc/yum.repos.d/securityonion.repo echo "name=Security Onion Repo" >> /etc/yum.repos.d/securityonion.repo @@ -1860,6 +1865,7 @@ securityonion_repo() { echo "baseurl=file:///nsm/kernelrepo/" >> /etc/yum.repos.d/securityonionkernel.repo echo "enabled=1" >> /etc/yum.repos.d/securityonionkernel.repo echo "gpgcheck=1" >> /etc/yum.repos.d/securityonionkernel.repo + echo "skip_if_unavailable=1" >> /etc/yum.repos.d/securityonionkernel.repo fi logCmd "dnf repolist all" if [[ $waitforstate ]]; then From b0b022c3ada07e03fd4ecf2ee5ac9f06294e3174 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Wed, 24 Jun 2026 13:23:25 -0400 Subject: [PATCH 5/5] Seed an empty /nsm/kernelrepo so the manager repo is always valid so-repo-sync only populates /nsm/kernelrepo after the highstate, so on a manager the file:///nsm/kernelrepo repo could be assigned before any repodata exists, failing every dnf op. Run createrepo on the dir when repodata/repomd.xml is missing, leaving a synced repo untouched. --- salt/manager/init.sls | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/salt/manager/init.sls b/salt/manager/init.sls index d6c154efa..e77b1a601 100644 --- a/salt/manager/init.sls +++ b/salt/manager/init.sls @@ -96,6 +96,18 @@ kernelrepo_dir: - group - show_changes: False +# Ensure /nsm/kernelrepo is always a valid (if empty) repo before it is ever assigned to +# a client. Without repodata/repomd.xml an enabled file:///nsm/kernelrepo repo makes every +# dnf operation fail; so-repo-sync only populates it after the highstate, so seed an empty +# repo here. Only runs when repodata is missing, so it won't clobber a synced repo. +kernelrepo_init_empty: + cmd.run: + - name: createrepo /nsm/kernelrepo + - unless: 'test -e /nsm/kernelrepo/repodata/repomd.xml' + - require: + - file: kernelrepo_dir + - pkg: install_createrepo + manager_sbin: file.recurse: - name: /usr/sbin