diff --git a/xCAT-SoftLayer/bin/modifygrub b/xCAT-SoftLayer/bin/modifygrub index a2e70caff..2c3566e46 100755 --- a/xCAT-SoftLayer/bin/modifygrub +++ b/xCAT-SoftLayer/bin/modifygrub @@ -106,12 +106,13 @@ sub getNodeIpInfo { my @nics = grep(m/\s+master\s+$nic\s+/, @output); if (!scalar(@nics)) { die "Error: can't find the NICs that are part of $nic.\n"; } ($realnic) = $nics[0]=~m/^\d+:\s+(\S+): /; - # go back thru the ip add show output and find the mac of this nic - foreach my $line (@output) { - my ($nictmp, $mactmp, $foundnic); - if (($nictmp) = $line=~m/^\d+:\s+(\S+): / && $nictmp eq $realnic) { $foundnic = 1; } - if (($mactmp) = $line=~m|^\s+link/ether\s+(\S+) | && $foundnic) { $mac = $mactmp; last; } # got mac, we are done - } + # do not need to go back thru the ip addr show output and find the mac of this nic because the mac + # of the bond nic is the same. Plus the code below does not work right for some reason anyway. + #foreach my $line (@output) { + # my ($nictmp, $mactmp, $foundnic); + # if (($nictmp) = $line=~m/^\d+:\s+(\S+): / && $nictmp eq $realnic) { $foundnic = 1; } + # if (($mactmp) = $line=~m|^\s+link/ether\s+(\S+) | && $foundnic) { $mac = $mactmp; last; } # got mac, we are done + #} } # finally, find the gateway diff --git a/xCAT-SoftLayer/bin/pushinitrd b/xCAT-SoftLayer/bin/pushinitrd index bcad30198..fe7e88c83 100755 --- a/xCAT-SoftLayer/bin/pushinitrd +++ b/xCAT-SoftLayer/bin/pushinitrd @@ -207,7 +207,7 @@ sub modifyAutoinstFiles { # Copy softlayer specific systemimager post-install scripts to the systemimager location. # These cause si to use static ip and insert a wait into the bring up of the network. sub copySyscloneFiles { - my $cmd = "cp -f /opt/xcat/share/xcat/sysclone/post-install/* /install/sysclone/scripts/post-install"; + my $cmd = "cp -f /opt/xcat/share/xcat/sysclone/post-install/16all.updatenetwork /install/sysclone/scripts/post-install"; print "Copying SoftLayer-specific post scripts to the SystemImager post-install directory.\n"; runcmd($cmd); } diff --git a/xCAT-SoftLayer/postscripts/configbond b/xCAT-SoftLayer/postscripts/configbond new file mode 100755 index 000000000..0cd4e033d --- /dev/null +++ b/xCAT-SoftLayer/postscripts/configbond @@ -0,0 +1,228 @@ +#!/usr/bin/perl + +# xCAT postscript for configuring bonding of nics. +# Usage: configbond bond1 eth1 [eth3] +# +# Note: this postscript currently has some assumptions that are specific to the softlayer environment. +# It is only used to configure bond1, because bond0 gets configured by the node provisioning process. + +use strict; +# Check number of args + +my $nargs = $#ARGV + 1; +if (scalar(@ARGV) < 2 || scalar(@ARGV) > 3) { + system("logger -t xcat -p local4.err 'Usage: configbond bond dev0 [dev1]'"); + exit 1; +} + +my $bond = shift(@ARGV); +my $nic = $ARGV[0]; +my @devs = (); +push(@devs,$ARGV[0]); +if (defined($ARGV[1])) { push(@devs,$ARGV[1]); } +my $nicips = $ENV{NICIPS}; +my $nicnetworks = $ENV{NICNETWORKS}; +my $net_cnt = $ENV{NETWORKS_LINES}; + +#todo: these are specific to softlayer. They should be another attribute or argument +my $bondingopts = 'mode=4 miimon=100 downdelay=0 updelay=0 lacp_rate=fast xmit_hash_policy=1'; + +my $netmask =''; +my $ipaddr = ''; +my $nic_num = ''; +my $subnet = ''; +my $nic_net = ''; +my $net_name = ''; +my @nic_nets = (); # array of networks for this nic +my @nic_ips =(); # array of ipaddresses for this nic +my @networks = (); # array of all networks from networks table. + # { network_name, subnet, netmask } + +system("logger -t xcat -p local4.err 'configbond: Master: $bond'"); +system("logger -t xcat -p local4.err 'configbond: Slaves: @devs'"); +#system("logger -t xcat -p local4.err 'configbond: NIC: $nic'"); +system("logger -t xcat -p local4.err 'configbond: NICNETWORKS: $nicnetworks'"); +system("logger -t xcat -p local4.err 'configbond: NICIPS: $nicips'"); + +# Update modprobe +my $file = "/etc/modprobe.d/$bond.conf"; +if (!open(FILE, ">$file")) { system("logger -t xcat -p local4.err 'configbond: cannot open $file.'"); exit 1; } + +print FILE "alias $bond bonding\n"; +# the bonding options are put in the ifcfg file instead +#print FILE "options $bond mode=balance-rr miimon=100\n"; +close FILE; + +# create array of network info. Needed in case where there are +# more than one ip address per nic and shouldn't be many networks. +my $net_info; +my $cnt = 1; + +while ( $cnt <= $net_cnt ) { + $net_info = $ENV{"NETWORKS_LINE$cnt"}; + $net_info =~ /^netname=([^\|]*)\|\|/; + $net_name = $1; + $net_info =~ /net=([^\|]*)\|\|/; + $subnet = $1; + $net_info =~ /mask=([^\|]*)\|\|/; + $netmask = $1; + push @{ $networks[$cnt-1] }, ($net_name, $subnet, $netmask); + $cnt +=1; +} + +# get network or networks for this nic from NICNETWORKS: +# eth0:1_0_0_0-255_255_0_0|network2,eth1:1_1_0_0 +# create array of networks for this nic +foreach my $nic_networks (split(/,/,$nicnetworks)) { + my @net = (); + if ( $nic_networks =~ /!/ ) { + @net = split(/!/,$nic_networks); + } else { + @net = split(/:/,$nic_networks); + } + if ($net[0] eq $nic) { + @nic_nets = split(/\|/,$net[1]); + last; + } +} + +# get all nic ipaddress from $nicips: i.e. eth0:1.0.0.1|2.0.0.1,eth1:1.1.1.1 +# Then get all ips for this specific nic, i.e. eth0. +foreach my $ips (split(/,/,$nicips)) { + my @ip = (); + if ( $ips =~ /!/ ) { + @ip = split(/!/,$ips); + } else { + @ip = split(/:/,$ips); + } + if ($ip[0] eq $nic ) { + @nic_ips = split(/\|/,$ip[1]); + } +} + + +my $i; +for ($i=0; $i < (scalar @nic_ips) ; $i++ ) { + + # Time to create the interfaces. + # loop through the nic networks, find the matching networks to get the + # subnet and netmask and then create the appropriate ifcfg file for linux + my $specific_nic = $nic; + if ($i > 0) { + $specific_nic = $nic . ":" . ($i); + } + + #todo: support case in which nicnetworks is not specified, find the correct network by calculation + $cnt = 0; + $subnet = ""; + $netmask = ""; + $net_name = ""; + while ( $cnt < $net_cnt ) { + if ( $networks[$cnt][0] eq $nic_nets[$i] ) { + + $subnet = $networks[$cnt][1]; + $netmask = $networks[$cnt][2]; + $cnt = $net_cnt; # found match - get out. + } + else { + $cnt++; + } + } + + # check that there is a subnet and netmask set + if ( !(length($subnet) > 0) || !(length($netmask) > 0) ) { + system("logger -t xcat -p local4.err 'configbond: network subnet or netmask not set.'"); + exit 1; + } + system("logger -t xcat -p local4.err 'configbond: network subnet and netmask: $subnet, $netmask'"); + system("logger -t xcat -p local4.err 'configbond: $specific_nic, $nic_ips[$i]'"); + + # Write the master info to the ifcfg file + if (-d "/etc/sysconfig/network-scripts") { + # rhel/centos/fedora + my $dir = "/etc/sysconfig/network-scripts"; + if (!open(FILE, ">$dir/ifcfg-$bond")) { system("logger -t xcat -p local4.err 'configbond: cannot open $dir/ifcfg-$bond.'"); exit 1; } + + print FILE "DEVICE=$bond\n"; + print FILE "BOOTPROTO=none\n"; + print FILE "IPADDR=$nic_ips[$i]\n"; + print FILE "NETMASK=$netmask\n"; + print FILE "ONBOOT=yes\n"; + print FILE "USERCTL=no\n"; + print FILE qq(BONDING_OPTS="$bondingopts"\n); + close FILE; + + # Configure slaves + foreach my $dev (@devs) { + system("logger -t xcat -p local4.err 'configbond: slave dev: $dev'"); + if (!open(FILE, ">$dir/ifcfg-$dev")) { system("logger -t xcat -p local4.err 'configbond: cannot open $dir/ifcfg-$dev'"); exit 1; } + print FILE "DEVICE=$dev\n"; + print FILE "BOOTPROTO=none\n"; + print FILE "MASTER=$bond\n"; + print FILE "ONBOOT=yes\n"; + print FILE "SLAVE=yes\n"; + print FILE "USERCTL=no\n"; + close FILE; + } + } + elsif (-d "/etc/sysconfig/network") { + # sles + my $dir = "/etc/sysconfig/network"; + if (!open(FILE, ">$dir/ifcfg-$bond")) { system("logger -t xcat -p local4.err 'configbond: cannot open $dir/ifcfg-$bond.'"); exit 1; } + + print FILE "BOOTPROTO=static\n"; + print FILE "BONDING_MASTER=yes\n"; + print FILE "BONDING_MODULE_OPTS='$bondingopts'\n"; + print FILE "NAME='Bonded Interface'\n"; + print FILE "IPADDR=$nic_ips[$i]\n"; + print FILE "NETMASK=$netmask\n"; + print FILE "STARTMODE=onboot\n"; + print FILE "USERCONTROL=no\n"; + my $devnum = 0; + foreach my $dev (@devs) { + print FILE "BONDING_SLAVE_$devnum=$dev\n"; + $devnum++; + } + close FILE; + + # Configure slaves + foreach my $dev (@devs) { + system("logger -t xcat -p local4.err 'configbond: slave dev: $dev'"); + if (!open(FILE, ">$dir/ifcfg-$dev")) { system("logger -t xcat -p local4.err 'configbond: cannot open $dir/ifcfg-$dev'"); exit 1; } + print FILE "BOOTPROTO=none\n"; + print FILE "STARTMODE=hotplug\n"; + close FILE; + } + } + else { + # do not recognize this distro + system("logger -t xcat -p local4.err 'configbond: network directory is not either the Red Hat or SuSE format.'"); + exit 1; + } + + # Apply the changes. Since we are only doing bond1 right now, lets not restart the whole network + # so we dont disrupt the installnic connection. Instead we just need to bring down the slave nics, + # and then bring up the bond nic. + #runcmd("service network restart"); + foreach my $dev (@devs) { + runcmd("ifdown $dev"); + } + runcmd("ifdown $bond"); # in case it was already up + runcmd("ifup $bond"); # note: this wont reload the bonding kernel module, so we are depending on the provisioning process to already have set the correct bonding options + system("logger -t xcat -p local4.info 'configbond: successfully configured $specific_nic.'"); + +} +exit 0; + +sub runcmd { + my $cmd = shift @_; + $cmd .= ' 2>&1'; + my @output = `$cmd`; + my $rc = $? >> 8; + if ($rc) { + system("logger -t xcat -p local4.err 'configeth: command $cmd failed with rc $rc: " . join('',@output) . "'"); + my $errout= "configeth: command $cmd failed with rc $rc."; + `echo $errout`; + exit $rc; + } +} diff --git a/xCAT-SoftLayer/si-post-install/16all.updatenetwork b/xCAT-SoftLayer/si-post-install/16all.updatenetwork index 2d80690aa..db6830859 100755 --- a/xCAT-SoftLayer/si-post-install/16all.updatenetwork +++ b/xCAT-SoftLayer/si-post-install/16all.updatenetwork @@ -1,9 +1,12 @@ #!/bin/bash -# Configure network settings after SI has installed the OS +# SI post-install script to configure network settings after SI has installed the OS +# SI post-install scripts run in a chroot environment of the final OS image . /tmp/post-install/variables.txt +bondingopts='mode=4 miimon=100 downdelay=0 updelay=0 lacp_rate=fast xmit_hash_policy=1' + # determine if we should be using a static ip or dhcp staticIP () { # Eventually we should use the SI variable IP_ASSIGNMENT_METHOD below to determine this. @@ -35,11 +38,13 @@ if [ -n "$rule_file" ];then fi hostname $HOSTNAME +bond=bond0 device_names=`ifconfig -a | grep -i hwaddr | grep -i 'Ethernet' | grep -v usb| awk '{print $1}'` str_cfg_file='' if [ -d "/etc/sysconfig/network-scripts/" ];then #redhat + dir="/etc/sysconfig/network-scripts" grep -i HOSTNAME /etc/sysconfig/network if [ $? -eq 0 ];then sed -i "s/HOSTNAME=.*/HOSTNAME=$HOSTNAME/g" /etc/sysconfig/network @@ -47,21 +52,44 @@ if [ -d "/etc/sysconfig/network-scripts/" ];then echo "HOSTNAME=$HOSTNAME" >> /etc/sysconfig/network fi if staticIP; then + # delete all nic cfg files left over from the golden node + for i in $device_names;do + rm -f "$dir/ifcfg-$i" + done + # set static ip from variables in variables.txt - i="$DEVICE" - str_cfg_file="/etc/sysconfig/network-scripts/ifcfg-$i" + # write ifcfg-bond0. For now we assume the installnic should be part of bond0, + # because in SL i think that is always the case. + i="$bond" + str_cfg_file="$dir/ifcfg-$i" echo "DEVICE=$i" > $str_cfg_file - echo "BOOTPROTO=static" >> $str_cfg_file + echo "BOOTPROTO=none" >> $str_cfg_file echo "ONBOOT=yes" >> $str_cfg_file + echo "USERCTL=no" >> $str_cfg_file + echo 'BONDING_OPTS="'$bondingopts'"' >> $str_cfg_file echo "IPADDR=$IPADDR" >> $str_cfg_file echo "NETMASK=$NETMASK" >> $str_cfg_file echo "NETWORK=$NETWORK" >> $str_cfg_file echo "BROADCAST=$BROADCAST" >> $str_cfg_file #todo: add gateway config? Not sure, because the boot kernels gateway might not be the final OS gateway + + # write ifcfg-eth0 + i="$DEVICE" + str_cfg_file="$dir/ifcfg-$i" + echo "DEVICE=$i" > $str_cfg_file + echo "BOOTPROTO=none" >> $str_cfg_file + echo "MASTER=$bond" >> $str_cfg_file + echo "ONBOOT=yes" >> $str_cfg_file + echo "SLAVE=yes" >> $str_cfg_file + echo "USERCTL=no" >> $str_cfg_file + + # write modprobe alias config + str_cfg_file="/etc/modprobe.d/$bond.conf" + echo "alias $bond bonding" > $str_cfg_file else # use dhcp for all nics for i in $device_names;do - str_cfg_file="/etc/sysconfig/network-scripts/ifcfg-$i" + str_cfg_file="$dir/ifcfg-$i" echo "DEVICE=$i" > $str_cfg_file echo "BOOTPROTO=dhcp" >> $str_cfg_file echo "NM_CONTROLLED=yes" >> $str_cfg_file @@ -70,23 +98,54 @@ if [ -d "/etc/sysconfig/network-scripts/" ];then fi elif [ -d "/etc/sysconfig/network/" ];then #suse + dir="/etc/sysconfig/network" echo "$HOSTNAME" > /etc/HOSTNAME if staticIP; then + # delete all nic cfg files left over from the golden node + for i in $device_names;do + rm -f "$dir/ifcfg-$i" + done + # set static ip from variables in variables.txt - i="$DEVICE" - str_cfg_file="/etc/sysconfig/network/ifcfg-$i" - echo "DEVICE=$i" > $str_cfg_file - echo "BOOTPROTO=static" >> $str_cfg_file + # write ifcfg-bond0. For now we assume the installnic should be part of bond0, + # because in SL i think that is always the case. + i="$bond" + str_cfg_file="$dir/ifcfg-$i" + echo "BOOTPROTO=static" > $str_cfg_file echo "STARTMODE=onboot" >> $str_cfg_file + echo "BONDING_MASTER=yes" >> $str_cfg_file + echo "BONDING_MODULE_OPTS='$bondingopts'" >> $str_cfg_file + echo "NAME='Bonded Interface'" >> $str_cfg_file echo "IPADDR=$IPADDR" >> $str_cfg_file echo "NETMASK=$NETMASK" >> $str_cfg_file echo "NETWORK=$NETWORK" >> $str_cfg_file echo "BROADCAST=$BROADCAST" >> $str_cfg_file + echo "USERCONTROL=no" >> $str_cfg_file + echo "BONDING_SLAVE_0=$DEVICE" >> $str_cfg_file + + # write ifcfg-eth0 + i="$DEVICE" + str_cfg_file="$dir/ifcfg-$i" + echo "BOOTPROTO=none" > $str_cfg_file + echo "STARTMODE=hotplug" >> $str_cfg_file + + # write modprobe alias config + str_cfg_file="/etc/modprobe.d/$bond.conf" + echo "alias $bond bonding" > $str_cfg_file + + # this was the original config of the eth0 nic (without bonding) + #echo "DEVICE=$i" > $str_cfg_file + #echo "BOOTPROTO=static" >> $str_cfg_file + #echo "STARTMODE=onboot" >> $str_cfg_file + #echo "IPADDR=$IPADDR" >> $str_cfg_file + #echo "NETMASK=$NETMASK" >> $str_cfg_file + #echo "NETWORK=$NETWORK" >> $str_cfg_file + #echo "BROADCAST=$BROADCAST" >> $str_cfg_file #todo: add gateway config? Not sure, because the boot kernels gateway might not be the final OS gateway else # use dhcp for all nics for i in $device_names;do - str_cfg_file="/etc/sysconfig/network/ifcfg-$i" + str_cfg_file="$dir/ifcfg-$i" echo "DEVICE=$i" > $str_cfg_file echo "BOOTPROTO=dhcp" >> $str_cfg_file echo "STARTMODE=onboot" >> $str_cfg_file