From 886db49e2754a7cad1c46c4e230eed681528e2ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Wed, 22 Jul 2026 22:54:20 -0300 Subject: [PATCH] fix(postscripts): disable xcatpostinit1 before running the postscripts The generated /opt/xcat/xcatinstallpost ran the install postscripts first and only disabled the xcatpostinit1 service afterwards. If one of those postscripts rebooted the node (for example a firmware or kernel update), the service was still enabled, so on the next boot the whole postscript set ran again from the start. Disable the service *before* running the postscripts so a mid-postscript reboot cannot re-trigger them. The disable decision reads OSVER (base variant only), RUNBOOTSCRIPTS and NODESTATUS, which the included xcatinstallpost script would otherwise set. Moving the INCLUDE below the disable block leaves those variables unset, so read them up front (the included script re-reads them) and source xcatlib.sh so msgutil_r is available; the disable decision is then identical to before. The original change (lenovobuild 9184cbe0) touched only the legacy post.xcat. Modern EL uses the systemd variants: post.xcat.ng (RHEL/CentOS 8 and 9) and post.xcat.rhels10 (RHEL 10). Apply the same reorder to all three so the fix actually takes effect on current platforms. Lab-validated with a full AlmaLinux 9.8 stateful install (post.xcat.ng path): the generated xcatinstallpost disables the service before running the postscripts, the postscripts run exactly once, the node reaches "booted", and with the default NODESTATUS=1 the service is left enabled just as before. Recovered from the unmerged lenovobuild branch (original 9184cbe0), adapted and extended to the .ng and .rhels10 variants. Co-authored-by: Jarrod Johnson <10814490+jjohnson42@users.noreply.github.com> --- .../share/xcat/install/scripts/post.xcat | 17 +++++++++++++++-- .../share/xcat/install/scripts/post.xcat.ng | 16 ++++++++++++++-- .../xcat/install/scripts/post.xcat.rhels10 | 16 ++++++++++++++-- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/xCAT-server/share/xcat/install/scripts/post.xcat b/xCAT-server/share/xcat/install/scripts/post.xcat index ad53a5c60..d6ac63ff0 100755 --- a/xCAT-server/share/xcat/install/scripts/post.xcat +++ b/xCAT-server/share/xcat/install/scripts/post.xcat @@ -360,11 +360,22 @@ fi #create the xcatinstallpost mkdir -p /opt/xcat cat >/opt/xcat/xcatinstallpost << 'EOF' -#INCLUDE:#TABLE:site:key=installdir:value#/postscripts/xcatinstallpost# - +#!/bin/bash +# Disable the xcatpostinit1 service *before* running the postscripts (the +# INCLUDE at the end). If a postscript reboots the node, the service is +# already disabled, so the whole postscript set is not run again on reboot. +# The disable decision needs OSVER, RUNBOOTSCRIPTS and NODESTATUS, which the +# included script would otherwise set; read them up front (it re-reads them), +# and source xcatlib.sh so msgutil_r is available for the debug messages. +[ -f /xcatpost/xcatlib.sh ] && . /xcatpost/xcatlib.sh if [ -f /xcatpost/mypostscript.post ]; then + OSVER=`grep '^OSVER=' /xcatpost/mypostscript.post |cut -d= -f2|sed s/\'//g` RUNBOOTSCRIPTS=`grep 'RUNBOOTSCRIPTS=' /xcatpost/mypostscript.post |cut -d= -f2 | tr -d \'\" | tr A-Z a-z` + XCATDEBUGMODE=`grep 'XCATDEBUGMODE=' /xcatpost/mypostscript.post |cut -d= -f2 | tr -d \'\" | tr A-Z a-z` + MASTER_IP=`grep '^MASTER_IP=' /xcatpost/mypostscript.post |cut -d= -f2|sed s/\'//g` fi +[ -f /xcatpost/mypostscript ] && NODESTATUS=`grep 'NODESTATUS=' /xcatpost/mypostscript |awk -F = '{print $2}'|tr -d \'\" | tr A-Z a-z ` +[ -z "$NODESTATUS" ] && NODESTATUS="1" if [[ $OSVER == ubuntu* ]]; then if [[ ! "$RUNBOOTSCRIPTS" =~ ^(1|yes|y)$ ]]; then @@ -383,6 +394,8 @@ else fi +#INCLUDE:#TABLE:site:key=installdir:value#/postscripts/xcatinstallpost# + EOF chmod 755 /opt/xcat/xcatinstallpost diff --git a/xCAT-server/share/xcat/install/scripts/post.xcat.ng b/xCAT-server/share/xcat/install/scripts/post.xcat.ng index bbabcd1fe..78f0e09a9 100644 --- a/xCAT-server/share/xcat/install/scripts/post.xcat.ng +++ b/xCAT-server/share/xcat/install/scripts/post.xcat.ng @@ -355,12 +355,22 @@ chmod 0755 /opt/xcat/xcatpostinit1 # Create the xcatinstallpost mkdir -p /opt/xcat cat >/opt/xcat/xcatinstallpost <<'EOF' -#INCLUDE:#TABLE:site:key=installdir:value#/postscripts/xcatinstallpost# - +#!/bin/bash +# Disable the xcatpostinit1 service *before* running the postscripts (the +# INCLUDE at the end). If a postscript reboots the node, the service is +# already disabled, so the whole postscript set is not run again on reboot. +# The disable decision needs RUNBOOTSCRIPTS and NODESTATUS, which the included +# script would otherwise set; read them up front (it re-reads them), and source +# xcatlib.sh so msgutil_r is available for the debug message. +[ -f /xcatpost/xcatlib.sh ] && . /xcatpost/xcatlib.sh if [ -f /xcatpost/mypostscript.post ] then RUNBOOTSCRIPTS=`grep 'RUNBOOTSCRIPTS=' /xcatpost/mypostscript.post | cut -d= -f2 | tr -d \'\" | tr A-Z a-z` + XCATDEBUGMODE=`grep 'XCATDEBUGMODE=' /xcatpost/mypostscript.post | cut -d= -f2 | tr -d \'\" | tr A-Z a-z` + MASTER_IP=`grep '^MASTER_IP=' /xcatpost/mypostscript.post | cut -d= -f2 | sed s/\'//g` fi +[ -f /xcatpost/mypostscript ] && NODESTATUS=`grep 'NODESTATUS=' /xcatpost/mypostscript | awk -F = '{print $2}' | tr -d \'\" | tr A-Z a-z` +[ -z "$NODESTATUS" ] && NODESTATUS="1" if [[ ! "$RUNBOOTSCRIPTS" =~ ^(1|yes|y)$ ]] && [[ ! "$NODESTATUS" =~ ^(1|yes|y)$ ]]; then systemctl disable xcatpostinit1.service @@ -371,6 +381,8 @@ if [[ ! "$RUNBOOTSCRIPTS" =~ ^(1|yes|y)$ ]] && [[ ! "$NODESTATUS" =~ ^(1|yes|y)$ esac fi +#INCLUDE:#TABLE:site:key=installdir:value#/postscripts/xcatinstallpost# + EOF chmod 0755 /opt/xcat/xcatinstallpost diff --git a/xCAT-server/share/xcat/install/scripts/post.xcat.rhels10 b/xCAT-server/share/xcat/install/scripts/post.xcat.rhels10 index bbabcd1fe..78f0e09a9 100644 --- a/xCAT-server/share/xcat/install/scripts/post.xcat.rhels10 +++ b/xCAT-server/share/xcat/install/scripts/post.xcat.rhels10 @@ -355,12 +355,22 @@ chmod 0755 /opt/xcat/xcatpostinit1 # Create the xcatinstallpost mkdir -p /opt/xcat cat >/opt/xcat/xcatinstallpost <<'EOF' -#INCLUDE:#TABLE:site:key=installdir:value#/postscripts/xcatinstallpost# - +#!/bin/bash +# Disable the xcatpostinit1 service *before* running the postscripts (the +# INCLUDE at the end). If a postscript reboots the node, the service is +# already disabled, so the whole postscript set is not run again on reboot. +# The disable decision needs RUNBOOTSCRIPTS and NODESTATUS, which the included +# script would otherwise set; read them up front (it re-reads them), and source +# xcatlib.sh so msgutil_r is available for the debug message. +[ -f /xcatpost/xcatlib.sh ] && . /xcatpost/xcatlib.sh if [ -f /xcatpost/mypostscript.post ] then RUNBOOTSCRIPTS=`grep 'RUNBOOTSCRIPTS=' /xcatpost/mypostscript.post | cut -d= -f2 | tr -d \'\" | tr A-Z a-z` + XCATDEBUGMODE=`grep 'XCATDEBUGMODE=' /xcatpost/mypostscript.post | cut -d= -f2 | tr -d \'\" | tr A-Z a-z` + MASTER_IP=`grep '^MASTER_IP=' /xcatpost/mypostscript.post | cut -d= -f2 | sed s/\'//g` fi +[ -f /xcatpost/mypostscript ] && NODESTATUS=`grep 'NODESTATUS=' /xcatpost/mypostscript | awk -F = '{print $2}' | tr -d \'\" | tr A-Z a-z` +[ -z "$NODESTATUS" ] && NODESTATUS="1" if [[ ! "$RUNBOOTSCRIPTS" =~ ^(1|yes|y)$ ]] && [[ ! "$NODESTATUS" =~ ^(1|yes|y)$ ]]; then systemctl disable xcatpostinit1.service @@ -371,6 +381,8 @@ if [[ ! "$RUNBOOTSCRIPTS" =~ ^(1|yes|y)$ ]] && [[ ! "$NODESTATUS" =~ ^(1|yes|y)$ esac fi +#INCLUDE:#TABLE:site:key=installdir:value#/postscripts/xcatinstallpost# + EOF chmod 0755 /opt/xcat/xcatinstallpost