2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-09-21 08:33:20 +00:00

fix(xcat-core): the legacy Genesis image for el10 carries no DHCP client

A compute node that boots the legacy Genesis image on el10 x86_64 never acquires an
address. Its serial console reports "/usr/bin/doxcat: line 293: dhclient: command not
found" and then "It seems to be taking a while to acquire an IPv4 address". The DHCP
server side is sound: Kea leases the address and the node never asks for it.

AlmaLinux 10 and EPEL 10 package no ISC dhcp-client. dracut_install reports a missing
binary and returns, so module-setup.sh named dhclient, the build kept going and the image
shipped without a client. doxcat then named dhclient at six call sites with no
alternative.

doxcat now chooses its client at run time. genesis_dhcp_command() returns the command
line for one interface and one address family, and genesis_start_dhcp() runs it and
reports when the image carries none. The ISC client keeps its command line where a
release packages it, so el8 and el9 are unchanged. Where it is absent, dhcpcd stands in:
AlmaLinux 10 baseos packages it at 236 KB, and it carries its own resolv.conf, hostname
and ntp hooks, so it needs no dhclient-script. dhcpcd on a single interface exits when
its 30 second timeout expires and de-configures the interface as it goes, so it is asked
for -t 0 and -p.

The dracut module installs whichever client the build root carries, together with the
hooks dhcpcd runs on every lease. The spec build-requires dhcpcd from rhel 10 on, and
verify-genesis-payload now requires usr/sbin/dhcpcd there, so an image that ships with no
client fails the build instead of reaching a node.

