From ba48f4a0d86f5d0ed4cb69dcc83ef60cc7161e97 Mon Sep 17 00:00:00 2001 From: linggao Date: Wed, 23 Jan 2013 18:36:42 +0000 Subject: [PATCH] Make routes persistent for sles/rh/ferdora/centos for makerouts command. git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@14966 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- perl-xCAT/xCAT/Schema.pm | 2 +- xCAT-server/lib/xcat/plugins/route.pm | 423 +++++++++++++++++++++++++- xCAT/postscripts/routeop | 168 +++++++++- 3 files changed, 566 insertions(+), 27 deletions(-) diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm index 26240f70c..47d683a4d 100644 --- a/perl-xCAT/xCAT/Schema.pm +++ b/perl-xCAT/xCAT/Schema.pm @@ -665,7 +665,7 @@ osimage => { synclists => 'The fully qualified name of a file containing a list of files to synchronize on the nodes. Can be a comma separated list of multiple synclist files. The synclist generated by PCM named /install/osimages//synclist.cfm is reserved for use only by PCM and should not be edited by the admin.', postscripts => 'Comma separated list of scripts that should be run on this image after diskfull installation or diskless boot. For installation of RedHat, CentOS, Fedora, the scripts will be run before the reboot. For installation of SLES, the scripts will be run after the reboot but before the init.d process. For diskless deployment, the scripts will be run at the init.d time, and xCAT will automatically add the list of scripts from the postbootscripts attribute to run after postscripts list. For installation of AIX, the scripts will run after the reboot and acts the same as the postbootscripts attribute. For AIX, use the postbootscripts attribute. See the site table runbootscripts attribute. Support will be added in the future for the postscripts attribute to run the scripts before the reboot in AIX. ', postbootscripts => 'Comma separated list of scripts that should be run on this after diskfull installation or diskless boot. On AIX these scripts are run during the processing of /etc/inittab. On Linux they are run at the init.d time. xCAT automatically adds the scripts in the xcatdefaults.postbootscripts attribute to run first in the list. See the site table runbootscripts attribute.', - serverrole => 'The role of the server created by this osimage. Default roles: mgtnode, servicenode, compute.', + serverrole => 'The role of the server created by this osimage. Supported roles: mgtnode, servicenode, compute, storage, utility, login.', isdeletable => 'A flag to indicate whether this image profile can be deleted. This attribute is only used by PCM.', kitcomponents => 'List of Kit Component IDs assigned to this OS Image definition.', comments => 'Any user-written notes.', diff --git a/xCAT-server/lib/xcat/plugins/route.pm b/xCAT-server/lib/xcat/plugins/route.pm index 3b827aad9..263279254 100644 --- a/xCAT-server/lib/xcat/plugins/route.pm +++ b/xCAT-server/lib/xcat/plugins/route.pm @@ -28,6 +28,15 @@ use Getopt::Long; use xCAT::NodeRange; use Data::Dumper; use xCAT::NodeRange; +use IO::File; +use File::Copy; +use Sys::Hostname; + + +my $xcat_config_start="# xCAT_CONFIG_START"; +my $xcat_config_end="# xCAT_CONFIG_END"; + + 1; @@ -61,7 +70,6 @@ sub handled_commands #------------------------------------------------------- sub preprocess_request { - my $request = shift; my $callback = shift; my $sub_req = shift; @@ -399,7 +407,7 @@ sub process_makeroutes { if ($remote) { #to the nodes my $nodes_tmp=$route_hash->{nodes}; - print "nodes=@$nodes_tmp, remote=$remote, delete=$delete\n"; + #print "nodes=@$nodes_tmp, remote=$remote, delete=$delete\n"; my $op="add"; if ($delete) { $op="delete"; } my $output = xCAT::Utils->runxcmd( @@ -415,10 +423,10 @@ sub process_makeroutes { $callback->($rsp); } else { #local on mn or sn if ($delete) { - delete_route($callback, $route_hash->{net}, $route_hash->{mask}, $gw_ip, $gw_name); + delete_route($callback, $route_hash->{net}, $route_hash->{mask}, $gw_ip, $gw_name, $route_hash->{ifname}); } else { - set_route($callback, $route_hash->{net}, $route_hash->{mask}, $gw_ip, $gw_name); + set_route($callback, $route_hash->{net}, $route_hash->{mask}, $gw_ip, $gw_name,$route_hash->{ifname}); } } } @@ -473,7 +481,6 @@ sub process_ipforward { } else { xCAT::NetworkUtils->setup_ip_forwarding(1); } - } @@ -548,6 +555,11 @@ sub set_route { my $mask = shift; my $gw_ip = shift; my $gw=shift; + my $ifname=shift; + + my $host=hostname(); + + #print "set_route get called\n"; my $result; if (!route_exists($net, $mask, $gw_ip, $gw)) { @@ -559,19 +571,61 @@ sub set_route { $cmd="route add -net $net -netmask $mask $gw_ip"; } #print "cmd=$cmd\n"; + my $rsp={}; + $rsp->{data}->[0]= "$host: Adding temporary route: $cmd"; + $callback->($rsp); + $result=`$cmd 2>&1`; if ($? != 0) { my $rsp={}; - $rsp->{error}->[0]= "$cmd\nerror code=$?, result=$result\n"; + $rsp->{error}->[0]= "$host: $cmd\nerror code=$?, result=$result\n"; $callback->($rsp); - return 1; - } else { - #TODO: set per permanent route - } + #return 1; + } + } else { + my $rsp={}; + $rsp->{data}->[0]= "$host: The temporary route already exists for $net."; + $callback->($rsp); } + + #handle persistent routes + if (xCAT::Utils->isLinux()) { #Linux + my $os = xCAT::Utils->osver(); + #print "os=$os $net, $mask, $gw_ip, $gw, $ifname\n"; + if ($os =~ /sles/) { #sles + addPersistentRoute_Sles($callback, $net, $mask, $gw_ip, $gw, $ifname); + } elsif ($os =~ /ubuntu/) { #ubuntu or Debian? + #my $filename="/etc/network/interfaces"; + #my @output=getConfig($filename); + #Example: + #auto eth0 + #iface eth0 inet static + # address 192.168.1.2 + # netmask 255.255.255.0 + # gateway 192.168.1.254 + # up route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.2.1 + # down route del -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.2.1 + my $rsp={}; + $rsp->{data}->[0]= "$host: Adding persistent route on Ubuntu is not supported yet."; + $callback->($rsp); + + } + elsif ($os =~ /rh|fedora|centos/) { #RH, Ferdora, CentOS + addPersistentRoute_RH($callback, $net, $mask, $gw_ip, $gw, $ifname); + } + } else { #AIX + # chdev -l inet0 -a route=net,-hopcount,0,,0,192.168.1.1 + # chdev -l inet0 -a route=net, -hopcount,255.255.255.128,,,,,192.168.3.155,192.168.2.1 + # lsattr -El inet0 -a route + my $rsp={}; + $rsp->{data}->[0]= "$host: Adding persistent route on AIX is not supported yet."; + $callback->($rsp); + } + return 0; } + # deletes the route with given parameters sub delete_route { my $callback=shift; @@ -579,6 +633,11 @@ sub delete_route { my $mask = shift; my $gw_ip = shift; my $gw=shift; + my $ifname=shift; + + my $host=hostname(); + + #print "delete_route get called\n"; my $result; if (route_exists($net, $mask, $gw_ip, $gw)) { @@ -590,17 +649,353 @@ sub delete_route { $cmd="route delete -net $net -netmask $mask $gw_ip"; } #print "cmd=$cmd\n"; + my $rsp={}; + $rsp->{data}->[0]= "$host: Removin the temporary route: $cmd"; + $callback->($rsp); + $result=`$cmd 2>&1`; if ($? != 0) { my $rsp={}; - $rsp->{error}->[0]= "$cmd\nerror code=$?, result=$result\n"; + $rsp->{error}->[0]= "$host: $cmd\nerror code=$?, result=$result\n"; $callback->($rsp); - return 1; - } else { - #TODO: delete route permanently } + } else { + my $rsp={}; + $rsp->{data}->[0]= "$host: The temporary route does not exist for $net."; + $callback->($rsp); + + } + + #handle persistent route + if (xCAT::Utils->isLinux()) { #Linux + my $os = xCAT::Utils->osver(); + if ($os =~ /sles/) { #sles + deletePersistentRoute_Sles($callback, $net, $mask, $gw_ip, $gw, $ifname); + } elsif ($os =~ /ubuntu/) { #ubuntu or Debian? + #my $filename="/etc/network/interfaces"; + #my @output=getConfig($filename); + #Example: + #auto eth0 + #iface eth0 inet static + # address 192.168.1.2 + # netmask 255.255.255.0 + # gateway 192.168.1.254 + # up route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.2.1 + # down route del -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.2.1 + my $rsp={}; + $rsp->{data}->[0]= "$host: Removing persistent route on Ubuntu is not supported yet."; + $callback->($rsp); + } + elsif ($os =~ /rh|fedora|centos/) { #RH, Ferdora + deletePersistentRoute_RH($callback, $net, $mask, $gw_ip, $gw, $ifname); + } + } else { #AIX + # chdev -l inet0 -a delroute=net,-hopcount,0,,0,192.168.1.1 + # chdev -l inet0 -a delroute=net,-hopcount,255.255.255.128,,,,,192.168.3.128,192.168.2.1 + my $rsp={}; + $rsp->{data}->[0]= "$host: Removing persistent route on AIX is not supported yet."; + $callback->($rsp); + } + + return 0; +} + + +#set the given route to the configuration file +sub setConfig { + my $filename=shift; + my $new_conf_block=shift; + #print "filename=$filename\n"; + + my $new_config=join("\n", @$new_conf_block); + my $last_char = substr $new_config,-1,1; + if ($last_char ne "\n") { $new_config .= "\n"; } + + my $filename_tmp = "$filename.$$"; + open (OUTFILE, '>', $filename_tmp); + my $found=0; + if (-f $filename) { + open (INFILE, '<', $filename); + my $inblock=0; + while () { + my $line=$_; + if (!$inblock) { + print OUTFILE $line; + } + if ($line =~ /$xcat_config_start/) { + $found=1; + $inblock=1; + print OUTFILE $new_config; + } elsif ($line =~ /$xcat_config_end/) { + $inblock=0; + print OUTFILE "$xcat_config_end\n"; + } + } + } + if (!$found) { + print OUTFILE "$xcat_config_start\n"; + print OUTFILE $new_config; + print OUTFILE "$xcat_config_end\n"; + } + close (INFILE); + close (OUTFILE); + copy($filename_tmp, $filename); + unlink($filename_tmp); +} + +#gets the xCAT configurations from the given file +sub getConfig { + my $filename=shift; + my @output=(); + if (-f $filename) { + open(FILE, "<", $filename); + my $xcatconf = 0; + my $first=0; + while () { + chomp; + if (/$xcat_config_start/) { + $xcatconf = 1; + $first=1; + } + elsif (/$xcat_config_end/) { + $xcatconf = 0; + } + if ($first) { + $first=0; + next; + } + + if ($xcatconf) { + push @output, $_; + } + } + } + return @output; +} + +#add the routes to the /etc/sysconfig/network/routes file +#The format is: destination gateway mask ifname +sub addPersistentRoute_Sles { + my $callback=shift; + my $net=shift; + my $mask=shift; + my $gw_ip=shift; + my $gw=shift; + my $ifname=shift; + + my $host=hostname(); + + my $filename="/etc/sysconfig/network/routes"; + my @output=getConfig($filename); + #print "old output=" . join("\n", @output) . "\n"; + my $hasConfiged=0; + if (@output && (@output > 0)) { + $hasConfiged=checkConfig_Sles($net, $mask, $gw_ip, $gw, \@output); + } + #print "hasConfiged=$hasConfiged\n"; + my $new_config="$net $gw_ip $mask $ifname\n"; + if (!$hasConfiged) { + push(@output, $new_config); + #print "new output=" . join("\n", @output) . "\n"; + #Add the route to the configuration file + #the format is: destination gateway mask ifname + setConfig($filename, \@output); + + chomp($new_config); + my $rsp={}; + $rsp->{data}->[0]= "$host: Added persistent route \"$new_config\" to $filename."; + $callback->($rsp); + } else { + chomp($new_config); + my $rsp={}; + $rsp->{data}->[0]= "$host: Persistent route \"$new_config\" already exists in $filename."; + $callback->($rsp); + } +} + +#remove the routes from the /etc/sysconfig/network/routes file +sub deletePersistentRoute_Sles { + my $callback=shift; + my $net=shift; + my $mask=shift; + my $gw_ip=shift; + my $gw=shift; + my $ifname=shift; + + my $host=hostname(); + + my $filename="/etc/sysconfig/network/routes"; + my @output=getConfig($filename); + #print "old output=" . join("\n", @output) . "\n"; + my @new_output=(); + my $bigfound=0; + foreach my $tmp_conf (@output) { + my $found = checkConfig_Sles($net, $mask, $gw_ip, $gw, [$tmp_conf]); + if (!$found) { + push(@new_output, $tmp_conf); + } else { + $bigfound=1; + } + } + #print "new output=" . join("\n", @new_output) . "\n"; + #set the new configuration to the configuration file + setConfig($filename, \@new_output); + if ($bigfound) { + my $rsp={}; + $rsp->{data}->[0]= "$host: Removed persistent route \"$net $gw_ip $mask $ifname\" from $filename."; + $callback->($rsp); + } else { + my $rsp={}; + $rsp->{data}->[0]= "$host: Persistent route \"$net $gw_ip $mask $ifname\" does not exist in $filename."; + $callback->($rsp); + } +} + + + +#check if the route is in the SLES network configuration file +sub checkConfig_Sles { + my $net = shift; + my $mask = shift; + my $gw_ip = shift; + my $gw=shift; + my $output=shift; + + foreach my $line (@$output) { + my @a=split(' ', $line); + my ($net1,$mask1,$gw1); + if (@a>0) { + $net1=$a[0]; + if ($net1 eq '-') { $net1=$net;} + } + if (@a>1) { + $gw1=$a[1]; + if ($gw1 eq '-') { $gw1=$gw_ip; } + } + if (@a>2) { + $mask1=$a[2]; + if ($mask1 eq '-') { $mask1=$mask;} + } + + #print "net=$net1,$net mask=$mask1,$mask gw=$gw1,$gw_ip\n"; + if (($net1 && $net1 eq $net) && ($mask1 && $mask1 eq $mask) && (($gw1 && $gw1 eq $gw) || ($gw1 && $gw1 eq $gw_ip))) { + return 1; + } + } + return 0; +} + +#add the routes to the /etc/sysconfig/static-routes file +#The format is: any net 172.16.0.0 netmask 255.240.0.0 gw 192.168.0.1 eth0 +sub addPersistentRoute_RH { + my $callback=shift; + my $net=shift; + my $mask=shift; + my $gw_ip=shift; + my $gw=shift; + my $ifname=shift; + + my $host=hostname(); + + my $filename="/etc/sysconfig/static-routes"; + my @output=getConfig($filename); + #print "old output=" . join("\n", @output) . "\n"; + my $hasConfiged=0; + if (@output && (@output > 0)) { + $hasConfiged=checkConfig_RH($net, $mask, $gw_ip, $gw, \@output); + } + #print "hasConfiged=$hasConfiged\n"; + my $new_config="any net $net netmask $mask gw $gw_ip $ifname\n"; + if (!$hasConfiged) { + push(@output, $new_config); + #print "new output=" . join("\n", @output) . "\n"; + #Add the route to the configuration file + #the format is: destination gateway mask ifname + setConfig($filename, \@output); + + chomp($new_config); + my $rsp={}; + $rsp->{data}->[0]= "$host: Added persistent route \"$new_config\" to $filename."; + $callback->($rsp); + } else { + chomp($new_config); + my $rsp={}; + $rsp->{data}->[0]= "$host: Persistent route \"$new_config\" already exists in $filename."; + $callback->($rsp); + } +} + +#remove the routes from the /etc/sysconfig/static-routes file +sub deletePersistentRoute_RH { + my $callback=shift; + my $net=shift; + my $mask=shift; + my $gw_ip=shift; + my $gw=shift; + my $ifname=shift; + + my $host=hostname(); + + my $filename="/etc/sysconfig/static-routes"; + my @output=getConfig($filename); + #print "old output=" . join("\n", @output) . "\n"; + my @new_output=(); + my $bigfound=0; + foreach my $tmp_conf (@output) { + my $found = checkConfig_RH($net, $mask, $gw_ip, $gw, [$tmp_conf]); + if (!$found) { + push(@new_output, $tmp_conf); + } else { + $bigfound=1; + } + } + #print "new output=" . join("\n", @new_output) . "\n"; + #set the new configuration to the configuration file + setConfig($filename, \@new_output); + if ($bigfound) { + my $rsp={}; + $rsp->{data}->[0]= "$host: Removed persistent route \"any net $net netmask $mask gw $gw_ip $ifname\" from $filename."; + $callback->($rsp); + } else { + my $rsp={}; + $rsp->{data}->[0]= "$host: Persistent route \"any net $net netmask $mask gw $gw_ip $ifname\" does not exist in $filename."; + $callback->($rsp); + } +} + +sub checkConfig_RH { + my $net = shift; + my $mask = shift; + my $gw_ip = shift; + my $gw=shift; + my $output=shift; + + foreach my $line (@$output) { + my @a=split(' ', $line); + #The format is: any net 172.16.0.0 netmask 255.240.0.0 gw 192.168.0.1 eth0 + my ($net1,$mask1,$gw1); + if (@a>2) { + $net1=$a[2]; + if ($net1 eq '-') { $net1=$net;} + } + if (@a>4) { + $mask1=$a[4]; + if ($mask1 eq '-') { $mask1=$mask;} + } + if (@a>6) { + $gw1=$a[6]; + if ($gw1 eq '-') { $gw1=$gw_ip; } + } + + #print "net=$net1,$net mask=$mask1,$mask gw=$gw1,$gw_ip\n"; + if (($net1 && $net1 eq $net) && ($mask1 && $mask1 eq $mask) && (($gw1 && $gw1 eq $gw) || ($gw1 && $gw1 eq $gw_ip))) { + return 1; + } } return 0; } + + + diff --git a/xCAT/postscripts/routeop b/xCAT/postscripts/routeop index fbe6b6e15..d47d71bed 100755 --- a/xCAT/postscripts/routeop +++ b/xCAT/postscripts/routeop @@ -75,42 +75,186 @@ route_exists() echo $ret } -result=$(route_exists $net $mask $gw) -if [ "$result" = "0" ]; then - if [ "$op" = "add" ]; then +add_persistent_route() +{ + net=$1; + mask=$2; + gw=$3; + if [ -n "$4" ]; then + ifname=$4 + fi + + xcat_config_start="# xCAT_CONFIG_START"; + xcat_config_end="# xCAT_CONFIG_END"; + + if [ "$(uname -s)" = "Linux" ]; then + #determine the os name + OS_name="something" + if [ -f /etc/redhat-release ] + then + OS_name="redhat" #it can be RedHatFerdora or CentOS + elif [ -f /etc/SuSE-release ] + then + OS_name="sles" + fi + + case $OS_name in + sles) + #echo "sles" + filename="/etc/sysconfig/network/routes"; + route="$net $gw $mask $ifname"; + if [ -f $filename ]; then + grep "$route" $filename + if [ $? -ne 0 ]; then #route does not exist + grep "$xcat_config_start" $filename + if [ $? -ne 0 ]; then #no xCAT section + echo $xcat_config_start >> $filename + echo $route >> $filename + echo $xcat_config_end >> $filename + else + sed -i -e s/"$xcat_config_end"/"$route\n$xcat_config_end"/g $filename + fi + echo "Persistent route \"$route\" added in $filename." + else + echo "Persistent route \"$route\" already exists in $filename." + fi + else + #echo "got here" + echo "$xcat_config_start" > $filename + echo "$route" >> $filename + echo "$xcat_config_end" >> $filename + echo "Route \"$route\" added in $filename." + fi + + ;; + ubuntu*) + echo "Adding persistent route on Ubuntu is not supported yet." + ;; + redhat) + #echo "rh/fedora/centos" + filename="/etc/sysconfig/static-routes"; + route="any net $net netmask $mask gw $gw $ifname"; + if [ -f $filename ]; then + grep "$route" $filename + if [ $? -ne 0 ]; then #route does not exist + grep "$xcat_config_start" $filename + if [ $? -ne 0 ]; then #no xCAT section + echo $xcat_config_start >> $filename + echo $route >> $filename + echo $xcat_config_end >> $filename + else + sed -i -e s/"$xcat_config_end"/"$route\n$xcat_config_end"/g $filename + fi + echo "Persistent route \"$route\" added in $filename." + else + echo "Persistent route \"$route\" already exists in $filename." + fi + else + #echo "got here" + echo "$xcat_config_start" > $filename + echo "$route" >> $filename + echo "$xcat_config_end" >> $filename + echo "Persistent route \"$route\" added in $filename." + fi + ;; + esac + else #AIX + echo "Adding persistent route on AIX is not supported yet." + fi +} + +rm_persistent_route() +{ + net=$1; + mask=$2; + gw=$3; + if [ -n "$4" ]; then + ifname=$4 + fi + + if [ "$(uname -s)" = "Linux" ]; then + #determine the os name + OS_name="something" + if [ -f /etc/redhat-release ] + then + OS_name="redhat" #it can be RedHatFerdora or CentOS + elif [ -f /etc/SuSE-release ] + then + OS_name="sles" + fi + + case $OS_name in + sles) + #echo "sles" + filename="/etc/sysconfig/network/routes"; + route="$net $gw $mask $ifname"; + if [ -f $filename ]; then + sed -i -e s/"$route"//g $filename + fi + echo "Persistent route \"$route\" removed from $filename." + ;; + ubuntu*) + echo "Removing persistent route on Ubuntu is not supported yet." + ;; + redhat) + #echo "rh/fedora/centos" + filename="/etc/sysconfig/static-routes"; + route="any net $net netmask $mask gw $gw $ifname"; + if [ -f $filename ]; then + sed -i -e s/"$route"//g $filename + fi + echo "Persistent route \"$route\" removed from $filename." + ;; + esac + else #AIX + echo "Removing persistent route on AIX is not supported yet." + fi +} + + + +if [ "$op" = "add" ]; then + result=$(route_exists $net $mask $gw) + if [ "$result" = "0" ]; then if [ "$(uname -s)" = "Linux" ]; then cmd="route add -net $net netmask $mask gw $gw" else cmd="route add -net $net -netmask $mask $gw" fi - echo "$cmd" + echo "Adding temporary route: $cmd" result=`$cmd 2>&1` code=$? if [ $code -ne 0 ]; then logger -t xCAT -p local4.err "$cmd\nerror code=$code, result=$result." echo " error code=$code, result=$result." - exit 1; + #exit 1; fi else - echo "The route ($net $mask $gw) does not exist." - fi -else - if [ "$op" = "delete" ]; then + echo "The temporary route ($net $mask $gw) already exists." + fi + + #add persistent route + add_persistent_route $net $mask $gw $ifname +elif [ "$op" = "delete" ]; then + result=$(route_exists $net $mask $gw) + if [ "$result" = "1" ]; then if [ "$(uname -s)" = "Linux" ]; then cmd="route delete -net $net netmask $mask gw $gw" else cmd="route delete -net $net -netmask $mask $gw" fi - echo "$cmd" + echo "Removing temporary route: $cmd" result=`$cmd 2>&1` code=$? if [ $code -ne 0 ]; then logger -t xCAT -p local4.err "$cmd\nerror code=$code, result=$result." echo " error code=$code, result=$result." - exit 1; fi else - echo "The route ($net $mask $gw) already exists." + echo "The temporary route ($net $mask $gw) does not exist." fi + + #remove the persistent route + rm_persistent_route $net $mask $gw $ifname fi exit 0