diff --git a/xCAT-server/share/xcat/install/scripts/post.rhels10 b/xCAT-server/share/xcat/install/scripts/post.rhels10 index d7faa49c9..8b6bba514 100644 --- a/xCAT-server/share/xcat/install/scripts/post.rhels10 +++ b/xCAT-server/share/xcat/install/scripts/post.rhels10 @@ -6,18 +6,23 @@ [ "$MASTER_IP" ] || export MASTER_IP="#ENV:MASTER_IP#" #INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/scriptlib# -# Show connections : -nmcli -g NAME,STATE con show | \ - # print connection name for activated interfaces (ignores loopback iterface) - perl -F: -lane 'print $F[0] if $F[0] ne "lo" && $F[1] eq "activated"' | \ - # enable connection during the boot - xargs -t -I% nmcli con mod % connection.autoconnect yes +if command -v nmcli >/dev/null 2>&1; then + nmcli -g NAME,STATE con show | \ + awk -F: '$1 != "lo" && $2 == "activated" {print $1}' | \ + while IFS= read -r con_name + do + [ -n "$con_name" ] || continue + nmcli con mod "$con_name" connection.autoconnect yes + done +fi -internet_repo_file_list="oracle-linux-ol10.repo uek-ol10.repo Rocky-AppStream.repo Rocky-BaseOS.repo Rocky-Extras.repo CentOS-Base.repo almalinux-ha.repo almalinux-nfv.repo almalinux-powertools.repo almalinux.repo almalinux-resilientstorage.repo almalinux-rt.repo" +internet_repo_file_list="oracle-linux-ol10.repo uek-ol10.repo Rocky-AppStream.repo Rocky-BaseOS.repo Rocky-Extras.repo rocky.repo rocky-extras.repo CentOS-Base.repo centos.repo centos-addons.repo almalinux-ha.repo almalinux-nfv.repo almalinux-powertools.repo almalinux.repo almalinux-resilientstorage.repo almalinux-rt.repo" for repo_file in $internet_repo_file_list do if [ -f /etc/yum.repos.d/$repo_file ]; then - sed -i -e 's/enabled=1/enabled=0/' /etc/yum.repos.d/$repo_file + sed -i -e 's/^[[:space:]]*enabled[[:space:]]*=[[:space:]]*1/enabled=0/' /etc/yum.repos.d/$repo_file fi done + +exit 0 diff --git a/xCAT-server/share/xcat/install/scripts/post.rhels8 b/xCAT-server/share/xcat/install/scripts/post.rhels8 index 6ab305e87..418557a9d 100644 --- a/xCAT-server/share/xcat/install/scripts/post.rhels8 +++ b/xCAT-server/share/xcat/install/scripts/post.rhels8 @@ -6,27 +6,56 @@ [ "$MASTER_IP" ] || export MASTER_IP="#ENV:MASTER_IP#" #INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/scriptlib# -for i in $(ls /etc/sysconfig/network-scripts/ifcfg-* | grep -v ifcfg-lo) -do - nicname="${i##*-}" - if ethtool $nicname | grep -E -i -q "Link detected.*yes" >/dev/null 2>&1 - then - case "$XCATDEBUGMODE" in - "1"|"2") - msgutil_r "$MASTER_IP" "info" "set NIC $nicname to be activated on system boot" "/var/log/xcat/xcat.log" - ;; - esac - sed -i 's/ONBOOT=no/ONBOOT=yes/' "$i" +activate_nm_connections() +{ + nmcli -g NAME,STATE con show | \ + awk -F: '$1 != "lo" && $2 == "activated" {print $1}' | \ + while IFS= read -r con_name + do + [ -n "$con_name" ] || continue + case "$XCATDEBUGMODE" in + "1"|"2") + msgutil_r "$MASTER_IP" "info" "set connection $con_name to be activated on system boot" "/var/log/xcat/xcat.log" + ;; + esac + nmcli con mod "$con_name" connection.autoconnect yes + done +} + +activated_ifcfg=0 +if compgen -G "/etc/sysconfig/network-scripts/ifcfg-*" >/dev/null 2>&1; then + for i in /etc/sysconfig/network-scripts/ifcfg-* + do + [ "${i##*/}" = "ifcfg-lo" ] && continue + nicname="${i##*-}" + if ethtool "$nicname" 2>/dev/null | grep -E -i -q "Link detected.*yes" >/dev/null 2>&1 + then + case "$XCATDEBUGMODE" in + "1"|"2") + msgutil_r "$MASTER_IP" "info" "set NIC $nicname to be activated on system boot" "/var/log/xcat/xcat.log" + ;; + esac + sed -i 's/ONBOOT=no/ONBOOT=yes/' "$i" + activated_ifcfg=1 + fi + done + + if [ "$activated_ifcfg" -eq 0 ] && command -v nmcli >/dev/null 2>&1; then + activate_nm_connections fi -done +elif command -v nmcli >/dev/null 2>&1; then + activate_nm_connections +fi # List of internal repos to be disabled -internet_repo_file_list="oracle-linux-ol8.repo uek-ol8.repo Rocky-AppStream.repo Rocky-BaseOS.repo Rocky-Extras.repo CentOS-Base.repo almalinux-ha.repo almalinux-nfv.repo almalinux-powertools.repo almalinux.repo almalinux-resilientstorage.repo almalinux-rt.repo" +internet_repo_file_list="oracle-linux-ol8.repo oracle-linux-ol9.repo uek-ol8.repo uek-ol9.repo Rocky-AppStream.repo Rocky-BaseOS.repo Rocky-Extras.repo rocky.repo rocky-extras.repo CentOS-Base.repo centos.repo centos-addons.repo almalinux-ha.repo almalinux-nfv.repo almalinux-powertools.repo almalinux.repo almalinux-resilientstorage.repo almalinux-rt.repo" for repo_file in $internet_repo_file_list do if [ -f /etc/yum.repos.d/$repo_file ]; then - sed -i -e 's/enabled=1/enabled=0/' /etc/yum.repos.d/$repo_file + sed -i -e 's/^[[:space:]]*enabled[[:space:]]*=[[:space:]]*1/enabled=0/' /etc/yum.repos.d/$repo_file fi done + +exit 0 diff --git a/xCAT-server/share/xcat/netboot/rh/genimage b/xCAT-server/share/xcat/netboot/rh/genimage index f34f1c985..cc18fa09a 100755 --- a/xCAT-server/share/xcat/netboot/rh/genimage +++ b/xCAT-server/share/xcat/netboot/rh/genimage @@ -798,11 +798,11 @@ if ((-d "$rootimg_dir/usr/share/dracut") or (-d "$rootimg_dir/usr/lib/dracut")) # List of internet repos to be disabled -my @internet_repo_file_list = ("oracle-linux-ol8.repo", "uek-ol8.repo", "Rocky-AppStream.repo", "Rocky-BaseOS.repo", "Rocky-Extras.repo", "CentOS-Base.repo", "almalinux-ha.repo", "almalinux-nfv.repo", "almalinux-plus.repo", "almalinux-powertools.repo", "almalinux.repo", "almalinux-resilientstorage.repo", "almalinux-rt.repo"); +my @internet_repo_file_list = ("oracle-linux-ol8.repo", "oracle-linux-ol9.repo", "oracle-linux-ol10.repo", "uek-ol8.repo", "uek-ol9.repo", "uek-ol10.repo", "Rocky-AppStream.repo", "Rocky-BaseOS.repo", "Rocky-Extras.repo", "rocky.repo", "rocky-extras.repo", "CentOS-Base.repo", "centos.repo", "centos-addons.repo", "almalinux-ha.repo", "almalinux-nfv.repo", "almalinux-plus.repo", "almalinux-powertools.repo", "almalinux.repo", "almalinux-resilientstorage.repo", "almalinux-rt.repo"); foreach ( @internet_repo_file_list ) { if (-e "$rootimg_dir/etc/yum.repos.d/$_") { - system("sed -i -e 's/enabled=1/enabled=0/' $rootimg_dir/etc/yum.repos.d/$_"); + system("sed -i -e 's/^[[:space:]]*enabled[[:space:]]*=[[:space:]]*1/enabled=0/' $rootimg_dir/etc/yum.repos.d/$_"); } } @@ -930,6 +930,7 @@ unless (-f "$cwd/../add-on/statelite/rc.statelite") { exit 1; } +mkpath "$rootimg_dir/etc/init.d"; system("cp $cwd/../add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite"); system("cp $cwd/../add-on/statelite/rc.localdisk $rootimg_dir/etc/init.d/localdisk"); @@ -2588,4 +2589,3 @@ sub usage { return 0; } - diff --git a/xCAT-server/xCAT-server.spec b/xCAT-server/xCAT-server.spec index 8c188efe1..f11d7bfe5 100644 --- a/xCAT-server/xCAT-server.spec +++ b/xCAT-server/xCAT-server.spec @@ -40,7 +40,12 @@ BuildArch: noarch %if %s390x Requires: perl-IO-Socket-SSL perl-XML-Simple perl-XML-Parser %else +%if 0%{?rhel} >= 8 BuildRequires: perl-generators +%endif +%if 0%{?fedora} +BuildRequires: perl-generators +%endif Requires: perl-IO-Socket-SSL perl-XML-Simple perl-XML-Parser perl-Digest-SHA1 perl(LWP::Protocol::https) perl-XML-LibXML %endif Obsoletes: atftp-xcat diff --git a/xCAT/postscripts/configeth b/xCAT/postscripts/configeth index 0fb9c3733..ea8ec0b70 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" =~ ^(rhels9|alma9|rocky9) ]]; then + if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then nmcli con modify $con_name $name $value else grep -i "${name}" $str_conf_file @@ -824,7 +824,7 @@ elif [ "$1" = "-s" ];then do name="${array_extra_param_names[$i]}" value="${array_extra_param_values[$i]}" - if [[ "$OSVER" =~ ^(rhels9|alma9|rocky9) ]]; then + if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then nmcli con modify $con_name $name $value else echo "$i: name=$name value=$value" diff --git a/xCAT/postscripts/configib b/xCAT/postscripts/configib index 7f48eb42d..9e9d233a7 100755 --- a/xCAT/postscripts/configib +++ b/xCAT/postscripts/configib @@ -177,7 +177,7 @@ then exit fi - if [[ $OS_name != 'ubuntu' ]] && [[ ! "$OSVER" =~ ^(rhels9|alma9|rocky9) ]]; then + if [[ $OS_name != 'ubuntu' ]] && [[ ! "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; 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" =~ ^(rhels9|alma9|rocky9) ]]; then + if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; 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" =~ ^(rhels9|alma9|rocky9) ]]; then + if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; 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" =~ ^(rhels9|alma9|rocky9) ]]; then + if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; 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" =~ ^(rhels9|alma9|rocky9) ]]; then + if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; 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" =~ ^(rhels9|alma9|rocky9) ]]; then + if ! [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; 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 bfabbc287..48c387ed9 100755 --- a/xCAT/postscripts/nicutils.sh +++ b/xCAT/postscripts/nicutils.sh @@ -1809,7 +1809,7 @@ function add_extra_params_nmcli { con_name=$2 rc=0 - if ! [[ "$OSVER" =~ ^(rhels9|alma9|rocky9) ]]; then + if ! [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; 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 @@ -1830,7 +1830,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" =~ ^(rhels9|alma9|rocky9) ]]; then + if [[ "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then nmcli con modify "$con_name" "$name" "$value" rc+=$? else @@ -1849,7 +1849,7 @@ function add_extra_params_nmcli { i=$((i+1)) done - if [[ ! "$OSVER" =~ ^(rhels9|alma9|rocky9) ]]; then + if [[ ! "$OSVER" =~ ^(rhel|rhels|alma|almalinux|rocky|centos|ol)(9|1[0-9]) ]]; then $nmcli con reload $str_conf_file fi return $rc diff --git a/xCAT/postscripts/ospkgs b/xCAT/postscripts/ospkgs index a824e7222..5183b1e9e 100755 --- a/xCAT/postscripts/ospkgs +++ b/xCAT/postscripts/ospkgs @@ -244,6 +244,25 @@ array_ospkgdirs=($OSPKGDIR) #under the directories specified in "OSPKGDIR" array_empty os_path + +is_el_modular_pkgdir() +{ + pmatch "$OSVER" "rhel[89]*" || + pmatch "$OSVER" "rhel1[0-9]*" || + pmatch "$OSVER" "rhels[89]*" || + pmatch "$OSVER" "rhels1[0-9]*" || + pmatch "$OSVER" "centos[89]*" || + pmatch "$OSVER" "centos1[0-9]*" || + pmatch "$OSVER" "rocky[89]*" || + pmatch "$OSVER" "rocky1[0-9]*" || + pmatch "$OSVER" "alma[89]*" || + pmatch "$OSVER" "alma1[0-9]*" || + pmatch "$OSVER" "almalinux[89]*" || + pmatch "$OSVER" "almalinux1[0-9]*" || + pmatch "$OSVER" "ol[89]*" || + pmatch "$OSVER" "ol1[0-9]*" +} + index=0 for dir in ${array_ospkgdirs[@]} do @@ -273,15 +292,11 @@ do ospkgdir="$ospkgdir/SL" fi fi - if ( ! pmatch "$OSVER" "rhels[89]*" && - ! pmatch "$OSVER" "centos[89]*" && - ! pmatch "$OSVER" "rocky[89]*" && - ! pmatch "$OSVER" "alma[89]*" && - ! pmatch "$OSVER" "ol[89]*"); then - # For rhels8/9, centos8/9, ol8/9, alma8/9 and rocky8 do not put $ospkgdir by itself + if ! is_el_modular_pkgdir || \ + { [ "$dir" != "$default_pkgdir" ] && [ "$dir" != "$default_pkgdir/" ]; }; then + # For EL8+ modular distros, only the base OS pkgdir expands to subrepos. array_set_element os_path $index $ospkgdir fi - array_set_element os_path $index $ospkgdir if [ $dir == $default_pkgdir ] || [ $dir == "$default_pkgdir/" ]; then ospkgdir=$(echo $ospkgdir|sed 's/\/1$/\/2/') if ( pmatch "$OSVER" "sle15*" ); then @@ -345,18 +360,15 @@ do array_set_element os_path $index $ospkgdir_ok done fi # x86_64 - elif ( pmatch "$OSVER" "rhels[89]*" || - pmatch "$OSVER" "centos[89]*" || - pmatch "$OSVER" "rocky[89]*" || - pmatch "$OSVER" "alma[89]*" || - pmatch "$OSVER" "ol[89]*"); then - # for rhels8/9, centos8/9, ol8/9, alma8/9 and rocky8/9 the repodata is in ./BaseOS, ./AppStream, not in ./ + elif is_el_modular_pkgdir; then + # for EL8+ modular distros the repodata is in ./BaseOS and ./AppStream, not in ./ for arg in "BaseOS" "AppStream" do ospkgdir_ok="$ospkgdir/$arg" array_set_element os_path $index $ospkgdir_ok index=$(expr $index + 1) done + continue fi # if...elif..fi fi # eq default_pkgdir fi # match rhel* @@ -1045,5 +1057,3 @@ else fi exit $RETURNVAL - - diff --git a/xCAT/postscripts/otherpkgs b/xCAT/postscripts/otherpkgs index 301174e11..07c8a332e 100755 --- a/xCAT/postscripts/otherpkgs +++ b/xCAT/postscripts/otherpkgs @@ -323,6 +323,35 @@ fi array_ospkgdirs=($OSPKGDIR) IFS=$OIFS array_empty os_path + + is_el_modular_pkgdir() + { + pmatch "$OSVER" "rhel[89]*" || + pmatch "$OSVER" "rhel1[0-9]*" || + pmatch "$OSVER" "rhels[89]*" || + pmatch "$OSVER" "rhels1[0-9]*" || + pmatch "$OSVER" "centos[89]*" || + pmatch "$OSVER" "centos1[0-9]*" || + pmatch "$OSVER" "rocky[89]*" || + pmatch "$OSVER" "rocky1[0-9]*" || + pmatch "$OSVER" "alma[89]*" || + pmatch "$OSVER" "alma1[0-9]*" || + pmatch "$OSVER" "almalinux[89]*" || + pmatch "$OSVER" "almalinux1[0-9]*" || + pmatch "$OSVER" "ol[89]*" || + pmatch "$OSVER" "ol1[0-9]*" + } + + is_el_yum_distro() + { + pmatch "$OSVER" "rhel*" || + pmatch "$OSVER" "centos*" || + pmatch "$OSVER" "rocky*" || + pmatch "$OSVER" "alma*" || + pmatch "$OSVER" "ol*" || + pmatch "$OSVER" "SL*" + } + index=0 for dir in ${array_ospkgdirs[@]} do @@ -352,12 +381,9 @@ fi ospkgdir="$ospkgdir/SL" fi fi - if ( ! pmatch "$OSVER" "rhels[89]*" && - ! pmatch "$OSVER" "centos[89]*" && - ! pmatch "$OSVER" "rocky[89]*" && - ! pmatch "$OSVER" "alma[89]*" && - ! pmatch "$OSVER" "ol[89]*"); then - # For rhels8/9, centos8/9, ol8/9, and rocky8/9 do not put $ospkgdir by itself + if ! is_el_modular_pkgdir || \ + { [ "$dir" != "$default_pkgdir" ] && [ "$dir" != "$default_pkgdir/" ]; }; then + # For EL8+ modular distros, only the base OS pkgdir expands to subrepos. array_set_element os_path $index $ospkgdir fi @@ -398,18 +424,15 @@ fi array_set_element os_path $index $ospkgdir_ok done fi # x86_64 - elif ( pmatch "$OSVER" "rhels[89]*" || - pmatch "$OSVER" "centos[89]*" || - pmatch "$OSVER" "rocky[89]*" || - pmatch "$OSVER" "alma[89]*" || - pmatch "$OSVER" "ol[89]*"); then - # for rhels8/9, centos8/9, ol8/9, alma8/9 and rocky8/9 the repodata is in ./BaseOS, ./AppStream, not in ./ + elif is_el_modular_pkgdir; then + # for EL8+ modular distros the repodata is in ./BaseOS and ./AppStream, not in ./ for arg in "BaseOS" "AppStream" do ospkgdir_ok="$ospkgdir/$arg" array_set_element os_path $index $ospkgdir_ok index=$(expr $index + 1) done + continue fi # if...elif..fi fi # eq default_pkgdir fi # match rhel* @@ -567,7 +590,7 @@ if ( ! ( pmatch "$OSVER" "sles10*" ) && [ $haszypper -eq 1 ] ); then result=`zypper --non-interactive --no-gpg-checks refresh 2>&1` -elif ( ((pmatch "$OSVER" "rhel*") || (pmatch "$OSVER" "centos*") || (pmatch "$OSVER" "SL*")) && [ $hasyum -eq 1 ] ); then +elif ( is_el_yum_distro && [ $hasyum -eq 1 ] ); then #remove old repo files mkdir -p /etc/yum.repos.d if [ `ls -1 /etc/yum.repos.d/local-repository*.repo 2>/dev/null | wc -l` -gt 0 ]; then @@ -1121,4 +1144,3 @@ EOF` done exit $RETURNVAL - diff --git a/xCAT/postscripts/routeop b/xCAT/postscripts/routeop index 1ce7592e6..7a7ed5813 100755 --- a/xCAT/postscripts/routeop +++ b/xCAT/postscripts/routeop @@ -49,12 +49,12 @@ fi # use nummask to know whether the netmask format is 255.255.255.0 or CIDR (a number) nummask=0 -echo $mask | egrep "^[.0123456789]+$" > /dev/null +echo $mask | grep -E "^[.0123456789]+$" > /dev/null if [ $? -ne 0 ]; then echo "Error: invalid format of netmask $mask." exit 1 else - echo $mask | egrep "^[0123456789]+$" > /dev/null + echo $mask | grep -E "^[0123456789]+$" > /dev/null if [ $? -eq 0 ]; then # only has digital nummask=1 # the netmask is the length of network mask. if [ $mask -ge 128 ]; then @@ -124,21 +124,26 @@ function debianpreconf(){ route_exists() { - net=$1 - mask=$2 - gw=$3 - ret=0 + local route_net=$1 + local route_mask=$2 + local route_gw=$3 + local route_ifname + local ret=0 + local result + local os_type if [ -n "$4" ]; then - ifname=$4 + route_ifname=$4 + else + route_ifname=$ifname fi os_type=$(uname -s) # ipv6 - if echo $net | grep : 2>&1 1>/dev/null + if echo $route_net | grep : 2>&1 1>/dev/null then - result=`ip -6 route show $net/$mask` + result=`ip -6 route show $route_net/$route_mask` if [ $? -ne 0 ] || [ -z "$result" ] then ret=0 @@ -146,16 +151,53 @@ route_exists() ret=1 fi else - result=`netstat -nr|grep $net`; - if [ $? -eq 0 ] && [ -n "$result" ]; then - for x in `echo "$result"|tr -s " " ","` - do + if [ "$os_type" = "Linux" ] && command -v ip >/dev/null 2>&1; then + local route_prefix=$route_mask + local line + + if ! echo "$route_prefix" | grep -E "^[0123456789]+$" >/dev/null 2>&1; then + if type v4mask2prefix >/dev/null 2>&1; then + route_prefix=$(v4mask2prefix "$route_mask") + fi + fi + + if [ "$route_net" = "default" ]; then + result=$(ip route show default 2>/dev/null) + elif echo "$route_prefix" | grep -E "^[0123456789]+$" >/dev/null 2>&1; then + result=$(ip route show "$route_net/$route_prefix" 2>/dev/null) + else + result=$(ip route show "$route_net" 2>/dev/null) + fi + + while IFS= read -r line + do + [ -n "$line" ] || continue + if [ -n "$route_gw" ] && [ "$route_gw" != "0.0.0.0" ]; then + case " $line " in + *" via $route_gw "*) ;; + *) continue ;; + esac + fi + if [ -n "$route_ifname" ]; then + case " $line " in + *" dev $route_ifname "*) ;; + *) continue ;; + esac + fi + ret=1 + break + done <<< "$result" + else + result=`netstat -nr|grep $route_net`; + if [ $? -eq 0 ] && [ -n "$result" ]; then + for x in `echo "$result"|tr -s " " ","` + do if [ "$os_type" = "Linux" ]; then net1=`echo $x|cut -d',' -f1` gw1=`echo $x|cut -d',' -f2` mask1=`echo $x|cut -d',' -f3` ifname1=`echo $x|cut -d',' -f8` - if [ "$net" = "$net1" ] && [ "$mask" = "$mask1" ] && [ "$gw" = "$gw1" ] && [ "$ifname" = "$ifname1" ]; then + if [ "$route_net" = "$net1" ] && [ "$route_mask" = "$mask1" ] && [ "$route_gw" = "$gw1" ] && [ "$route_ifname" = "$ifname1" ]; then ret=1 break fi @@ -163,10 +205,10 @@ route_exists() tmp1=`echo $x|cut -d',' -f1` gw1=`echo $x|cut -d',' -f2` - n1=`echo $net |cut -d'.' -f1` - n2=`echo $net |cut -d'.' -f2` - n3=`echo $net |cut -d'.' -f3` - n4=`echo $net |cut -d'.' -f4` + n1=`echo $route_net |cut -d'.' -f1` + n2=`echo $route_net |cut -d'.' -f2` + n3=`echo $route_net |cut -d'.' -f3` + n4=`echo $route_net |cut -d'.' -f4` netnum="$(( ($n1 << 24) + ($n2 << 16) + ($n3 << 8) + $n4 ))" bits=32 @@ -176,20 +218,237 @@ route_exists() netnum="$(( $netnum >> 1 ))" done - tmp2="$net/$bits"; + tmp2="$route_net/$bits"; #echo "$tmp2=$tmp2" - if [ "$tmp1" = "$tmp2" ] && [ "$gw" = "$gw1" ]; then + if [ "$tmp1" = "$tmp2" ] && [ "$route_gw" = "$gw1" ]; then ret=1 break fi fi - done + done + fi fi fi echo $ret } +is_ipv6_route() +{ + case "$1" in + *:*) return 0 ;; + *) return 1 ;; + esac +} + +ipv4_route_prefix() +{ + local route_mask=$1 + + if echo "$route_mask" | grep -E "^[0123456789]+$" >/dev/null 2>&1; then + echo "$route_mask" + elif type v4mask2prefix >/dev/null 2>&1; then + v4mask2prefix "$route_mask" + else + echo "$route_mask" + fi +} + +ipv4_route_destination() +{ + local route_net=$1 + local route_mask=$2 + + if [ "$route_net" = "default" ]; then + echo "default" + else + echo "$route_net/$(ipv4_route_prefix "$route_mask")" + fi +} + +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 + return 0 + fi + + [ -r /etc/os-release ] || return 1 + local os_id + local version_major + os_id=$(sed -n 's/^ID=//p' /etc/os-release | head -1 | tr -d '"') + version_major=$(sed -n 's/^VERSION_ID=//p' /etc/os-release | head -1 | tr -d '"' | cut -d. -f1) + + case "$os_id" in + rhel|rocky|almalinux|centos|ol) + case "$version_major" in + ''|*[!0-9]*) return 1 ;; + esac + [ "$version_major" -ge 9 ] + ;; + *) + return 1 + ;; + esac +} + +route_ifname() +{ + local route_net=$1 + local route_gw=$2 + local requested_ifname=$3 + + if [ -n "$requested_ifname" ]; then + echo "$requested_ifname" + return 0 + fi + + if [ "$route_net" = "default" ]; then + if is_ipv6_route "$route_gw"; then + ip -6 route show default 2>/dev/null | awk '{for (i = 1; i <= NF; i++) if ($i == "dev") {print $(i + 1); exit}}' + else + ip route show default 2>/dev/null | awk '{for (i = 1; i <= NF; i++) if ($i == "dev") {print $(i + 1); exit}}' + fi + fi +} + +nm_connection_for_ifname() +{ + local dev=$1 + local con_name + + [ -n "$dev" ] || return 1 + + con_name=$(nmcli -g GENERAL.CONNECTION device show "$dev" 2>/dev/null | head -1) + if [ -n "$con_name" ] && [ "$con_name" != "--" ]; then + echo "$con_name" + return 0 + fi + + con_name=$(nmcli -g NAME,DEVICE connection show --active 2>/dev/null | awk -F: -v dev="$dev" '$2 == dev {print $1; exit}') + if [ -n "$con_name" ]; then + echo "$con_name" + return 0 + fi + + if nmcli connection show "$dev" >/dev/null 2>&1; then + echo "$dev" + return 0 + fi + + return 1 +} + +nmcli_remove_routes_by_destination() +{ + local con_name=$1 + local family=$2 + local route_dest=$3 + local current_routes + local current_route + + current_routes=$(nmcli -g "$family.routes" connection show "$con_name" 2>/dev/null | tr ',' '\n') + while IFS= read -r current_route + do + current_route=$(echo "$current_route" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + [ -n "$current_route" ] || continue + case "$current_route" in + "$route_dest"|"$route_dest "*) + nmcli connection modify "$con_name" -"$family.routes" "$current_route" >/dev/null 2>&1 + ;; + esac + done <<< "$current_routes" +} + +nmcli_persistent_route() +{ + local route_action=$1 + local route_net=$2 + local route_mask=$3 + local route_gw=$4 + local route_dev + local con_name + local family + local route_dest + local route_value + local empty_gw + local rc + + route_dev=$(route_ifname "$route_net" "$route_gw" "$5") + if [ -z "$route_dev" ]; then + echo "Error: the device name is necessary to configure a NetworkManager persistent route." + return 1 + fi + + con_name=$(nm_connection_for_ifname "$route_dev") + if [ -z "$con_name" ]; then + echo "Error: unable to find a NetworkManager connection for $route_dev." + return 1 + fi + + if is_ipv6_route "$route_net" || is_ipv6_route "$route_gw"; then + family="ipv6" + empty_gw="::" + else + family="ipv4" + empty_gw="0.0.0.0" + fi + + if [ "$route_net" = "default" ]; then + if [ "$route_action" = "delete" ]; then + nmcli connection modify "$con_name" "$family.gateway" "" + rc=$? + [ $rc -eq 0 ] && echo "Persistent default route removed from NetworkManager connection \"$con_name\"." + return $rc + elif [ -n "$route_gw" ] && [ "$route_gw" != "$empty_gw" ]; then + nmcli connection modify "$con_name" "$family.gateway" "$route_gw" "$family.never-default" no + rc=$? + [ $rc -eq 0 ] && echo "Persistent default route via $route_gw added to NetworkManager connection \"$con_name\"." + return $rc + else + if [ "$family" = "ipv6" ]; then + route_value="::/0" + else + route_value="0.0.0.0/0" + fi + nmcli connection modify "$con_name" -"$family.routes" "$route_value" >/dev/null 2>&1 + nmcli connection modify "$con_name" +"$family.routes" "$route_value" + rc=$? + [ $rc -eq 0 ] && echo "Persistent default route for $route_dev added to NetworkManager connection \"$con_name\"." + return $rc + fi + else + if [ "$family" = "ipv4" ]; then + route_dest=$(ipv4_route_destination "$route_net" "$route_mask") + else + route_dest="$route_net/$route_mask" + fi + route_value="$route_dest" + if [ -n "$route_gw" ] && [ "$route_gw" != "$empty_gw" ]; then + route_value="$route_value $route_gw" + fi + + if [ "$route_action" = "delete" ]; then + nmcli connection modify "$con_name" -"$family.routes" "$route_value" + rc=$? + [ $rc -eq 0 ] && echo "Persistent route \"$route_value\" removed from NetworkManager connection \"$con_name\"." + return $rc + else + if [ "$route_action" = "replace" ]; then + nmcli_remove_routes_by_destination "$con_name" "$family" "$route_dest" + else + nmcli connection modify "$con_name" -"$family.routes" "$route_value" >/dev/null 2>&1 + fi + nmcli connection modify "$con_name" +"$family.routes" "$route_value" + rc=$? + [ $rc -eq 0 ] && echo "Persistent route \"$route_value\" added to NetworkManager connection \"$con_name\"." + return $rc + fi + fi +} + # handle the route replace operation that adding the setting to configuration file replace_persistent_route() { @@ -256,7 +515,7 @@ replace_persistent_route() fi fi if [ -f $filename ]; then - egrep "^$routedest" $filename 2>&1 1>/dev/null + grep -E "^$routedest" $filename 2>&1 1>/dev/null if [ $? -ne 0 ]; then #route does not exist echo $route >> $filename echo "Persistent route \"$route\" has been added in $filename." @@ -277,6 +536,10 @@ replace_persistent_route() echo "Error: the device name is necessary to configure static route." return 1 fi + if redhat_uses_nmcli_routes; then + nmcli_persistent_route replace "$net" "$mask" "$gw" "$ifname" + return $? + fi if echo $net | grep : 2>&1 1>/dev/null then @@ -309,7 +572,7 @@ replace_persistent_route() routedest1=$routedest fi if [ -f $filename ]; then - egrep "^$routedest" $filename 2>&1 1>/dev/null + grep -E "^$routedest" $filename 2>&1 1>/dev/null if [ $? -ne 0 ]; then #route does not exist echo $route >> $filename echo "Persistent route \"$route\" has been added in $filename." @@ -583,6 +846,10 @@ add_persistent_route() ;; redhat) #echo "rh/fedora/centos" + if redhat_uses_nmcli_routes; then + nmcli_persistent_route add "$net" "$mask" "$gw" "$ifname" + return $? + fi # ipv6 net if echo $net | grep : 2>&1 1>/dev/null then @@ -729,6 +996,10 @@ rm_persistent_route() ;; redhat) #echo "rh/fedora/centos" + if redhat_uses_nmcli_routes; then + nmcli_persistent_route delete "$net" "$mask" "$gw" "$ifname" + return $? + fi #ipv6 if echo $net | grep : 2>&1 1>/dev/null then @@ -796,12 +1067,19 @@ if [ "$op" = "add" ]; then cmd="ip -6 route add $net/$mask via $gw" fi else - if [ "$(uname -s)" = "Linux" ]; then - if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then + if [ "$(uname -s)" = "Linux" ]; then + if command -v ip >/dev/null 2>&1; then + route_dest=$(ipv4_route_destination "$net" "$mask") + if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then + cmd="ip route add $route_dest dev $ifname" + else + cmd="ip route add $route_dest via $gw" + fi + elif [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then cmd="route add -net $net netmask $mask dev $ifname" - else + else cmd="route add -net $net netmask $mask gw $gw" - fi + fi else cmd="route add -net $net -netmask $mask $gw" fi @@ -845,12 +1123,19 @@ elif [ "$op" = "delete" ]; then cmd="ip -6 route delete $net/$mask via $gw" fi else - if [ "$(uname -s)" = "Linux" ]; then - if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then + if [ "$(uname -s)" = "Linux" ]; then + if command -v ip >/dev/null 2>&1; then + route_dest=$(ipv4_route_destination "$net" "$mask") + if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then + cmd="ip route delete $route_dest dev $ifname" + else + cmd="ip route delete $route_dest via $gw" + fi + elif [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then cmd="route delete -net $net netmask $mask dev $ifname" - else + else cmd="route delete -net $net netmask $mask gw $gw" - fi + fi else cmd="route delete -net $net -netmask $mask $gw" fi