diff --git a/xCAT-test/unit/xcatlib_el_version.t b/xCAT-test/unit/xcatlib_el_version.t new file mode 100644 index 000000000..6337d4007 --- /dev/null +++ b/xCAT-test/unit/xcatlib_el_version.t @@ -0,0 +1,203 @@ +#!/usr/bin/env perl +use strict; +use warnings; + +use File::Spec; +use File::Temp qw(tempdir); +use FindBin; +use Test::More; + +my $xcatlib = File::Spec->catfile( + $FindBin::Bin, '..', '..', 'xCAT', 'postscripts', 'xcatlib.sh' +); +my $nicutils = File::Spec->catfile( + $FindBin::Bin, '..', '..', 'xCAT', 'postscripts', 'nicutils.sh' +); +my $routeop = File::Spec->catfile( + $FindBin::Bin, '..', '..', 'xCAT', 'postscripts', 'routeop' +); + +sub extra_parameter_path { + my ( $osver, $report_rematch ) = @_; + $report_rematch //= ''; + my $script = <<'BASH'; +source "$1" +source "$2" +query_extra_params() +{ + array_extra_param_names=(mtu) + array_extra_param_values=(9000) +} + +grep() +{ + return 0 +} +sed() +{ + printf '%s\n' legacy-write +} +nmcli() +{ + case "$1 $2" in + 'con modify') printf '%s\n' el9-nmcli ;; + 'con reload') printf '%s\n' legacy-reload ;; + *) return 2 ;; + esac +} +OSVER=$3 +add_extra_params_nmcli eth0 test0 +if [ "$4" = rematch ]; then + printf '%s|%s|%s|%s\n' \ + "${#BASH_REMATCH[@]}" \ + "${BASH_REMATCH[0]-}" \ + "${BASH_REMATCH[1]-}" \ + "${BASH_REMATCH[2]-}" +fi +BASH + + open( + my $output, + '-|', + 'bash', + '--noprofile', + '--norc', + '-c', + $script, + 'bash', + $xcatlib, + $nicutils, + $osver, + $report_rematch + ) or die "Unable to run EL postscript workflow: $!"; + + my $result = do { local $/; <$output> }; + close($output) or die "EL postscript workflow failed: $?"; + chomp $result; + return $result; +} + +sub route_path_without_current_helper { + my ($stale_library) = @_; + my $tempdir = tempdir( CLEANUP => 1 ); + my $runner = File::Spec->catfile( $tempdir, 'routeop-runner' ); + + if ($stale_library) { + my $old_xcatlib = File::Spec->catfile( $tempdir, 'xcatlib.sh' ); + open( my $library, '>', $old_xcatlib ) + or die "Unable to create old xcatlib stub: $!"; + print {$library} "# Older xcatlib without xcat_is_el9_or_later\n"; + close($library) or die "Unable to close old xcatlib stub: $!"; + } + + my $script = <<'BASH'; +exec 2>&1 +uname() +{ + printf '%s\n' "$ROUTE_TEST_UNAME" +} +nmcli() +{ + return 0 +} +report_route_path() +{ + if [ "$ROUTE_TEST_UNSET_HELPER" = 1 ]; then + unset -f xcat_is_el9_or_later + fi + OS_name=redhat + OSVER=rhel9 + if redhat_uses_nmcli_routes; then + printf '%s\n' el9-nmcli + else + printf '%s\n' legacy-route + fi +} +trap report_route_path EXIT +source "$1" noop 192.0.2.0 24 192.0.2.1 eth0 +BASH + + local $ENV{ROUTE_TEST_UNAME} = 'Linux'; + local $ENV{ROUTE_TEST_UNSET_HELPER} = $stale_library ? 0 : 1; + open( + my $output, + '-|', + 'bash', + '--noprofile', + '--norc', + '-c', + $script, + $runner, + $routeop + ) or die "Unable to run routeop workflow: $!"; + + my $result = do { local $/; <$output> }; + close($output) or die "routeop workflow failed: $?"; + chomp $result; + return $result; +} + +my @accepted = ( + [ 'rhel9', 'RHEL 9' ], + [ 'rhels9.6', 'legacy RHEL spelling with a point release' ], + [ 'alma9', 'AlmaLinux short spelling' ], + [ 'almalinux9.5', 'AlmaLinux long spelling with a point release' ], + [ 'rocky10', 'Rocky Linux 10' ], + [ 'centos10-stream', 'CentOS 10 stream suffix' ], + [ 'ol10', 'Oracle Linux 10' ], +); + +for my $case (@accepted) { + is( + extra_parameter_path( $case->[0] ), + 'el9-nmcli', + "$case->[1] uses the EL9 NetworkManager path" + ); +} + +my @rejected = ( + [ 'rhel8.10', 'RHEL 8' ], + [ 'rhels8', 'legacy RHEL 8 spelling' ], + [ 'alma8', 'AlmaLinux 8 short spelling' ], + [ 'almalinux8.10', 'AlmaLinux 8 long spelling' ], + [ 'rocky8', 'Rocky Linux 8' ], + [ 'centos8', 'CentOS 8' ], + [ 'ol8', 'Oracle Linux 8' ], + [ 'redhat9', 'unsupported Red Hat spelling' ], + [ 'ubuntu24.04', 'unrelated distribution' ], + [ '', 'missing OS version' ], +); + +for my $case (@rejected) { + is( + extra_parameter_path( $case->[0] ), + "legacy-write\nlegacy-reload", + "$case->[1] uses the legacy ifcfg path" + ); +} + +is( + route_path_without_current_helper(0), + 'el9-nmcli', + 'routeop preserves EL9 routing when xcatlib is unavailable' +); + +is( + route_path_without_current_helper(1), + 'el9-nmcli', + 'routeop preserves EL9 routing with an older xcatlib' +); + +is( + extra_parameter_path( 'rhel9', 'rematch' ), + "el9-nmcli\n3|rhel9|rhel|9", + 'EL9 workflow preserves successful regex captures' +); + +is( + extra_parameter_path( 'rhel8', 'rematch' ), + "legacy-write\nlegacy-reload\n0|||", + 'legacy workflow preserves failed regex captures' +); + +done_testing(); diff --git a/xCAT/postscripts/configeth b/xCAT/postscripts/configeth index fff118007..bfcc76e6d 100755 --- a/xCAT/postscripts/configeth +++ b/xCAT/postscripts/configeth @@ -215,7 +215,7 @@ function configipv4(){ do name="${array_extra_param_names[$i]}" value="${array_extra_param_values[$i]}" - if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then + if xcat_is_el9_or_later "$OSVER"; then # Best-effort: apply as a native NetworkManager property if one exists. # Arbitrary ifcfg-style keys (e.g. CONNECTED_MODE) have no NM setting and # are (re)persisted into the keyfile [user] section after ALL IPs are @@ -840,7 +840,7 @@ elif [ "$1" = "-s" ];then do name="${array_extra_param_names[$i]}" value="${array_extra_param_values[$i]}" - if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then + if xcat_is_el9_or_later "$OSVER"; then nmcli con modify $con_name $name $value else echo "$i: name=$name value=$value" @@ -1326,7 +1326,7 @@ fi # in-memory model and drops anything NM does not model, so an earlier write would be lost. # On EL10 (keyfile-only) there is no ifcfg file to hold these. We do NOT reload after, so # the file keeps the section; NM tolerates an unknown [user] section in keyfile mode. -if [ "$str_os_type" = "redhat" ] && [ "$networkmanager_active" = "1" ] && [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then +if [ "$str_os_type" = "redhat" ] && [ "$networkmanager_active" = "1" ] && xcat_is_el9_or_later "$OSVER"; then # Resolve the connection's keyfile by UUID -- NM may name it "-.nmconnection" # (not the plain ".nmconnection") when a same-named file already exists. ep_con="xcat-${str_nic_name}" diff --git a/xCAT/postscripts/configib b/xCAT/postscripts/configib index 9e9d233a7..0009875e8 100755 --- a/xCAT/postscripts/configib +++ b/xCAT/postscripts/configib @@ -177,7 +177,7 @@ then exit fi - if [[ $OS_name != 'ubuntu' ]] && [[ ! "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then + if [[ $OS_name != 'ubuntu' ]] && ! xcat_is_el9_or_later "$OSVER"; then if [ $OS_name == 'suse' ] then dir="/etc/sysconfig/network" @@ -485,7 +485,7 @@ IPADDR_$ipindex=$nicip" >> $dir/ifcfg-$nic # First ip address if [ $ipindex -eq 1 ] then - if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then + if xcat_is_el9_or_later "$OSVER"; then if nmcli --field connection.id con show $nic 2>&1 1>/dev/null then # modify current connection # ipv6 @@ -551,7 +551,7 @@ IPADDR=$nicip" > $dir/ifcfg-$nic name="${array_extra_param_names[$i]}" value="${array_extra_param_values[$i]}" echo " $i: name=$name value=$value" - if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then + if xcat_is_el9_or_later "$OSVER"; then nmcli con modify $nic $name $value else grep -i "${name}" $dir/ifcfg-$nic @@ -564,7 +564,7 @@ IPADDR=$nicip" > $dir/ifcfg-$nic i=$((i+1)) done else # not the first ip address - if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then + if xcat_is_el9_or_later "$OSVER"; then if nmcli --field connection.id con show $nic 2>&1 1>/dev/null then # modify current connection # ipv6 @@ -643,7 +643,7 @@ IPADDR$ipindex=$nicip" name="${array_extra_param_names[$i]}" value="${array_extra_param_values[$i]}" echo " $i: name=$name value=$value" - if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then + if xcat_is_el9_or_later "$OSVER"; then nmcli con modify $nic $name $value else grep -i "${name}" $cfgfile @@ -826,7 +826,7 @@ then done else if [ $nmcli_used -eq 1 ]; then - if ! [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then + if ! xcat_is_el9_or_later "$OSVER"; then nmcli con reload $dir/ifcfg-$nic fi nmcli con up $nic 2>&1 diff --git a/xCAT/postscripts/nicutils.sh b/xCAT/postscripts/nicutils.sh index b51afbfb2..89f727076 100755 --- a/xCAT/postscripts/nicutils.sh +++ b/xCAT/postscripts/nicutils.sh @@ -1813,7 +1813,7 @@ function add_extra_params_nmcli { con_name=$2 rc=0 - if ! [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then + if ! xcat_is_el9_or_later "$OSVER"; then str_conf_file="/etc/sysconfig/network-scripts/ifcfg-${con_name}" str_conf_file_1="/etc/sysconfig/network-scripts/ifcfg-${con_name}-1" if [ -f $str_conf_file_1 ]; then @@ -1834,7 +1834,7 @@ function add_extra_params_nmcli { if [ -n "$name" -a -n "$value" ]; then # For RHEL 9, use nmcli directly, otherwise use ifcfg scheme. - if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then + if xcat_is_el9_or_later "$OSVER"; then nmcli con modify "$con_name" "$name" "$value" rc+=$? else @@ -1853,7 +1853,7 @@ function add_extra_params_nmcli { i=$((i+1)) done - if [[ ! "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then + if ! xcat_is_el9_or_later "$OSVER"; then $nmcli con reload $str_conf_file fi return $rc diff --git a/xCAT/postscripts/routeop b/xCAT/postscripts/routeop index 95b68076e..8cf93e33b 100755 --- a/xCAT/postscripts/routeop +++ b/xCAT/postscripts/routeop @@ -267,7 +267,11 @@ redhat_uses_nmcli_routes() [ "$OS_name" = "redhat" ] || return 1 command -v nmcli >/dev/null 2>&1 || return 1 - if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then + if command -v xcat_is_el9_or_later >/dev/null 2>&1; then + if xcat_is_el9_or_later "$OSVER"; then + return 0 + fi + elif [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then return 0 fi diff --git a/xCAT/postscripts/xcatlib.sh b/xCAT/postscripts/xcatlib.sh index 1dbef7b35..5ddbc6663 100755 --- a/xCAT/postscripts/xcatlib.sh +++ b/xCAT/postscripts/xcatlib.sh @@ -17,6 +17,12 @@ function hashget(){ eval echo "\$${str_hashname}" } +# Match the OSVER forms currently used by EL9+ postscript paths. +xcat_is_el9_or_later() +{ + [[ "$1" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]] +} + function debianpreconf(){ #create the config sub dir if [ ! -d "/etc/network/interfaces.d" ];then