The first phase code drop for CFM like funtion
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@3514 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
parent
845afe2051
commit
05c9e4b58f
@ -3959,4 +3959,128 @@ sub checkCredFiles
|
||||
|
||||
}
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
=head3 getsynclistfile
|
||||
Get the synclist file for the nodes;
|
||||
The arguments $os,$arch,$profile,$insttype are only available when no $nodes is specified
|
||||
|
||||
Arguments:
|
||||
$nodes
|
||||
$os
|
||||
$arch
|
||||
$profile
|
||||
$insttype - installation type (can be install or netboot)
|
||||
Returns:
|
||||
When specified $nodes: reference of a hash of node=>synclist
|
||||
Otherwise: full path of the synclist file
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
Example:
|
||||
my $node_syncfile=xCAT::Utils->getsynclistfile($nodes);
|
||||
my $syncfile=xCAT::Utils->getsynclistfile(undef, 'sles11', 'ppc64', 'compute', 'netboot');
|
||||
Comments:
|
||||
none
|
||||
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
sub getsynclistfile()
|
||||
{
|
||||
my $nodes = shift;
|
||||
if (($nodes) && ($nodes =~ /xCAT::Utils/))
|
||||
{
|
||||
$nodes = shift;
|
||||
}
|
||||
|
||||
my ($os, $arch, $profile, $inst_type) = @_;
|
||||
|
||||
# if does not specify the $node param, default consider for genimage command
|
||||
if ($nodes) {
|
||||
my %node_syncfile = ();
|
||||
|
||||
my %node_insttype = ();
|
||||
my %insttype_node = ();
|
||||
# get the nodes installation type
|
||||
xCAT::SvrUtils->getNodesetStates($nodes, \%insttype_node);
|
||||
# convert the hash to the node=>type
|
||||
foreach my $type (keys %insttype_node) {
|
||||
foreach my $node (@{$insttype_node{$type}}) {
|
||||
$node_insttype{$node} = $type;
|
||||
}
|
||||
}
|
||||
|
||||
# get the os,arch,profile attributes for the nodes
|
||||
my $nodetype_t = xCAT::Table->new('nodetype');
|
||||
unless ($nodetype_t) {
|
||||
return ;
|
||||
}
|
||||
my $nodetype_v = $nodetype_t->getNodesAttribs($nodes, ['profile','os','arch']);
|
||||
|
||||
foreach my $node (@$nodes) {
|
||||
$inst_type = $node_insttype{$node};
|
||||
if ($inst_type eq "netboot" || $inst_type eq "diskless") {
|
||||
$inst_type = "netboot";
|
||||
} else {
|
||||
$inst_type = "install";
|
||||
}
|
||||
|
||||
$profile = $nodetype_v->{$node}->[0]->{'profile'};
|
||||
$os = $nodetype_v->{$node}->[0]->{'os'};
|
||||
$arch = $nodetype_v->{$node}->[0]->{'arch'};
|
||||
|
||||
my $platform = "";
|
||||
if ($os) {
|
||||
if ($os =~ /rh.*/) { $platform = "rh"; }
|
||||
elsif ($os =~ /centos.*/) { $platform = "centos"; }
|
||||
elsif ($os =~ /fedora.*/) { $platform = "fedora"; }
|
||||
elsif ($os =~ /sles.*/) { $platform = "sles"; }
|
||||
elsif ($os =~ /AIX.*/) { $platform = "AIX"; }
|
||||
}
|
||||
|
||||
my $base = "/install/custom/$inst_type/$platform";
|
||||
if (-r "$base/$profile.$os.$arch.synclist") {
|
||||
$node_syncfile{$node} = "$base/$profile.$os.$arch.synclist";
|
||||
} elsif (-r "$base/$profile.$arch.synclist") {
|
||||
$node_syncfile{$node} = "$base/$profile.$arch.synclist";
|
||||
} elsif (-r "$base/$profile.$os.synclist") {
|
||||
$node_syncfile{$node} = "$base/$profile.$os.synclist";
|
||||
} elsif (-r "$base/$profile.synclist") {
|
||||
$node_syncfile{$node} = "$base/$profile.synclist";
|
||||
}
|
||||
}
|
||||
|
||||
return \%node_syncfile;
|
||||
} else {
|
||||
my $platform = "";
|
||||
if ($os) {
|
||||
if ($os =~ /rh.*/) { $platform = "rh"; }
|
||||
elsif ($os =~ /centos.*/) { $platform = "centos"; }
|
||||
elsif ($os =~ /fedora.*/) { $platform = "fedora"; }
|
||||
elsif ($os =~ /sles.*/) { $platform = "sles"; }
|
||||
elsif ($os =~ /AIX.*/) { $platform = "AIX"; }
|
||||
}
|
||||
|
||||
my $base = "/install/custom/$inst_type/$platform";
|
||||
if (-r "$base/$profile.$os.$arch.synclist") {
|
||||
return "$base/$profile.$os.$arch.synclist";
|
||||
} elsif (-r "$base/$profile.$arch.synclist") {
|
||||
return "$base/$profile.$arch.synclist";
|
||||
} elsif (-r "$base/$profile.$os.synclist") {
|
||||
return "$base/$profile.$os.synclist";
|
||||
} elsif (-r "$base/$profile.synclist") {
|
||||
return "$base/$profile.synclist";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
@ -228,6 +228,9 @@ sub makescript {
|
||||
push @scriptd, "NODESETSTATE=".$nodesetstate."\n";
|
||||
push @scriptd, "export NODESETSTATE\n";
|
||||
|
||||
# set the UPDATENODE flag in the script, the default it 0, that means not in the updatenode process
|
||||
push @scriptd, "UPDATENODE=0\n";
|
||||
push @scriptd, "export UPDATENODE\n";
|
||||
|
||||
# see if this is a service or compute node?
|
||||
if (xCAT::Utils->isSN($node) ) {
|
||||
@ -356,4 +359,44 @@ sub get_otherpkg_file_name {
|
||||
return "";
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head3 syncfiles
|
||||
|
||||
Use the xdcp command to sync files from Management node/Service node to the Compute node
|
||||
|
||||
Arguments:
|
||||
Returns: 0 - failed; 1 - succeeded;
|
||||
Example:
|
||||
xCAT::Postage->syncfiles($node, $callback);
|
||||
|
||||
Comments:
|
||||
|
||||
=cut
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
sub syncfiles {
|
||||
my $node = shift;
|
||||
if ($node =~ /xCAT::Postage/) {
|
||||
$node = shift;
|
||||
}
|
||||
my $callback = shift;
|
||||
my $subreq = shift;
|
||||
|
||||
#get the sync file base on the node type
|
||||
my $synclist = xCAT::Utils->getsynclistfile([$node]);
|
||||
if (!$synclist) {
|
||||
xCAT::MsgUtils->message("S", "Cannot find synclist file for the $node");
|
||||
return 0;
|
||||
}
|
||||
|
||||
# call the xdcp plugin to handle the syncfile operation
|
||||
my $args = ["-F", "$$synclist{$node}"];
|
||||
my $env = ["DSH_RSYNC_FILE=$$synclist{$node}"];
|
||||
$subreq->({command=>['xdcp'], node=>[$node], arg=>$args, env=>$env}, $callback);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
67
xCAT-server/lib/xcat/plugins/syncfiles.pm
Normal file
67
xCAT-server/lib/xcat/plugins/syncfiles.pm
Normal file
@ -0,0 +1,67 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head1
|
||||
xCAT plugin package to handle syncfiles command
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
package xCAT_plugin::syncfiles;
|
||||
use xCAT::Utils;
|
||||
use xCAT::MsgUtils;
|
||||
use xCAT::NodeRange;
|
||||
|
||||
1;
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head3 handled_commands
|
||||
|
||||
Return list of commands handled by this plugin
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
sub handled_commands
|
||||
{
|
||||
return {'syncfiles' => "syncfiles"};
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head3 process_request
|
||||
|
||||
Process the command
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
sub process_request
|
||||
{
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $subreq = shift;
|
||||
|
||||
my $client;
|
||||
if ($request->{'_xcat_clienthost'}) {
|
||||
$client = $request->{'_xcat_clienthost'}->[0];
|
||||
}
|
||||
|
||||
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?)");
|
||||
return;
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
@ -56,13 +56,14 @@ sub preprocess_request
|
||||
{
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $subreq = shift;
|
||||
my $command = $request->{command}->[0];
|
||||
if ($request->{_xcatdest}) { return [$request]; } #exit if preprocessed
|
||||
my @requests=();
|
||||
|
||||
if ($command eq "updatenode")
|
||||
{
|
||||
return preprocess_updatenode($request, $callback);
|
||||
return preprocess_updatenode($request, $callback, $subreq);
|
||||
} elsif ($command eq "updatenodestat") {
|
||||
return [$request];
|
||||
}
|
||||
@ -89,11 +90,12 @@ sub process_request
|
||||
{
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $subreq = shift;
|
||||
my $command = $request->{command}->[0];
|
||||
my $localhostname=hostname();
|
||||
|
||||
if ($command eq "updatenode") {
|
||||
return updatenode($request, $callback);
|
||||
return updatenode($request, $callback, $subreq);
|
||||
} elsif ($command eq "updatenodestat") {
|
||||
return updatenodestat($request, $callback);
|
||||
} else {
|
||||
@ -112,7 +114,7 @@ sub process_request
|
||||
Arguments:
|
||||
request - the request. The request->{arg} is of the format:
|
||||
[-h|--help|-v|--version] or
|
||||
[noderange [postscripts]]
|
||||
[noderange [-s | -S] [postscripts]]
|
||||
callback - the pointer to the callback function.
|
||||
Returns:
|
||||
A pointer to an array of requests.
|
||||
@ -121,6 +123,7 @@ sub process_request
|
||||
sub preprocess_updatenode {
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $subreq = shift;
|
||||
my $args=$request->{arg};
|
||||
my @requests=();
|
||||
|
||||
@ -130,7 +133,7 @@ sub preprocess_updatenode {
|
||||
my $cb=shift;
|
||||
my $rsp={};
|
||||
$rsp->{data}->[0]= "Usage:";
|
||||
$rsp->{data}->[1]= " updatenode <noderange> [posts]";
|
||||
$rsp->{data}->[1]= " updatenode <noderange> [-s | -S] [posts]";
|
||||
$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.";
|
||||
@ -149,7 +152,9 @@ sub preprocess_updatenode {
|
||||
Getopt::Long::Configure("no_pass_through");
|
||||
if(!GetOptions(
|
||||
'h|help' => \$::HELP,
|
||||
'v|version' => \$::VERSION))
|
||||
'v|version' => \$::VERSION,
|
||||
's' => \$::SYNCSN,
|
||||
'S' => \$::SKIPSYNCFILE ))
|
||||
{
|
||||
&updatenode_usage($callback);
|
||||
return \@requests;;
|
||||
@ -198,6 +203,52 @@ sub preprocess_updatenode {
|
||||
# build an individual request for each service node
|
||||
my $sn = xCAT::Utils->get_ServiceNode(\@nodes, "xcat", "MN");
|
||||
|
||||
# If -s argument specified, sync files to the service node firstly
|
||||
if ($::SYNCSN) {
|
||||
my @MNnodeinfo = xCAT::Utils->determinehostname;
|
||||
my $MNnodename = pop @MNnodeinfo; # hostname
|
||||
my @MNnodeipaddr = @MNnodeinfo; # ipaddresses
|
||||
|
||||
my $node_syncfile = xCAT::Utils->getsynclistfile($nodes);
|
||||
my %syncfile_sn = ();
|
||||
foreach my $snkey (keys %$sn)
|
||||
{
|
||||
# exclude the Management node
|
||||
if (grep(/$snkey/, @MNnodeipaddr)) {
|
||||
next;
|
||||
}
|
||||
my @synclists = ();
|
||||
# Figure out the synclist files for the service node
|
||||
foreach my $node (@{$sn->{$snkey}}) {
|
||||
my $synclist = $$node_syncfile{$node};
|
||||
|
||||
unless ($synclist) {
|
||||
next;
|
||||
}
|
||||
if (! grep /\Q$synclist\E/, @synclists) {
|
||||
push @synclists, $synclist;
|
||||
push @{$syncfile_sn{$synclist}}, $node;
|
||||
}
|
||||
}
|
||||
|
||||
# If there are multiple synclist files for certain SN,
|
||||
# the synclist files maybe have conflicted content, so
|
||||
# display an warning message
|
||||
if ($#synclists > 0) {
|
||||
my $rsp = {};
|
||||
my $files = join(',', @synclists);
|
||||
$rsp->{data}->[0]= "Warning: The Service Node $snkey will be synced by following synclist files: $files";
|
||||
$callback->($rsp);
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $syncfile (keys %syncfile_sn) {
|
||||
my $arg = ["-s", "-F", "$syncfile"];
|
||||
my $env = ["RSYNCSN=yes", "DSH_RSYNC_FILE=$syncfile"];
|
||||
$subreq->({command=>['xdcp'], node=>$syncfile_sn{$syncfile}, arg=>$arg, env=>$env}, $callback);
|
||||
}
|
||||
}
|
||||
|
||||
# build each request for each service node
|
||||
foreach my $snkey (keys %$sn)
|
||||
{
|
||||
@ -227,11 +278,32 @@ sub preprocess_updatenode {
|
||||
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) {
|
||||
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 $synclist (keys %syncfile_node) {
|
||||
my $args = ["-F", "$synclist"];
|
||||
my $env = ["DSH_RSYNC_FILE=$synclist"];
|
||||
$subreq->({command=>['xdcp'], node=>$syncfile_node{$synclist}, arg=>$args, env=>$env}, $callback);
|
||||
}
|
||||
}
|
||||
|
||||
my $nodestring=join(',', @$nodes);
|
||||
#print "postscripts=$postscripts, nodestring=$nodestring\n";
|
||||
|
||||
|
@ -257,6 +257,10 @@ if ($inet6support) {
|
||||
}
|
||||
print $conn "#END OF SCRIPT\n";
|
||||
close($conn);
|
||||
} elsif ($text =~ /^syncfiles/) {
|
||||
plugin_command({command=>['syncfiles'],_xcat_clienthost=>[$node]},undef,\&build_response);
|
||||
print $conn "syncfiles done\n";
|
||||
close($conn);
|
||||
} elsif ($text =~ /^rebootnodes/) {
|
||||
my @cmdargs = split(/\s+/,$text);
|
||||
my $rebootcmd = shift(@cmdargs);
|
||||
|
@ -143,4 +143,8 @@ fi
|
||||
if [ -r /root/.ssh/id_rsa ]; then
|
||||
ssh-keygen -y -f /root/.ssh/id_rsa > /root/.ssh/id_rsa.pub
|
||||
fi
|
||||
|
||||
# start up the sshd for syncfiles postscript to do the sync work
|
||||
service sshd start
|
||||
|
||||
kill -9 $CREDPID
|
||||
|
24
xCAT/postscripts/startsyncfiles.awk
Executable file
24
xCAT/postscripts/startsyncfiles.awk
Executable file
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/awk -f
|
||||
BEGIN {
|
||||
if (ENVIRON["USEOPENSSLFORXCAT"]) {
|
||||
server = "openssl s_client -quiet -connect " ENVIRON["XCATSERVER"]
|
||||
} else {
|
||||
server = "/inet/tcp/0/127.0.0.1/400"
|
||||
}
|
||||
|
||||
quit = "no"
|
||||
|
||||
print "<xcatrequest>" |& server
|
||||
print " <command>syncfiles</command>" |& server
|
||||
print "</xcatrequest>" |& server
|
||||
|
||||
while (server |& getline) {
|
||||
if (match($0,"<syncfiles done>")) {
|
||||
quit = "yes"
|
||||
}
|
||||
if (match($0,"</xcatresponse>") && match(quit,"yes")) {
|
||||
close(server)
|
||||
exit
|
||||
}
|
||||
}
|
||||
}
|
69
xCAT/postscripts/syncfiles
Normal file
69
xCAT/postscripts/syncfiles
Normal file
@ -0,0 +1,69 @@
|
||||
#!/usr/bin/perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#####################################################
|
||||
#
|
||||
# xCAT post script for configuration files distribution
|
||||
#
|
||||
# It should be run after the remoteshell
|
||||
# It is also run by the updatenode cmd
|
||||
#
|
||||
#####################################################
|
||||
|
||||
|
||||
# do nothing when UPDATENODE=1
|
||||
if ($ENV{'UPDATENODE'} == 1
|
||||
|| $ENV{'NODESETSTATE'} eq "netboot"
|
||||
|| $ENV{'NODESETSTATE'} eq "diskless") {
|
||||
exit 0;
|
||||
}
|
||||
|
||||
`logger -t xCAT "Performing syncfiles postscript"`;
|
||||
|
||||
# get platform
|
||||
my $osname = `uname`;
|
||||
chomp $osname;
|
||||
|
||||
# run the xdcp on the MN/SN
|
||||
my $xcatpostdir = "/xcatpost";
|
||||
my $startsync = "";
|
||||
if ($osname eq "Linux") {
|
||||
`logger -t xCAT "run $xcatpostdir/startsyncfiles.awk"`;
|
||||
$startsync = "$xcatpostdir/startsyncfiles.awk";
|
||||
`$startsync`;
|
||||
} else {
|
||||
`logger -t xCAT "run $xcatpostdir/startsyncfilesaix.awk"`;
|
||||
&startsyncfilesaix();
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
|
||||
sub startsyncfilesaix
|
||||
{
|
||||
use IO::Socket;
|
||||
|
||||
my $port = "3002";
|
||||
my $remote = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $ENV{'MASTER'}, PeerPort => $port, );
|
||||
unless ($remote) {
|
||||
`logger -t xCAT "startsyncfiles: Cannot connect to host $ENV{'MASTER'}"`;
|
||||
}
|
||||
|
||||
$remote->autoflush(1);
|
||||
|
||||
while (<$remote>) {
|
||||
my $line = $_;
|
||||
chomp($line);
|
||||
|
||||
if ($line =~ /ready/) {
|
||||
print $remote "syncfiles\n";
|
||||
}
|
||||
|
||||
if ($line =~ /syncfiles done/) {
|
||||
close $remote;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
close $remote;
|
||||
return 0;
|
||||
}
|
@ -153,6 +153,13 @@ if (-f $scriptname) {
|
||||
my $nodesetstat="standalone";
|
||||
if (-f $scriptname)
|
||||
{
|
||||
# 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`;
|
||||
}
|
||||
|
||||
if (@ARGV>1) {
|
||||
my $scripts=$ARGV[1];
|
||||
my $POSTS=join('\n', split(',', $scripts));
|
||||
|
@ -88,6 +88,14 @@ while [ -z "$MYCONT" ]; do
|
||||
MYCONT=`cat /tmp/mypostscript`
|
||||
# echo "MYCONT=$MYCONT"
|
||||
done
|
||||
|
||||
# when called by the updatenode command,
|
||||
#modify the UPDATENODE flag to 1
|
||||
if [ $# -gt 0 ]; then
|
||||
TMP=`sed -e 's/UPDATENODE=0/UPDATENODE=1/g' /tmp/mypostscript`;
|
||||
echo "$TMP" > /tmp/mypostscript;
|
||||
fi
|
||||
|
||||
if [ $# -gt 1 ]; then
|
||||
POSTS=$2
|
||||
#remove all the postscripts
|
||||
|
Loading…
Reference in New Issue
Block a user