diff --git a/perl-xCAT/xCAT/Utils.pm b/perl-xCAT/xCAT/Utils.pm index 59657fc76..6d156836d 100644 --- a/perl-xCAT/xCAT/Utils.pm +++ b/perl-xCAT/xCAT/Utils.pm @@ -17,7 +17,7 @@ require xCAT::NodeRange; require DBI; our @ISA = qw(Exporter); -our @EXPORT_OK = qw(genpassword); +our @EXPORT_OK = qw(genpassword getsynclistfile); my $utildata; #data to persist locally #-------------------------------------------------------------------------------- diff --git a/xCAT-server/lib/xcat/plugins/packimage.pm b/xCAT-server/lib/xcat/plugins/packimage.pm index 33b4e0d3b..cd85fe98f 100644 --- a/xCAT-server/lib/xcat/plugins/packimage.pm +++ b/xCAT-server/lib/xcat/plugins/packimage.pm @@ -5,7 +5,7 @@ use File::Path; use File::Copy; use Cwd; use File::Temp; -use xCAT::Utils qw(genpassword); +use xCAT::Utils qw(genpassword getsynclistfile); Getopt::Long::Configure("bundling"); Getopt::Long::Configure("pass_through"); @@ -134,6 +134,13 @@ sub process_request { } } + # sync fils configured in the synclist to the rootimage + my $syncfile = xCAT::Utils->getsynclistfile(undef, $osver, $arch, $profile, "netboot"); + if (defined ($syncfile) && -f $syncfile + && -d "$installroot/netboot/$osver/$arch/$profile/rootimg") { + print "sync files from $syncfile to the $installroot/netboot/$osver/$arch/$profile/rootimg\n"; + `$::XCATROOT/bin/xdcp -i "$installroot/netboot/$osver/$arch/$profile/rootimg" -F $syncfile`; + } my $verb = "Packing"; if ($method =~ /nfs/) { diff --git a/xCAT-server/lib/xcat/plugins/syncfiles.pm b/xCAT-server/lib/xcat/plugins/syncfiles.pm index cf1011eff..7bb8e14d8 100644 --- a/xCAT-server/lib/xcat/plugins/syncfiles.pm +++ b/xCAT-server/lib/xcat/plugins/syncfiles.pm @@ -57,11 +57,6 @@ sub process_request } require xCAT::Postage; - my $rc = xCAT::Postage->syncfiles($client,$callback,$subreq); - if ($rc) { - xCAT::MsgUtils->message("S","Sync files to node $client completed"); - } else { - xCAT::MsgUtils->message("S","Encountered error when using xdcp sync files to $client"); - } + xCAT::Postage->syncfiles($client,$callback,$subreq); } diff --git a/xCAT-server/lib/xcat/plugins/updatenode.pm b/xCAT-server/lib/xcat/plugins/updatenode.pm index 3a5a0a5cc..3df65a075 100644 --- a/xCAT-server/lib/xcat/plugins/updatenode.pm +++ b/xCAT-server/lib/xcat/plugins/updatenode.pm @@ -133,11 +133,14 @@ sub preprocess_updatenode { my $cb=shift; my $rsp={}; $rsp->{data}->[0]= "Usage:"; - $rsp->{data}->[1]= " updatenode [-s | -S] [posts]"; + $rsp->{data}->[1]= " updatenode [-F] [-S] [-P] [postscript,...]"; $rsp->{data}->[2]= " updatenode [-h|--help|-v|--version]"; - $rsp->{data}->[3]= " noderange is a list of nodes or groups."; - $rsp->{data}->[4]= " posts is a comma separated list of postscript names."; - $rsp->{data}->[5]= " if omitted, all the postscripts will be run."; + $rsp->{data}->[3]= " is a list of nodes or groups."; + $rsp->{data}->[4]= " -F: Perform File Syncing."; + $rsp->{data}->[5]= " -S: Perform Software Maintenance."; + $rsp->{data}->[6]= " -p: Re-run Postscripts listed in postscript."; + $rsp->{data}->[7]= " [postscript,...] is a comma separated list of postscript names."; + $rsp->{data}->[8]= " If omitted, all the postscripts defined for the nodes will be run."; $cb->($rsp); } @@ -151,10 +154,11 @@ sub preprocess_updatenode { Getopt::Long::Configure("bundling"); Getopt::Long::Configure("no_pass_through"); if(!GetOptions( - 'h|help' => \$::HELP, + 'h|help' => \$::HELP, 'v|version' => \$::VERSION, - 's' => \$::SYNCSN, - 'S' => \$::SKIPSYNCFILE )) + 'F' => \$::FILESYNC, + 'S' => \$::SWMAINTENANCE, + 'P:s' => \$::RERUNPS)) { &updatenode_usage($callback); return \@requests;; @@ -187,40 +191,44 @@ sub preprocess_updatenode { if (@nodes == 0) { return \@requests; } if (@ARGV > 0) { - $postscripts=$ARGV[0]; - my @posts=split(',',$postscripts); - foreach (@posts) { - if ( ! -e "/install/postscripts/$_") { - my $rsp={}; - $rsp->{data}->[0]= "The postcript /install/postscripts/$_ does not exist."; - $callback->($rsp); - return \@requests; + &updatenode_usage($callback); + return \@requests; + } + + # If -F option specified, sync files to the noderange. + # Note: This action only happens on MN, since xdcp handles the hierarchical scenario + if ($::FILESYNC) { + my $reqcopy = {%$request}; + $reqcopy->{FileSyncing} = "yes"; + push @requests, $reqcopy; + } + + # handle the re-run postscripts option -P + if (defined ($::RERUNPS)) { + if ($::RERUNPS eq "") { + $postscripts = ""; + } else { + $postscripts=$::RERUNPS; + my @posts=split(',',$postscripts); + foreach (@posts) { + if ( ! -e "/install/postscripts/$_") { + my $rsp={}; + $rsp->{data}->[0]= "The postcript /install/postscripts/$_ does not exist."; + $callback->($rsp); + return \@requests; + } } } } - # If -s argument specified, sync files to the service nodes firstly - if ($::SYNCSN) { - my %syncfile_node = (); - my $node_syncfile = xCAT::Utils->getsynclistfile($nodes); - foreach my $node (@$nodes) { - my $synclist = $$node_syncfile{$node}; - - if ($synclist) { - push @{$syncfile_node{$synclist}}, $node; - next; - } - } - - foreach my $syncfile (keys %syncfile_node) { - my $arg = ["-s", "-F", "$syncfile"]; - my $env = ["RSYNCSN=yes", "DSH_RSYNC_FILE=$syncfile"]; - $subreq->({command=>['xdcp'], node=>$syncfile_node{$syncfile}, arg=>$arg, env=>$env}, $callback); - } - } + # when specified -S or -P # find service nodes for requested nodes # build an individual request for each service node + unless (defined($::SWMAINTENANCE) || defined($::RERUNPS)) { + return \@requests; + } + my $sn = xCAT::Utils->get_ServiceNode(\@nodes, "xcat", "MN"); # build each request for each service node @@ -229,11 +237,18 @@ sub preprocess_updatenode { my $reqcopy = {%$request}; $reqcopy->{node} = $sn->{$snkey}; $reqcopy->{'_xcatdest'} = $snkey; - $reqcopy->{postscripts} = [$postscripts]; + if (defined ($::SWMAINTENANCE)) { + $reqcopy->{swmaintenance} = "yes"; + } + if (defined ($::RERUNPS)) { + $reqcopy->{rerunps} = "yes"; + $reqcopy->{postscripts} = [$postscripts]; + } + push @requests, $reqcopy; } - return \@requests; + return \@requests; } @@ -253,13 +268,11 @@ sub updatenode { my $request = shift; my $callback = shift; my $subreq = shift; - my $postscripts=""; - if (($request->{postscripts}) && ($request->{postscripts}->[0])) { $postscripts=$request->{postscripts}->[0];} + my $nodes =$request->{node}; my $localhostname=hostname(); - # if not specifying -S, do the sync file operation - unless ($::SKIPSYNCFILE) { + if ($request->{FileSyncing} && $request->{FileSyncing} eq "yes") { my %syncfile_node = (); my %syncfile_rootimage = (); my $node_syncfile = xCAT::Utils->getsynclistfile($nodes); @@ -269,21 +282,6 @@ sub updatenode { if ($synclist) { push @{$syncfile_node{$synclist}}, $node; } - - # Figure out the directory of the root image - # one $synclist will only map to one root image, so - # just find the root image one time - # only for netboot node (diskless) - if ($synclist && $synclist =~ /\/netboot\//) { - if (! defined($syncfile_rootimage{$synclist})) { - my $root_dir = xCAT::Utils->getrootimage($node); - if (-d $root_dir) { - $syncfile_rootimage{$synclist} = $root_dir; - } else { - $syncfile_rootimage{$synclist} = "no_root_image"; - } - } - } } # Sync files to the target nodes @@ -292,28 +290,18 @@ sub updatenode { my $env = ["DSH_RSYNC_FILE=$synclist"]; $subreq->({command=>['xdcp'], node=>$syncfile_node{$synclist}, arg=>$args, env=>$env}, $callback); } - - # Sync files to the root image for the diskless nodes - foreach my $synclist (keys %syncfile_rootimage) { - if ($syncfile_rootimage{$synclist} eq "no_root_image") { - next; - } - my $args = ["-i", $syncfile_rootimage{$synclist}, "-F", $synclist]; - my $env = ["DSH_RSYNC_FILE=$synclist"]; - $subreq->({command=>['xdcp'], arg=>$args, env=>$env}, $callback); - } } - my $nodestring=join(',', @$nodes); - #print "postscripts=$postscripts, nodestring=$nodestring\n"; - - if ($nodestring) { + if ($request->{swmaintenance} && $request->{swmaintenance} eq "yes") { my $cmd; + my $nodestring=join(',', @$nodes); if (xCAT::Utils->isLinux()) { - $cmd="XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e /install/postscripts/xcatdsklspost 1 $postscripts 2>&1"; + $cmd="XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e /install/postscripts/xcatdsklspost 2 otherpkgs 2>&1"; } else { - $cmd="XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e /install/postscripts/xcataixpost -c 1 $postscripts 2>&1"; + my $rsp={}; + $rsp->{data}->[0]= "Dose not support Software Maintenance for AIX nodes"; + $callback->($rsp); } if (! open (CMD, "$cmd |")) { my $rsp={}; @@ -329,8 +317,37 @@ sub updatenode { } } - return 0; + if ($request->{rerunps} && $request->{rerunps} eq "yes") { + my $postscripts=""; + if (($request->{postscripts}) && ($request->{postscripts}->[0])) { $postscripts=$request->{postscripts}->[0];} + + my $nodestring=join(',', @$nodes); + #print "postscripts=$postscripts, nodestring=$nodestring\n"; + if ($nodestring) { + my $cmd; + if (xCAT::Utils->isLinux()) { + $cmd="XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e /install/postscripts/xcatdsklspost 1 $postscripts 2>&1"; + } + else { + $cmd="XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e /install/postscripts/xcataixpost -c 1 $postscripts 2>&1"; + } + if (! open (CMD, "$cmd |")) { + my $rsp={}; + $rsp->{data}->[0]= "Cannot run command $cmd"; + $callback->($rsp); + } else { + while () { + my $rsp={}; + $rsp->{data}->[0]= "$_"; + $callback->($rsp); + } + close(CMD); + } + } + } + + return 0; } diff --git a/xCAT/postscripts/startsyncfiles.aix b/xCAT/postscripts/startsyncfiles.aix index dc18761af..10b1be39f 100644 --- a/xCAT/postscripts/startsyncfiles.aix +++ b/xCAT/postscripts/startsyncfiles.aix @@ -9,32 +9,46 @@ # ##################################################### +use XML::Simple; -use IO::Socket; +my $useSocketSSL=eval { require IO::Socket::SSL; }; +if ($useSocketSSL) { + require IO::Socket::SSL; +} -my $port = "3002"; -my $remote = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $ENV{MASTER}, PeerPort => $port, ); +my $port = "3001"; +my $remote = IO::Socket::SSL->new( Proto => "tcp", PeerAddr => $ENV{MASTER}, PeerPort => $port, ); unless ($remote) { `logger -t xCAT "startsyncfiles: Cannot connect to host $ENV{MASTER}"`; exit 0; } -$remote->autoflush(1); +# Send Syncing File request to the xcatd +print $remote "\n"; +print $remote " syncfiles\n"; +print $remote "\n"; -while (defined (my $line = <$remote>)) { - chomp($line); - if ($line =~ /ready/) { - print $remote "syncfiles\n"; - } +my $response=''; +my $rsp; +while (<$remote>) { + $response .= $_; + if ($response =~ m/<\/xcatresponse>/) { + $rsp = eval { XMLin($response,SuppressEmpty=>undef,ForceArray=>1) }; + if ($rsp->{serverdone}) { + close $remote; + exit 1; + } - if ($line =~ /syncfiles done/) { - close $remote; - exit 1; + if ($rsp->{errorcode} || $rsp->{error}) { + close $remote; + exit 0; + } + $response=''; } } + close $remote; - -exit 1; +exit 0; diff --git a/xCAT/postscripts/startsyncfiles.awk b/xCAT/postscripts/startsyncfiles.awk index a1492075f..429962790 100755 --- a/xCAT/postscripts/startsyncfiles.awk +++ b/xCAT/postscripts/startsyncfiles.awk @@ -1,20 +1,25 @@ #!/usr/bin/awk -f BEGIN { - server = "openssl s_client -quiet -connect " ENVIRON["XCATSERVER"] + server = "openssl s_client -quiet -connect " ENVIRON["XCATSERVER"] - quit = "no" + quit = "no" + exitcode = 1 - print "" |& server - print " syncfiles" |& server - print "" |& server + print "" |& server + print " syncfiles" |& server + print "" |& server - while (server |& getline) { - if (match($0,"")) { - quit = "yes" - } - if (match($0,"") && match(quit,"yes")) { - close(server) - exit - } - } + while (server |& getline) { + if (match($0,"")) { + quit = "yes" + } + if (match($0,"") || match($0,"")) { + exitcode = 0 + } + + if (match($0,"") && match(quit,"yes")) { + close(server) + exit exitcode + } + } } diff --git a/xCAT/postscripts/syncfiles b/xCAT/postscripts/syncfiles index 268c9764a..81fc92a20 100644 --- a/xCAT/postscripts/syncfiles +++ b/xCAT/postscripts/syncfiles @@ -21,12 +21,21 @@ osname=`uname` # run the xdcp on the MN/SN xcatpostdir="/xcatpost" -if [ $osname="Linux" ] +if [ $osname = "Linux" ] then - `$xcatpostdir/startsyncfiles.awk` -elif [ $osname="AIX" ] +`$xcatpostdir/startsyncfiles.awk` +returncode=$? +elif [ $osname = "AIX" ] then - `$xcatpostdir/startsyncfiles.aix` +`$xcatpostdir/startsyncfiles.aix` +returncode=$? +fi + +if [ $returncode -eq 1 ] +then + logger -t xCAT "Perform Syncing File action successfully" +else + logger -t xCAT "Perform Syncing File action encountered error" fi exit 0 diff --git a/xCAT/postscripts/xcataixpost b/xCAT/postscripts/xcataixpost index 4d5c56ede..8d9e86ac7 100755 --- a/xCAT/postscripts/xcataixpost +++ b/xCAT/postscripts/xcataixpost @@ -174,8 +174,8 @@ if (-f $scriptname) { my $nodesetstat="standalone"; if (-f $scriptname) { - # when called by the updatenode command, - # modify the UPDATENODE flag to 1 + # when called by the updatenode command, + # modify the UPDATENODE flag to 1 if (@ARGV > 0) { $TMP=`sed -e 's/UPDATENODE=0/UPDATENODE=1/g' $scriptname`; `echo "$TMP" > $scriptname`; @@ -190,10 +190,18 @@ if (-f $scriptname) `echo "$TMP" > $scriptname`; #add requested postscripts in `echo "$POSTS" | tr "," "\n" >> $scriptname`; - } + } - $nodesetstat=`grep "NODESETSTATE=" $scriptname|awk -F \= '{print \$2}'`; - chomp($nodesetstat); + # when called by the updatenode command, + # if the first parameter equals 1, remove the otherpkgs postscript, + # since the otherpkgs only run for Linux software maintenance + if (@ARGV > 0 && $ARGV[0] == 1) { + my $TMP=`sed "/otherpkgs/ d" $scriptname`; + `echo "$TMP" > $scriptname`; + } + + $nodesetstat=`grep "NODESETSTATE=" $scriptname|awk -F \= '{print \$2}'`; + chomp($nodesetstat); $ENV{PATH}="/xcatpost:$ENV{PATH}"; &runcmd("cd /xcatpost;$scriptname"); } else { diff --git a/xCAT/postscripts/xcatdsklspost b/xCAT/postscripts/xcatdsklspost index 756a9774c..42651000e 100755 --- a/xCAT/postscripts/xcatdsklspost +++ b/xCAT/postscripts/xcatdsklspost @@ -88,6 +88,16 @@ fi #MYCONT=`cat /tmp/mypostscript` #echo "$MYCONT" +# when called by the updatenode command, +# if the first parameter equals 1, remove the otherpkgs postscript, +# since the otherpkgs only run for software maintenance: xcatdsklspost 2 otherpkgs +if [ $# -gt 0 ]; then +if [ $1 -eq 1 ]; then + TMP=`sed "/otherpkgs/ d" /tmp/mypostscript` + echo "$TMP" > /tmp/mypostscript +fi +fi + if [ $# -eq 0 ]; then #notify the server that we are done with netbooting CNS=`grep NODESTATUS= /tmp/mypostscript |awk -F = '{print $2}'`