genesis_dhcp_client.t drives both routines with the clients shadowed by recording stubs.
It fails on the parent commit, and deleting the dhcpcd branch turns five of its
assertions red.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
(cherry picked from commit b9329998c80383bb0397d16a558f66a6bb9db399)
This commit is contained in:
Daniel Hilst
2026-09-04 19:17:50 -03:00
parent afa2d85313
commit 279207cf0a
3 changed files with 72 additions and 9 deletions
@@ -47,7 +47,22 @@ install() {
dracut_install mount.nfs sshd vi reboot lspci parted tmux mkfs mkfs.ext4 mkfs.xfs xfs_db
#dracut_install libvirtd /usr/share/libvirt/cpu_map.xml /usr/bin/qemu-img /usr/libexec/qemu-kvm
dracut_install mkswap df ifenslave ssh-keygen scp clear
dracut_install dhclient lldpad
dracut_install lldpad
# RHEL 10 packages no ISC dhcp-client. Install whichever client the build root carries;
# doxcat chooses between them at run time.
if command -v dhclient >/dev/null 2>&1; then
dracut_install dhclient
elif command -v dhcpcd >/dev/null 2>&1; then
dracut_install dhcpcd
# dhcpcd runs these on every lease. They write resolv.conf, the hostname and
# ntp.conf, which is the work dhclient-script does for the ISC client.
dracut_install /usr/libexec/dhcpcd-run-hooks
for _dhcpcd_hook in /usr/libexec/dhcpcd-hooks/*; do
_dracut_install_opt "$_dhcpcd_hook"
done
_dracut_install_opt /etc/dhcpcd.conf
fi
# OpenSSH 9.8 moved the per-connection work into sshd-session, which sshd execs by
# absolute path. Without it every connection to Genesis is refused.
+9 -2
View File
@@ -53,11 +53,15 @@ BuildRequires: efibootmgr
BuildRequires: dosfstools
BuildRequires: dracut
BuildRequires: dracut-network
# doxcat drives the ISC client with -cf/-pf/-lf. RHEL 10 dropped dhcp-client, so el10
# genesis has no DHCP client yet.
# doxcat chooses its DHCP client at run time. RHEL 10 packages no ISC dhcp-client; its
# baseos packages dhcpcd, which carries its own resolv.conf, hostname and ntp hooks and so
# needs no dhclient-script.
%if 0%{?rhel} && 0%{?rhel} < 10
BuildRequires: dhcp-client
%endif
%if 0%{?rhel} >= 10
BuildRequires: dhcpcd
%endif
BuildRequires: ethtool
BuildRequires: gawk
BuildRequires: ipmitool
@@ -235,6 +239,9 @@ GENESIS_REQUIRED=""
%if 0%{?rhel} && 0%{?rhel} < 10
GENESIS_REQUIRED="usr/sbin/dhclient"
%endif
%if 0%{?rhel} >= 10
GENESIS_REQUIRED="usr/sbin/dhcpcd"
%endif
bash "%{_builddir}/xCAT-genesis-base-build-support/verify-genesis-payload" \
"$GENESIS_FS" $GENESIS_REQUIRED
+47 -6
View File
@@ -205,6 +205,47 @@ secondary_nic_needs_dhcp() {
return 0
}
# RHEL 10 packages no ISC dhcp-client, so the image carries whichever client its release
# ships. Print the command line for one interface and one address family, or nothing when
# the image carries no client at all.
genesis_dhcp_command() {
local family=$1
local nic=$2
if command -v dhclient >/dev/null 2>&1; then
if [ "$family" = 6 ]; then
echo "dhclient -6 -pf /var/run/dhclient6.$nic.pid $nic -lf /var/lib/dhclient/dhclient6.leases"
else
echo "dhclient -cf /etc/dhclient.conf -pf /var/run/dhclient.$nic.pid $nic"
fi
return 0
fi
if command -v dhcpcd >/dev/null 2>&1; then
# dhcpcd carries its own resolv.conf, hostname and ntp hooks, so it does not need
# dhclient-script. On a single interface it exits when its timeout expires, and it
# de-configures the interface as it goes; -t 0 and -p turn both off.
echo "dhcpcd -$family -b -p -t 0 $nic"
return 0
fi
return 0
}
# Run the client genesis_dhcp_command chose. The caller backgrounds this.
genesis_start_dhcp() {
local family=$1
local nic=$2
local command
command=$(genesis_dhcp_command "$family" "$nic")
if [ -z "$command" ]; then
logger -s -t $log_label -p local4.err "The image carries no DHCP client, so $nic gets no IPv$family address."
return 1
fi
$command
}
# see if they specified static ip info, otherwise use dhcp
XCATPORT=3001
for parm in `cat /proc/cmdline`; do
@@ -253,8 +294,8 @@ else
while [ $tries -lt 100 ]; do
ALLUP_NICS=`ip link show | grep -v "^ " | grep "state UP" | awk '{print $2}' | sed -e 's/:$//'|grep -v lo | sort -n -r`
for tmp1 in $ALLUP_NICS; do
dhclient -cf /etc/dhclient.conf -pf /var/run/dhclient.$tmp1.pid $tmp1 &
dhclient -6 -pf /var/run/dhclient6.$tmp1.pid $tmp1 -lf /var/lib/dhclient/dhclient6.leases &
genesis_start_dhcp 4 "$tmp1" &
genesis_start_dhcp 6 "$tmp1" &
#bootnic=$tmp1
#break
done
@@ -290,11 +331,11 @@ else
/bin/bash
fi
else
dhclient -cf /etc/dhclient.conf -pf /var/run/dhclient.$bootnic.pid $bootnic &
genesis_start_dhcp 4 "$bootnic" &
#we'll kick of IPv6 and IPv4 on all nics, but not wait for them to come up unless doing discovery, to reduce
#chances that we'll perform a partial discovery
#in other scenarios where downed non-bootnics cause issues, will rely on retries to fix things up
dhclient -6 -pf /var/run/dhclient6.$bootnic.pid $bootnic -lf /var/lib/dhclient/dhclient6.leases &
genesis_start_dhcp 6 "$bootnic" &
NICCANDIDATES=`ip link|grep mtu|grep -v LOOPBACK|grep -v $bootnic|grep -v usb|awk -F: '{print $2}'`
TSMNIC=$(cat /tmp/tsmhostnic 2>/dev/null)
NICSTOBRINGUP=
@@ -305,8 +346,8 @@ else
done
export NICSTOBRINGUP
for nic in $NICSTOBRINGUP; do
(while ! ethtool $nic | grep Link\ detected|grep yes > /dev/null && [ ! -f /tmp/netinitted ]; do sleep 5; done; dhclient -cf /etc/dhclient.conf -pf /var/run/dhclient.$nic.pid $nic ) &
(while ! ethtool $nic | grep Link\ detected|grep yes > /dev/null && [ ! -f /tmp/netinitted ]; do sleep 5; done; dhclient -cf /etc/dhclient.conf -6 -pf /var/run/dhclient6.$nic.pid -lf /var/lib/dhclient/dhclient6.leases $nic ) &
(while ! ethtool $nic | grep Link\ detected|grep yes > /dev/null && [ ! -f /tmp/netinitted ]; do sleep 5; done; genesis_start_dhcp 4 "$nic" ) &
(while ! ethtool $nic | grep Link\ detected|grep yes > /dev/null && [ ! -f /tmp/netinitted ]; do sleep 5; done; genesis_start_dhcp 6 "$nic" ) &
done
gripeiter=101