diff --git a/docs/source/guides/admin-guides/references/man1/updatenode.1.rst b/docs/source/guides/admin-guides/references/man1/updatenode.1.rst index cd9a37448..82499c50e 100644 --- a/docs/source/guides/admin-guides/references/man1/updatenode.1.rst +++ b/docs/source/guides/admin-guides/references/man1/updatenode.1.rst @@ -19,7 +19,7 @@ SYNOPSIS ******** -\ **updatenode**\ \ *noderange*\ [\ **-V | -**\ **-verbose**\ ] [\ **-F | -**\ **-sync**\ ] [\ **-f | -**\ **-snsync**\ ] [\ **-S | -**\ **-sw**\ ] [\ **-l**\ \ *userID*\ ] [\ **-P | -**\ **-scripts**\ [\ *script1,script2...*\ ]] [\ **-s | -**\ **-sn**\ ] [\ **-A | -**\ **-updateallsw**\ ] [\ **-c | -**\ **-cmdlineonly**\ ] [\ **-d**\ \ *alt_source_dir*\ ] [\ **-**\ **-fanout**\ =\ *fanout_value*\ ] [\ **-t**\ \ *timeout*\ } [\ *attr=val*\ [\ *attr=val...*\ ]] [\ **-n | -**\ **-noverify**\ ] +\ **updatenode**\ \ *noderange*\ [\ **-V | -**\ **-verbose**\ ] [\ **-F | -**\ **-sync**\ ] [\ **-f | -**\ **-snsync**\ ] [\ **-r | -**\ **-node-rcp**\ [\ *full_path_to_remote_copy_command*\ ]] [\ **-S | -**\ **-sw**\ ] [\ **-l**\ \ *userID*\ ] [\ **-P | -**\ **-scripts**\ [\ *script1,script2...*\ ]] [\ **-s | -**\ **-sn**\ ] [\ **-A | -**\ **-updateallsw**\ ] [\ **-c | -**\ **-cmdlineonly**\ ] [\ **-d**\ \ *alt_source_dir*\ ] [\ **-**\ **-fanout**\ =\ *fanout_value*\ ] [\ **-t**\ \ *timeout*\ } [\ *attr=val*\ [\ *attr=val...*\ ]] [\ **-n | -**\ **-noverify**\ ] \ **updatenode**\ \ **noderange**\ [\ **-k | -**\ **-security**\ ] [\ **-t**\ \ *timeout*\ ] @@ -382,7 +382,7 @@ OPTIONS \ **-F|-**\ **-sync**\ Specifies that file synchronization should be - performed on the nodes. rsync and ssh must + performed on the nodes. rsync/scp and ssh must be installed and configured on the nodes. The function is not supported for NFS-based statelite installations. For NFS-based statelite installations to sync files, you should use the @@ -396,7 +396,7 @@ OPTIONS Specifies that file synchronization should be performed to the service nodes that service the nodes in the noderange. This updates the service - nodes with the data to sync to the nodes. rsync and ssh must + nodes with the data to sync to the nodes. rsync/scp and ssh must be installed and configured on the service nodes. For hierarchy, this optionally can be done before syncing the files to the nodes with the -F flag. If the -f flag is not used, then @@ -412,6 +412,12 @@ OPTIONS +[\ **-r | -**\ **-node-rcp**\ [\ *full_path_to_remote_copy_command*\ ]] + + Specifies the full path of the remote copy command used for syncing files to node targets, such as "/usr/bin/rsync" or "/usr/bin/scp". If not specified, rsync will be used by default. + + + \ **-g|-**\ **-genmypost**\ Will generate a new mypostscript file for the diff --git a/perl-xCAT/xCAT/DSHCLI.pm b/perl-xCAT/xCAT/DSHCLI.pm index c1f59fdea..85693ec22 100644 --- a/perl-xCAT/xCAT/DSHCLI.pm +++ b/perl-xCAT/xCAT/DSHCLI.pm @@ -22,6 +22,8 @@ use xCAT::MsgUtils; use xCAT::Utils; use xCAT::TableUtils; use xCAT::NodeRange; +use xCAT::DSHCLI; +use Data::Dumper; use lib '/opt/xcat/xdsh'; our @dsh_available_contexts = (); our @dsh_valid_contexts = (); @@ -922,6 +924,7 @@ sub fork_fanout_dcp $dsh_trace && (xCAT::MsgUtils->message("I", $rsp, $::CALLBACK)); + my @process_info = xCAT::DSHCore->fork_output($user_target, @dcp_command); vec($$outfh_targets{'bitmap'}, fileno($process_info[1]), 1) = 1; @@ -1329,7 +1332,7 @@ sub fork_fanout_dsh #print "Command=@dsh_command\n"; #@process_info = xCAT::DSHCore->fork_output($user_target, @dsh_command); - push(@commands, \@dsh_command); #print Dumper(\@commands); + push(@commands, \@dsh_command); @process_info = xCAT::DSHCore->fork_output_for_commands($user_target, @commands); if ($process_info[0] == -2) { @@ -4531,15 +4534,6 @@ sub parse_and_run_dcp } } - # invalid to put the -F with the -r flag - if ($options{'File'} && $options{'node-rcp'}) - { - my $rsp = {}; - $rsp->{error}->[0] = -"If -F option is use, then -r is invalid. The command will always the rsync using ssh."; - xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1); - return; - } # invalid to put the -s without the -F flag if (!($options{'File'}) && $options{'rsyncSN'}) @@ -4566,22 +4560,31 @@ sub parse_and_run_dcp } } - elsif ($^O eq 'linux') + elsif (($^O eq 'linux') and !$options{'node-rcp'}) { $options{'node-rcp'} = '/usr/bin/rsync'; } } - my $remotecopycommand = $options{'node-rcp'}; - if ($options{'node-rcp'} - && (!-f $options{'node-rcp'} || !-x $options{'node-rcp'})) - { - my $rsp = {}; - $rsp->{error}->[0] = -"Remote command: $remotecopycommand does not exist or is not executable."; - xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1); - return; - } + my $remotecopycommand = $options{'node-rcp'}; + if ($options{'node-rcp'}) { + if (!-f $options{'node-rcp'} || !-x $options{'node-rcp'}) + { + my $rsp = {}; + $rsp->{error}->[0] = + "Remote command: $remotecopycommand does not exist or is not executable."; + xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1); + return; + } + + if ($remotecopycommand !~ /\/(rcp|scp|rsync)$/){ + my $rsp = {}; + $rsp->{error}->[0] = + "Remote command: $remotecopycommand is invalid, the support remote commands: scp,rcp,rsync."; + xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1); + return; + } + } # # build list of nodes my @nodelist; @@ -4673,6 +4676,7 @@ sub parse_and_run_dcp { $::SYNCSN = 1; } + # the parsing of the file will fill in an array of postscripts # need to be run if the associated file is updated @@ -4726,6 +4730,7 @@ sub parse_and_run_dcp my $rsp = {}; $rsp->{error}->[0] = "Error parsing the rsync file:$syncfile."; xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1); + $::FAILED_NODES=scalar @nodelist; return; } @@ -5067,6 +5072,7 @@ sub parse_rsync_input_file_on_MN my $addappendscript = 0; open(INPUTFILE, "< $input_file") || die "File $input_file does not exist\n"; + while (my $line = ) { chomp $line; @@ -5284,6 +5290,15 @@ sub parse_rsync_input_file_on_MN { $$options{'nodes'} = join ',', keys %{ $$options{'destDir_srcFile'} }; } + + my $remotecopycommand=$$options{'node-rcp'}; + if($remotecopycommand !~ /\/rsync$/ and @::postscripts){ + my $rsp = {}; + $rsp->{error}->[0] ="key word 'EXECUTE' is unavailable when the remote copy command specified by '-r|--node-rcp' is $remotecopycommand. Does 'EXECUTEALWAYS' work for you?"; + xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1); + return 1; + } + return 0; } @@ -5780,6 +5795,15 @@ sub parse_rsync_input_file_on_SN { $$options{'nodes'} = join ',', keys %{ $$options{'destDir_srcFile'} }; } + + my $remotecopycommand=$$options{'node-rcp'}; + if($remotecopycommand !~ /\/rsync$/ and @::postscripts){ + my $rsp = {}; + $rsp->{error}->[0] ="key word 'EXECUTE' is unavailable when the remote copy command specified by '-r|--node-rcp' is $remotecopycommand. Does 'EXECUTEALWAYS' work for you?"; + xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1); + return 1; + } + return 0; } diff --git a/perl-xCAT/xCAT/SSH.pm b/perl-xCAT/xCAT/SSH.pm index 182671abb..0f6d0b30e 100644 --- a/perl-xCAT/xCAT/SSH.pm +++ b/perl-xCAT/xCAT/SSH.pm @@ -5,7 +5,6 @@ package xCAT::SSH; # cannot use strict use base xCAT::DSHRemoteShell; - # Determine if OS is AIX or Linux # Configure standard locations of commands based on OS @@ -136,33 +135,87 @@ sub remote_copy_command { my @src_files = (); my @dest_file = (); - my @src_file_list = split $::__DCP_DELIM, $$config{'src-file'}; + if ($$config{'destDir_srcFile'}){ + my $dest_dir_list = join ' ', keys %{ $$config{'destDir_srcFile'} }; + my $dest_user_host = $$config{'dest-host'}; + if ($::SYNCSN == 1) + { # syncing service node + #todo + $scpfile = "/tmp/scp_$$config{'dest-host'}"; + } + else + { + $scpfile = "/tmp/scp_$$config{'dest-host'}"; + } + + open SCPCMDFILE, "> $scpfile" + or die "Can not open file $scpfile"; + if ($$config{'dest-user'}) + { + $dest_user_host = + "$$config{'dest-user'}@" . "$$config{'dest-host'}"; + } + if ($$config{'trace'}) { + print SCPCMDFILE "#!/bin/sh -x\n"; + } else { + print SCPCMDFILE "#!/bin/sh\n"; + } - foreach $src_file (@src_file_list) { - my @src_path = (); - $$config{'src-user'} && push @src_path, "$$config{'src-user'}@"; - $$config{'src-host'} && push @src_path, "$$config{'src-host'}:"; - $$config{'src-file'} && push @src_path, $src_file; - push @src_files, (join '', @src_path); + print SCPCMDFILE + "/usr/bin/ssh $dest_user_host '/bin/mkdir -p $dest_dir_list'\n"; + + foreach my $dest_dir (keys %{ $$config{'destDir_srcFile'} }){ + if($$config{'destDir_srcFile'}{$dest_dir}{'same_dest_name'}){ + my @src_file = + @{ $$config{'destDir_srcFile'}{$dest_dir}{'same_dest_name'} }; + my $src_file_list = join ' ', @src_file; + print SCPCMDFILE + "$exec_path -p -r $src_file_list $dest_user_host:$dest_dir\n"; + } + + if($$config{'destDir_srcFile'}{$dest_dir}{'diff_dest_name'}){ + my %diff_dest_hash = + %{ $$config{'destDir_srcFile'}{$dest_dir}{'diff_dest_name'} }; + foreach my $src_file_diff_dest (keys %diff_dest_hash) + { + my $diff_basename = $diff_dest_hash{$src_file_diff_dest}; + print SCPCMDFILE + "$exec_path -p -r $src_file_diff_dest $dest_user_host:$dest_dir/$diff_basename\n"; + } + } + } + + close SCPCMDFILE; + chmod 0755, $scpfile; + @command = ('/bin/sh', '-c', $scpfile); + }else{ + my @src_file_list = split $::__DCP_DELIM, $$config{'src-file'}; + + foreach $src_file (@src_file_list) { + my @src_path = (); + $$config{'src-user'} && push @src_path, "$$config{'src-user'}@"; + $$config{'src-host'} && push @src_path, "$$config{'src-host'}:"; + $$config{'src-file'} && push @src_path, $src_file; + push @src_files, (join '', @src_path); + } + + $$config{'dest-user'} && push @dest_file, "$$config{'dest-user'}@"; + $$config{'dest-host'} && push @dest_file, "$$config{'dest-host'}:"; + $$config{'dest-file'} && push @dest_file, $$config{'dest-file'}; + + push @command, $exec_path; + $$config{'preserve'} && push @command, '-p'; + $$config{'recursive'} && push @command, '-r'; + + if ($$config{'options'}) { + my @options = split ' ', $$config{'options'}; + push @command, @options; + } + + ($ssh_version eq 'OpenSSH') && push @command, '-B'; + push @command, @src_files; + push @command, (join '', @dest_file); } - - $$config{'dest-user'} && push @dest_file, "$$config{'dest-user'}@"; - $$config{'dest-host'} && push @dest_file, "$$config{'dest-host'}:"; - $$config{'dest-file'} && push @dest_file, $$config{'dest-file'}; - - push @command, $exec_path; - $$config{'preserve'} && push @command, '-p'; - $$config{'recursive'} && push @command, '-r'; - - if ($$config{'options'}) { - my @options = split ' ', $$config{'options'}; - push @command, @options; - } - - ($ssh_version eq 'OpenSSH') && push @command, '-B'; - push @command, @src_files; - push @command, (join '', @dest_file); - return @command; } diff --git a/perl-xCAT/xCAT/Usage.pm b/perl-xCAT/xCAT/Usage.pm index aeb8cdfe2..3abcf53b2 100755 --- a/perl-xCAT/xCAT/Usage.pm +++ b/perl-xCAT/xCAT/Usage.pm @@ -500,7 +500,7 @@ my %usage = ( or updatenode [-V|--verbose] [-k|--security] [-s|--sn] [-t ] or - updatenode [-V|--verbose] [-F|--sync | -f|--snsync] [-l|--user[username]] [--fanout=[fanout value]] [-S|--sw] [-t ] + updatenode [-V|--verbose] [-F|--sync | -f|--snsync] [-r|--node-rcp ] [-l|--user[username]] [--fanout=[fanout value]] [-S|--sw] [-t ] [-P|--scripts [script1,script2,...]] [-s|--sn] [-A|--updateallsw] [-c|--cmdlineonly] [-d alt_source_dir] [attr=val [attr=val...]] @@ -520,7 +520,9 @@ Options: [-f|--snsync] Performs File Syncing to the service nodes that service the nodes in the noderange. - + + [-r|--node-rcp] Specifies the full path of the remote copy command used for sync files to node targets, such as /usr/bin/rsync and /usr/bin/scp + [-g|--genmypost] Will generate a new mypostscript file for the the nodes in the noderange, if site precreatemypostscripts is 1 or YES. diff --git a/xCAT-client/bin/updatenode b/xCAT-client/bin/updatenode index ebfe392e2..f4dd1a79b 100755 --- a/xCAT-client/bin/updatenode +++ b/xCAT-client/bin/updatenode @@ -56,7 +56,7 @@ if (!($tmp =~ / (--help|-h|-v|--version)/)) { my $arg = shift(@ARGV); # Set the noderange - if ($arg !~ /^-/) { + if ($arg and $arg !~ /^-/) { my @tempnr = (); foreach my $nr (split(/,/, $arg)) { if ($nr =~ /^\^(.*)$/) { @@ -82,7 +82,7 @@ if (!($tmp =~ / (--help|-h|-v|--version)/)) { push(@{ $cmdref->{arg} }, @ARGV); # check the syntax -my ($ALLSW, $CMDLINE, $ALTSRC, $HELP, $VERSION, $VERBOSE, $FILESYNC, $GENMYPOST, $USER, $SNFILESYNC, $SWMAINTENANCE, $SETSERVER, $RERUNPS, $SECURITY, $OS, $fanout, $timeout, $NOVERIFY); +my ($ALLSW, $CMDLINE, $ALTSRC, $HELP, $VERSION, $VERBOSE, $FILESYNC, $GENMYPOST, $USER, $SNFILESYNC, $SWMAINTENANCE, $SETSERVER, $RERUNPS, $SECURITY, $OS, $fanout, $timeout, $NOVERIFY,$RCP); if ( !GetOptions( 'A|updateallsw' => \$ALLSW, @@ -103,6 +103,7 @@ if ( 'fanout=i' => \$fanout, 't|timetout=i' => \$timeout, 'n|noverify' => \$NOVERIFY, + 'r|node-rcp' => \$RCP, ) ) { &updatenode_usage(); diff --git a/xCAT-client/pods/man1/updatenode.1.pod b/xCAT-client/pods/man1/updatenode.1.pod index 582a9da26..3fc86a737 100644 --- a/xCAT-client/pods/man1/updatenode.1.pod +++ b/xCAT-client/pods/man1/updatenode.1.pod @@ -4,7 +4,7 @@ B - Update nodes in an xCAT cluster environment. =head1 SYNOPSIS -B I [B<-V>|B<--verbose>] [B<-F>|B<--sync>] [B<-f>|B<--snsync>] [B<-S>|B<--sw>] [B<-l> I] [B<-P>|B<--scripts> [I]] [B<-s>|B<--sn>] [B<-A>|B<--updateallsw>] [B<-c>|B<--cmdlineonly>] [B<-d> I] [B<--fanout>=I] [B<-t> I} [I [I]] [B<-n>|B<--noverify>] +B I [B<-V>|B<--verbose>] [B<-F>|B<--sync>] [B<-f>|B<--snsync>] [B<-r>|B<--node-rcp> [I]] [B<-S>|B<--sw>] [B<-l> I] [B<-P>|B<--scripts> [I]] [B<-s>|B<--sn>] [B<-A>|B<--updateallsw>] [B<-c>|B<--cmdlineonly>] [B<-d> I] [B<--fanout>=I] [B<-t> I} [I [I]] [B<-n>|B<--noverify>] B B [B<-k>|B<--security>] [B<-t> I] @@ -289,7 +289,7 @@ Used to specify a source directory other than the standard lpp_source directory =item B<-F|--sync> Specifies that file synchronization should be -performed on the nodes. rsync and ssh must +performed on the nodes. rsync/scp and ssh must be installed and configured on the nodes. The function is not supported for NFS-based statelite installations. For NFS-based statelite installations to sync files, you should use the @@ -302,7 +302,7 @@ litefile table with source location specified in the litetree table. Specifies that file synchronization should be performed to the service nodes that service the nodes in the noderange. This updates the service -nodes with the data to sync to the nodes. rsync and ssh must +nodes with the data to sync to the nodes. rsync/scp and ssh must be installed and configured on the service nodes. For hierarchy, this optionally can be done before syncing the files to the nodes with the -F flag. If the -f flag is not used, then @@ -316,6 +316,12 @@ For statelite installations to sync files, you should use the read-only option for files/directories listed in litefile table with source location specified in the litetree table. + +=item [B<-r>|B<--node-rcp> [I]] + +Specifies the full path of the remote copy command used for syncing files to node targets, such as "/usr/bin/rsync" or "/usr/bin/scp". If not specified, rsync will be used by default. + + =item B<-g|--genmypost> Will generate a new mypostscript file for the diff --git a/xCAT-server/lib/xcat/plugins/syncfiles.pm b/xCAT-server/lib/xcat/plugins/syncfiles.pm index 8a50c3810..9114fbbde 100644 --- a/xCAT-server/lib/xcat/plugins/syncfiles.pm +++ b/xCAT-server/lib/xcat/plugins/syncfiles.pm @@ -12,7 +12,8 @@ use xCAT::Utils; use xCAT::MsgUtils; use xCAT::SvrUtils; use xCAT::NodeRange; - +use Data::Dumper; +use Getopt::Long; 1; #------------------------------------------------------- @@ -46,11 +47,32 @@ sub process_request my $callback = shift; my $subreq = shift; + my $args= $request->{arg}; # argument + @ARGV = @{$args}; my $client; if ($request->{'_xcat_clienthost'}) { $client = $request->{'_xcat_clienthost'}->[0]; } + + my %options = (); + Getopt::Long::Configure("posix_default"); + Getopt::Long::Configure("no_gnu_compat"); + Getopt::Long::Configure("bundling"); + if ( + !GetOptions( + 'r|c|node-rcp=s' => \$options{'node-rcp'}, + ) + ) + { + xCAT::MsgUtils->message("S", "Received syncfiles from $client, with invalid options @ARGV"); + return; + } + + if ($options{'node-rcp'}){ + $::RCP=$options{'node-rcp'}; + } + if ($client) { ($client) = noderange($client) } unless ($client) { #Not able to do identify the host in question xCAT::MsgUtils->message("S", "Received syncfiles from $client, which couldn't be correlated to a node (domain mismatch?)"); @@ -101,7 +123,11 @@ sub syncfiles { foreach my $synclistfile (@sl) { # call the xdcp plugin to handle the syncfile operation - my $args = [ "-F", "$synclistfile" ]; + my $args = [ "-F", "$synclistfile"]; + if($::RCP){ + push @$args,"-r"; + push @$args, "$::RCP"; + } my $env = ["DSH_RSYNC_FILE=$synclistfile"]; $subreq->({ command => ['xdcp'], node => [$node], arg => $args, env => $env }, $callback); } diff --git a/xCAT-server/lib/xcat/plugins/updatenode.pm b/xCAT-server/lib/xcat/plugins/updatenode.pm index 8b4559179..7df23f482 100644 --- a/xCAT-server/lib/xcat/plugins/updatenode.pm +++ b/xCAT-server/lib/xcat/plugins/updatenode.pm @@ -11,7 +11,6 @@ use lib "$::XCATROOT/lib/perl"; use xCAT::Table; use xCAT::Schema; -use Data::Dumper; use xCAT::Utils; use xCAT::SvrUtils; use xCAT::Scope; @@ -30,6 +29,7 @@ use File::Basename; use xCAT::GlobalDef; use xCAT_monitoring::monitorctrl; use Socket; +use Data::Dumper; use strict; my $CALLBACK; @@ -209,7 +209,7 @@ sub preprocess_updatenode } # parse the options - my ($ALLSW, $CMDLINE, $ALTSRC, $HELP, $VERSION, $VERBOSE, $FILESYNC, $GENMYPOST, $USER, $SNFILESYNC, $SWMAINTENANCE, $SETSERVER, $RERUNPS, $SECURITY, $OS, $fanout, $timeout, $NOVERIFY); + my ($ALLSW, $CMDLINE, $ALTSRC, $HELP, $VERSION, $VERBOSE, $FILESYNC, $GENMYPOST, $USER, $SNFILESYNC, $SWMAINTENANCE, $SETSERVER, $RERUNPS, $SECURITY, $OS, $fanout, $timeout, $NOVERIFY, $RCP); Getopt::Long::Configure("bundling"); Getopt::Long::Configure("no_pass_through"); if ( @@ -232,6 +232,7 @@ sub preprocess_updatenode 'fanout=i' => \$fanout, 't|timetout=i' => \$timeout, 'n|noverify' => \$NOVERIFY, + 'r|node-rcp=s' =>\$RCP, ) ) @@ -289,6 +290,11 @@ sub preprocess_updatenode } else { undef $::OS; } + if (defined($RCP)) { + $::RCP = $RCP; + } else { + undef $::RCP; + } # display the usage if -h or --help is specified if ($HELP) @@ -428,6 +434,15 @@ sub preprocess_updatenode return; } + if (($RCP) and (!$FILESYNC) and (!$SNFILESYNC)){ + my $rsp = {}; + $rsp->{data}->[0] = "-r|--node-rcp option is valid when option -f or -F is specified"; + $rsp->{errorcode}->[0] = 1; + $callback->($rsp); + return; + } + + # -f must not be with any other flag, this updates service nodes syncfiles if ($SNFILESYNC && ($SWMAINTENANCE || $RERUNPS || defined($RERUNPS) || $SECURITY || $FILESYNC)) { @@ -658,7 +673,11 @@ sub preprocess_updatenode { $request->{SNFileSyncing}->[0] = "yes"; } - + + if ($RCP){ + $request->{rcp}->[0]=$RCP; + } + # If -F or -f then, call CFMUtils to check if any PCM CFM data is to be # built for the node. This will also create the synclists attribute in # the osimage for each node in the noderange @@ -685,6 +704,7 @@ sub preprocess_updatenode } + # - need to consider the mixed cluster case # - can't depend on the os of the MN - need to split out the AIX nodes my ($rc, $AIXnodes, $Linuxnodes) = xCAT::InstUtils->getOSnodes($nodes); @@ -752,6 +772,7 @@ sub preprocess_updatenode # process the -F or -f flags if (($FILESYNC) || ($SNFILESYNC)) { + # If it is only -F or -f in the command, which are always run on the MN, # then run it now and you are # finished. @@ -821,6 +842,7 @@ sub preprocess_updatenode } + # # if hierarchy, then build the request for the service nodes # @@ -1078,7 +1100,6 @@ sub updatenode @::SUCCESSFULLNODES = (); @::FAILEDNODES = (); - #print Dumper($request); my $nodes = $request->{node}; #$request->{status}= "yes"; # for testing @@ -1135,7 +1156,7 @@ sub updatenode chomp $nimprime; # parse the options - my ($ALLSW, $CMDLINE, $ALTSRC, $HELP, $VERSION, $VERBOSE, $FILESYNC, $GENMYPOST, $USER, $SNFILESYNC, $SWMAINTENANCE, $SETSERVER, $RERUNPS, $SECURITY, $OS, $fanout, $timeout, $NOVERIFY); + my ($ALLSW, $CMDLINE, $ALTSRC, $HELP, $VERSION, $VERBOSE, $FILESYNC, $GENMYPOST, $USER, $SNFILESYNC, $SWMAINTENANCE, $SETSERVER, $RERUNPS, $SECURITY, $OS, $fanout, $timeout, $NOVERIFY, $RCP); Getopt::Long::Configure("bundling"); Getopt::Long::Configure("no_pass_through"); if ( @@ -1158,6 +1179,7 @@ sub updatenode 'fanout=i' => \$fanout, 't|timetout=i' => \$timeout, 'n|noverify' => \$NOVERIFY, + 'r|node-rcp=s' => \$RCP, ) ) { @@ -1211,6 +1233,11 @@ sub updatenode } else { undef $::OS; } + if (defined($RCP)) { + $::RCP = $RCP; + } else { + undef $::RCP; + } # # process @ARGV @@ -1712,6 +1739,7 @@ sub updatenodesyncfiles my %syncfile_node = (); my %syncfile_rootimage = (); + # $::NOSYNCFILE default value is 0 # if there is no syncfiles, set $::NOSYNCFILE=1 $::NOSYNCFILE = 0; @@ -1828,6 +1856,10 @@ sub updatenodesyncfiles $CALLBACK = $callback; + if($::RCP){ + push @$args, "--node-rcp"; + push @$args, "$::RCP"; + } $output = xCAT::Utils->runxcmd( { @@ -1841,21 +1873,32 @@ sub updatenodesyncfiles # build the list of good and bad nodes &buildnodestatus(\@$output, $callback); + if($::RUNCMD_RC and !@::FAILEDNODES){ + push @::FAILEDNODES,@{$syncfile_node{$synclist}}; + } } if ($request->{SNFileSyncing}->[0] eq "yes") { my $rsp = {}; - $rsp->{data}->[0] = "File synchronization has completed for service nodes."; + if(@::SUCCESSFULLNODES){ + $rsp->{data}->[0] = "File synchronization has completed for service nodes: \"".join(',',@::SUCCESSFULLNODES)."\""; + } if (@::FAILEDNODES) { $rsp->{errorcode}->[0] = 1; + $rsp->{data}->[0] = "File synchronization failed for service nodes: \"".join(',',@::FAILEDNODES)."\""; } $callback->($rsp); } + if ($request->{FileSyncing}->[0] eq "yes") { my $rsp = {}; - $rsp->{data}->[0] = "File synchronization has completed for nodes."; + if(@::SUCCESSFULLNODES){ + $rsp->{data}->[0] = "File synchronization has completed for nodes: \"".join(',',@::SUCCESSFULLNODES)."\""; + } + if (@::FAILEDNODES) { $rsp->{errorcode}->[0] = 1; + $rsp->{data}->[0] = "File synchronization failed for nodes: \"".join(',',@::FAILEDNODES)."\""; } $callback->($rsp); } diff --git a/xCAT-server/lib/xcat/plugins/xdsh.pm b/xCAT-server/lib/xcat/plugins/xdsh.pm index 50ae19bb3..2b295d144 100644 --- a/xCAT-server/lib/xcat/plugins/xdsh.pm +++ b/xCAT-server/lib/xcat/plugins/xdsh.pm @@ -17,13 +17,15 @@ use File::Basename; use File::Path; use POSIX; require xCAT::Table; - +use Data::Dumper; require xCAT::Utils; require xCAT::Zone; require xCAT::TableUtils; require xCAT::ServiceNodeUtils; require xCAT::MsgUtils; use Getopt::Long; + + require xCAT::DSHCLI; 1; @@ -63,6 +65,7 @@ sub preprocess_request my $sn; my $rc = 0; + #if already preprocessed, go straight to request if ((defined($req->{_xcatpreprocessed})) && ($req->{_xcatpreprocessed}->[0] == 1)) @@ -331,6 +334,11 @@ sub parse_xdcp_cmd } my $changedfile = 0; + if ($options{'node-rcp'}){ + $::RCP=$options{'node-rcp'}; + } + + # check to see if -F option and if there is, is the # input file fully defined path my $newfile; @@ -658,6 +666,10 @@ sub process_servicenodes_xdcp $addreq->{command}->[0] = $cmd; $addreq->{cwd}->[0] = $req->{cwd}->[0]; $addreq->{env} = $req->{env}; + if($::RCP){ + push(@{ $addreq->{arg} }, "-r"); + push(@{ $addreq->{arg} }, "$::RCP"); + } &process_request($addreq, $callback, $sub_req); if ($::FAILED_NODES == 0) diff --git a/xCAT/postscripts/startsyncfiles b/xCAT/postscripts/startsyncfiles new file mode 100755 index 000000000..1f1be4fc2 --- /dev/null +++ b/xCAT/postscripts/startsyncfiles @@ -0,0 +1,48 @@ +#!/bin/bash +log_label="xcat" +#mkdir -p /etc/xcat +#mkdir -p /etc/pki/tls +#if [ ! -f /etc/xcat/privkey.pem ]; then +# echo "[ req ] +#distinguished_name = nodedn + +#[ nodedn ]" > /etc/pki/tls/openssl.cnf +# logger -s -t $log_label -p local4.info "Generating private key..." +# openssl genrsa -out /etc/xcat/privkey.pem 1024 >& /dev/null +# logger -s -t $log_label -p local4.info "Done" +#fi + +#PUBKEY=`openssl rsa -in /etc/xcat/privkey.pem -pubout 2> /dev/null|grep -v "PUBLIC KEY"` +#PUBKEY=`echo $PUBKEY|sed -e 's/ //g'` +#export PUBKEY + + + +REQUEST="" +REQUEST=${REQUEST}"syncfiles" +#REQUEST=${REQUEST}"$PUBKEY" +#REQUEST=${REQUEST}"" + +if [ -n "$RCP" ]; then + REQUEST=${REQUEST}"-r" + REQUEST=${REQUEST}""${RCP}"" +fi + +REQUEST=${REQUEST}"" +RETCODE=0 + +while read LINE;do + echo $LINE + if echo $LINE| grep '' >/dev/null 2>&1; then + rm -rf $RESPFILE + exit $RETCODE + fi + if echo $LINE|grep '' >/dev/null 2>&1; then + RET=${LINE#*>} + RET=${RET%<*} + [ "$RET" != "0" ] && RETCODE=1 + fi +done < <(openssl s_client -no_ssl3 -no_ssl2 -connect $MASTER_IP:$XCATDPORT -ign_eof -quiet <<<$REQUEST) + +rm -rf $RESPFILE +exit $RETCODE diff --git a/xCAT/postscripts/startsyncfiles.awk b/xCAT/postscripts/startsyncfiles.awk index a7975410d..88f5a9e4a 100755 --- a/xCAT/postscripts/startsyncfiles.awk +++ b/xCAT/postscripts/startsyncfiles.awk @@ -11,6 +11,10 @@ BEGIN { print "" |& server print " syncfiles" |& server + if(RCP){ + print " -r" |& server + print " "RCP"" |& server + } print "" |& server while (server |& getline) { diff --git a/xCAT/postscripts/syncfiles b/xCAT/postscripts/syncfiles index 1074fe389..0816e14e6 100755 --- a/xCAT/postscripts/syncfiles +++ b/xCAT/postscripts/syncfiles @@ -14,13 +14,6 @@ if [ -d /.statelite ]; then exit 0 fi -if [ -f /etc/os-release ] && cat /etc/os-release |grep -i -e "^NAME=[ \"']*Cumulus Linux[ \"']*$" >/dev/null 2>&1 ; then - #TODO - echo "Cumulus OS is not supported yet, nothing to do..." - logger -t xcat -p local4.info "Cumulus OS is not supported yet, nothing to do..." - exit 0 -fi - # do nothing when UPDATENODE=1 because it is done from the top down if [ -n "$UPDATENODE" ] && [ $UPDATENODE -eq 1 ]; then #echo " Did not sync any files. Use updatenode -F to sync the files." @@ -36,6 +29,11 @@ if [ -n "$NOSYNCFILES" ] && [ $NOSYNCFILES -eq 1 ]; then exit 0 fi +RCP= +if [ ! -e "/usr/bin/rsync" ]; then + [ -e "/usr/bin/scp" ] && RCP="/usr/bin/scp" +fi + logger -t xcat -p local4.info "Performing syncfiles postscript" osname=`uname` @@ -47,9 +45,12 @@ quit="no" count=5 returncode=0 while [ $quit = "no" ]; do - if [ $osname = "Linux" ] + if cat /etc/os-release |grep -i cumulus >/dev/null 2>&1; then + RCP=$RCP $xcatpostdir/startsyncfiles + returncode=$? + elif [ $osname = "Linux" ] then - `$xcatpostdir/startsyncfiles.awk` + `$xcatpostdir/startsyncfiles.awk -v RCP=$RCP` returncode=$? elif [ $osname = "AIX" ] then