2007-10-26 22:44:33 +00:00
|
|
|
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
#-------------------------------------------------------
|
|
|
|
|
2008-02-18 15:57:25 +00:00
|
|
|
=head1
|
2007-10-26 22:44:33 +00:00
|
|
|
xCAT plugin package to handle xdsh
|
|
|
|
|
|
|
|
Supported command:
|
|
|
|
xdsh-> dsh
|
|
|
|
xdcp-> dcp
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
#-------------------------------------------------------
|
|
|
|
package xCAT_plugin::xdsh;
|
2008-07-18 12:04:28 +00:00
|
|
|
use strict;
|
2009-07-07 11:38:53 +00:00
|
|
|
use Storable qw(dclone);
|
2009-09-21 13:09:26 +00:00
|
|
|
use File::Basename;
|
|
|
|
use File::Path;
|
2008-04-07 19:25:44 +00:00
|
|
|
require xCAT::Table;
|
2007-10-26 22:44:33 +00:00
|
|
|
|
2008-04-07 19:25:44 +00:00
|
|
|
require xCAT::Utils;
|
2007-10-26 22:44:33 +00:00
|
|
|
|
2008-04-07 19:25:44 +00:00
|
|
|
require xCAT::MsgUtils;
|
2007-12-12 13:24:36 +00:00
|
|
|
use Getopt::Long;
|
|
|
|
require xCAT::DSHCLI;
|
2007-10-26 22:44:33 +00:00
|
|
|
1;
|
|
|
|
|
|
|
|
#-------------------------------------------------------
|
|
|
|
|
2008-02-18 15:57:25 +00:00
|
|
|
=head3 handled_commands
|
2007-10-26 22:44:33 +00:00
|
|
|
|
|
|
|
Return list of commands handled by this plugin
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
#-------------------------------------------------------
|
|
|
|
|
|
|
|
sub handled_commands
|
|
|
|
{
|
|
|
|
return {
|
|
|
|
xdsh => "xdsh",
|
|
|
|
xdcp => "xdsh"
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2008-03-10 18:25:22 +00:00
|
|
|
#-------------------------------------------------------
|
|
|
|
|
|
|
|
=head3 preprocess_request
|
|
|
|
|
|
|
|
Check and setup for hierarchy
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
#-------------------------------------------------------
|
2008-03-31 18:17:00 +00:00
|
|
|
sub preprocess_request
|
|
|
|
{
|
|
|
|
my $req = shift;
|
|
|
|
my $cb = shift;
|
|
|
|
my %sn;
|
2008-07-18 12:04:28 +00:00
|
|
|
my $sn;
|
2009-09-21 13:09:26 +00:00
|
|
|
my $command = $req->{command}->[0]; # xdsh vs xdcp
|
2009-07-22 13:36:13 +00:00
|
|
|
|
2009-03-16 13:24:16 +00:00
|
|
|
#if already preprocessed, go straight to request
|
2009-05-19 14:59:17 +00:00
|
|
|
if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; }
|
2008-10-17 16:04:13 +00:00
|
|
|
my $nodes = $req->{node};
|
|
|
|
my $service = "xcat";
|
2008-07-18 12:04:28 +00:00
|
|
|
my @requests;
|
2009-06-25 18:17:53 +00:00
|
|
|
my $syncsn = 0;
|
|
|
|
my $syncsnfile;
|
2009-09-23 11:44:08 +00:00
|
|
|
my $dcppull = 0;
|
2009-06-25 18:17:53 +00:00
|
|
|
|
|
|
|
# read the environment variables for rsync setup
|
2009-05-19 14:59:17 +00:00
|
|
|
foreach my $envar (@{$req->{env}})
|
|
|
|
{
|
|
|
|
my ($var, $value) = split(/=/, $envar, 2);
|
2009-07-22 13:36:13 +00:00
|
|
|
if ($var eq "RSYNCSNONLY")
|
2009-06-04 12:21:10 +00:00
|
|
|
{ # syncing SN, will change noderange to list of SN
|
2009-07-22 13:36:13 +00:00
|
|
|
# we are only syncing the service node ( -s flag)
|
2009-06-04 12:21:10 +00:00
|
|
|
$syncsn = 1;
|
2009-05-25 12:27:48 +00:00
|
|
|
}
|
2009-06-04 12:21:10 +00:00
|
|
|
if ($var eq "DSH_RSYNC_FILE") # from -F flag
|
|
|
|
{ # if hierarchy,need to copy file to the SN
|
|
|
|
$syncsnfile = $value; # in the new /tmp/xcatrf.tmp
|
2009-05-19 14:59:17 +00:00
|
|
|
}
|
2009-09-23 11:44:08 +00:00
|
|
|
if ($var eq "DCP_PULL") # from -P flag
|
|
|
|
{
|
|
|
|
$dcppull = 1; # TBD handle pull hierarchy
|
|
|
|
}
|
2009-05-19 14:59:17 +00:00
|
|
|
}
|
2008-03-31 18:17:00 +00:00
|
|
|
|
|
|
|
# find service nodes for requested nodes
|
|
|
|
# build an individual request for each service node
|
2009-06-04 12:21:10 +00:00
|
|
|
# find out the names for the Management Node
|
2009-06-25 18:17:53 +00:00
|
|
|
my @MNnodeinfo = xCAT::Utils->determinehostname;
|
|
|
|
my $MNnodename = pop @MNnodeinfo; # hostname
|
|
|
|
my @MNnodeipaddr = @MNnodeinfo; # ipaddresses
|
2009-09-21 13:09:26 +00:00
|
|
|
my $mnname = $MNnodeipaddr[0];
|
2009-06-25 18:17:53 +00:00
|
|
|
my $tmpsyncsnfile = "/tmp/xcatrf.tmp";
|
2009-09-21 13:09:26 +00:00
|
|
|
my $SNpath;
|
|
|
|
|
|
|
|
my $synfiledir = "/var/xcat/syncfiles"; # default
|
2008-10-17 16:04:13 +00:00
|
|
|
if ($nodes)
|
|
|
|
{
|
|
|
|
$sn = xCAT::Utils->get_ServiceNode($nodes, $service, "MN");
|
2009-09-21 13:09:26 +00:00
|
|
|
my @snodes;
|
|
|
|
my @snoderange;
|
2009-06-25 18:17:53 +00:00
|
|
|
|
2009-09-21 13:09:26 +00:00
|
|
|
# check to see if service nodes and not just the MN
|
|
|
|
if ($sn)
|
2009-06-25 18:17:53 +00:00
|
|
|
{
|
2009-09-21 13:09:26 +00:00
|
|
|
foreach my $snkey (keys %$sn)
|
|
|
|
{
|
|
|
|
if (!grep(/$snkey/, @MNnodeipaddr))
|
|
|
|
{ # if not the MN
|
|
|
|
push @snodes, $snkey;
|
|
|
|
$snoderange[0] .= "$snkey,";
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2009-06-25 18:17:53 +00:00
|
|
|
|
2009-09-21 13:09:26 +00:00
|
|
|
if (@snodes)
|
2009-05-25 12:27:48 +00:00
|
|
|
{
|
|
|
|
|
2009-09-21 13:09:26 +00:00
|
|
|
# get the directory on the servicenode to put the files in
|
|
|
|
my @syndir = xCAT::Utils->get_site_attribute("SNsyncfiledir");
|
|
|
|
if ($syndir[0])
|
|
|
|
{
|
|
|
|
$synfiledir = $syndir[0];
|
2009-06-25 18:17:53 +00:00
|
|
|
}
|
2009-09-21 13:09:26 +00:00
|
|
|
|
|
|
|
# if -F command and service nodes first need to rsync the SN
|
|
|
|
if ($syncsnfile)
|
|
|
|
{
|
|
|
|
|
|
|
|
#change noderange to the service nodes
|
2009-06-25 18:17:53 +00:00
|
|
|
my $addreq;
|
|
|
|
chop $snoderange[0];
|
2009-09-21 13:09:26 +00:00
|
|
|
$addreq->{'_xcatdest'} = $mnname;
|
2009-06-25 18:17:53 +00:00
|
|
|
$addreq->{node} = \@snodes;
|
|
|
|
$addreq->{noderange} = \@snoderange;
|
|
|
|
$addreq->{arg}->[0] = "-s";
|
|
|
|
$addreq->{arg}->[1] = "-F";
|
|
|
|
$addreq->{arg}->[2] = $syncsnfile;
|
|
|
|
$addreq->{command}->[0] = $req->{command}->[0];
|
|
|
|
$addreq->{cwd}->[0] = $req->{cwd}->[0];
|
|
|
|
push @requests, $addreq;
|
|
|
|
|
|
|
|
# need to add to the queue to copy rsync file( -F input)
|
|
|
|
# to the service node to the /tmp/xcatrf.tmp file
|
|
|
|
my $addreq;
|
2009-09-21 13:09:26 +00:00
|
|
|
$addreq->{'_xcatdest'} = $mnname;
|
2009-06-25 18:17:53 +00:00
|
|
|
$addreq->{node} = \@snodes;
|
|
|
|
$addreq->{noderange} = \@snoderange;
|
|
|
|
$addreq->{arg}->[0] = $syncsnfile;
|
|
|
|
$addreq->{arg}->[1] = $tmpsyncsnfile;
|
|
|
|
$addreq->{command}->[0] = $req->{command}->[0];
|
|
|
|
$addreq->{cwd}->[0] = $req->{cwd}->[0];
|
|
|
|
push @requests, $addreq;
|
2009-06-04 12:21:10 +00:00
|
|
|
}
|
2009-09-21 13:09:26 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
|
|
|
|
# if other xdcp command
|
|
|
|
# mk the diretory on the SN to hold the files
|
|
|
|
# to be sent to the CN.
|
|
|
|
# build a command to update the service nodes
|
|
|
|
# change the destination to the tmp location on
|
2009-09-23 11:44:08 +00:00
|
|
|
# the service node, if not pull function
|
|
|
|
if (($command eq "xdcp") && ($dcppull == 0))
|
2009-09-21 13:09:26 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
#make the needed directory on the service node
|
|
|
|
# create new directory for path on Service Node
|
|
|
|
my $frompath = $req->{arg}->[-2];
|
|
|
|
$SNpath = $synfiledir;
|
|
|
|
$SNpath .= $frompath;
|
|
|
|
my $SNdir;
|
|
|
|
$SNdir = dirname($SNpath); # get directory
|
|
|
|
my $addreq= dclone($req);
|
|
|
|
$addreq->{'_xcatdest'} = $mnname;
|
|
|
|
$addreq->{node} = \@snodes;
|
|
|
|
$addreq->{noderange} = \@snoderange;
|
|
|
|
$addreq->{arg}->[0] = "mkdir ";
|
|
|
|
$addreq->{arg}->[1] = "-p ";
|
|
|
|
$addreq->{arg}->[2] = $SNdir;
|
|
|
|
$addreq->{command}->[0] = "xdsh";
|
|
|
|
$addreq->{cwd}->[0] = $req->{cwd}->[0];
|
|
|
|
push @requests, $addreq;
|
|
|
|
|
|
|
|
# now sync file to the service node to the new
|
|
|
|
# tmp path
|
|
|
|
my $addreq = dclone($req);
|
|
|
|
$addreq->{'_xcatdest'} = $mnname;
|
|
|
|
chop $snoderange[0];
|
|
|
|
$addreq->{node} = \@snodes;
|
|
|
|
$addreq->{noderange} = \@snoderange;
|
|
|
|
$addreq->{arg}->[-1] = $SNdir;
|
|
|
|
push @requests, $addreq;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2009-05-25 12:27:48 +00:00
|
|
|
}
|
2009-09-21 13:09:26 +00:00
|
|
|
} # end if SN
|
2009-06-04 12:21:10 +00:00
|
|
|
|
2009-07-22 13:36:13 +00:00
|
|
|
# if not only syncing the service nodes ( -s flag)
|
|
|
|
# for each node build the
|
2009-09-21 13:09:26 +00:00
|
|
|
# the command, to sync from the service node
|
2009-07-22 13:36:13 +00:00
|
|
|
if ($syncsn == 0)
|
2009-09-21 13:09:26 +00:00
|
|
|
{ #syncing nodes ( no -s flag)
|
2009-07-22 13:36:13 +00:00
|
|
|
foreach my $snkey (keys %$sn)
|
|
|
|
{
|
2009-06-04 12:21:10 +00:00
|
|
|
|
2009-07-22 13:36:13 +00:00
|
|
|
if (!grep(/$snkey/, @MNnodeipaddr))
|
|
|
|
{ # entries run from the Service Node
|
2009-06-25 18:17:53 +00:00
|
|
|
|
2009-07-22 13:36:13 +00:00
|
|
|
# if the -F option to sync the nodes
|
|
|
|
# then for a Service Node
|
|
|
|
# change the command to use the -F /tmp/xcatrf.tmp
|
|
|
|
# because that is where the file was put on the SN
|
|
|
|
#
|
|
|
|
my $newSNreq = dclone($req);
|
|
|
|
if ($syncsnfile) # -F option
|
2009-06-04 12:21:10 +00:00
|
|
|
{
|
2009-07-22 13:36:13 +00:00
|
|
|
my $args = $newSNreq->{arg};
|
2009-06-04 12:21:10 +00:00
|
|
|
|
2009-07-22 13:36:13 +00:00
|
|
|
my $i = 0;
|
|
|
|
foreach my $argument (@$args)
|
2009-06-25 18:17:53 +00:00
|
|
|
{
|
2009-07-22 13:36:13 +00:00
|
|
|
|
|
|
|
# find the -F and change the name of the
|
|
|
|
# file in the next array entry to the tmp file
|
|
|
|
if ($argument eq "-F")
|
|
|
|
{
|
|
|
|
$i++;
|
|
|
|
$newSNreq->{arg}->[$i] = $tmpsyncsnfile;
|
|
|
|
last;
|
|
|
|
}
|
2009-06-04 12:21:10 +00:00
|
|
|
$i++;
|
|
|
|
}
|
|
|
|
}
|
2009-09-21 13:09:26 +00:00
|
|
|
else
|
|
|
|
{ # if other dcp command, change from directory
|
|
|
|
# to be the tmp directory on the service node
|
2009-09-23 11:44:08 +00:00
|
|
|
# if not pull (-P) funcion
|
|
|
|
if (($command eq "xdcp") && ($dcppull == 0))
|
2009-09-21 13:09:26 +00:00
|
|
|
{
|
|
|
|
$newSNreq->{arg}->[-2] = $SNpath;
|
|
|
|
}
|
|
|
|
}
|
2009-07-22 13:36:13 +00:00
|
|
|
$newSNreq->{node} = $sn->{$snkey};
|
|
|
|
$newSNreq->{'_xcatdest'} = $snkey;
|
|
|
|
$newSNreq->{_xcatpreprocessed}->[0] = 1;
|
|
|
|
push @requests, $newSNreq;
|
2009-06-04 12:21:10 +00:00
|
|
|
}
|
2009-07-22 13:36:13 +00:00
|
|
|
else
|
2009-09-21 13:09:26 +00:00
|
|
|
{ # just run normal dsh dcp
|
2009-07-22 13:36:13 +00:00
|
|
|
my $reqcopy = {%$req};
|
|
|
|
$reqcopy->{node} = $sn->{$snkey};
|
|
|
|
$reqcopy->{'_xcatdest'} = $snkey;
|
|
|
|
$reqcopy->{_xcatpreprocessed}->[0] = 1;
|
|
|
|
push @requests, $reqcopy;
|
|
|
|
|
|
|
|
}
|
|
|
|
} # end foreach
|
|
|
|
} # end syncing only service nodes
|
2009-06-25 18:17:53 +00:00
|
|
|
|
2008-10-17 16:04:13 +00:00
|
|
|
}
|
|
|
|
else
|
2009-07-22 13:36:13 +00:00
|
|
|
{ # running local on image
|
2008-10-17 16:04:13 +00:00
|
|
|
return [$req];
|
2008-03-31 18:17:00 +00:00
|
|
|
}
|
|
|
|
return \@requests;
|
|
|
|
}
|
2008-03-10 18:25:22 +00:00
|
|
|
|
2007-10-26 22:44:33 +00:00
|
|
|
#-------------------------------------------------------
|
|
|
|
|
2008-02-18 15:57:25 +00:00
|
|
|
=head3 process_request
|
2007-10-26 22:44:33 +00:00
|
|
|
|
|
|
|
Process the command
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
#-------------------------------------------------------
|
|
|
|
sub process_request
|
|
|
|
{
|
|
|
|
|
|
|
|
my $request = shift;
|
|
|
|
my $callback = shift;
|
|
|
|
my $nodes = $request->{node};
|
|
|
|
my $command = $request->{command}->[0];
|
|
|
|
my $args = $request->{arg};
|
2007-12-12 13:24:36 +00:00
|
|
|
my $envs = $request->{env};
|
2008-10-17 16:04:13 +00:00
|
|
|
my $rsp = {};
|
2008-02-18 15:57:25 +00:00
|
|
|
# get the Environment Variables and set them in the current environment
|
2008-03-31 18:17:00 +00:00
|
|
|
foreach my $envar (@{$request->{env}})
|
|
|
|
{
|
|
|
|
my ($var, $value) = split(/=/, $envar, 2);
|
|
|
|
$ENV{$var} = $value;
|
2007-12-12 13:24:36 +00:00
|
|
|
}
|
|
|
|
if ($command eq "xdsh")
|
|
|
|
{
|
|
|
|
xdsh($nodes, $args, $callback, $command, $request->{noderange}->[0]);
|
2007-10-26 22:44:33 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-12-12 13:24:36 +00:00
|
|
|
if ($command eq "xdcp")
|
2007-10-26 22:44:33 +00:00
|
|
|
{
|
2007-12-12 13:24:36 +00:00
|
|
|
xdcp($nodes, $args, $callback, $command,
|
|
|
|
$request->{noderange}->[0]);
|
2007-10-26 22:44:33 +00:00
|
|
|
}
|
|
|
|
else
|
2007-12-12 13:24:36 +00:00
|
|
|
{
|
2008-10-17 16:04:13 +00:00
|
|
|
my $rsp = {};
|
2007-10-26 22:44:33 +00:00
|
|
|
$rsp->{data}->[0] =
|
2008-02-18 15:57:25 +00:00
|
|
|
"Unknown command $command. Cannot process the command.";
|
|
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
|
|
return;
|
2007-10-26 22:44:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#-------------------------------------------------------
|
|
|
|
|
2008-02-18 15:57:25 +00:00
|
|
|
=head3 xdsh
|
2007-10-26 22:44:33 +00:00
|
|
|
|
2008-02-18 15:57:25 +00:00
|
|
|
Parses Builds and runs the dsh
|
2007-10-26 22:44:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
#-------------------------------------------------------
|
|
|
|
sub xdsh
|
|
|
|
{
|
2007-12-12 13:24:36 +00:00
|
|
|
my ($nodes, $args, $callback, $command, $noderange) = @_;
|
2008-03-31 18:17:00 +00:00
|
|
|
|
2009-11-10 15:57:05 +00:00
|
|
|
$::FAILED_NODES=0;
|
|
|
|
# parse dsh input, will return $::NUMBER_NODES_FAILED
|
2008-07-18 12:04:28 +00:00
|
|
|
my @local_results =
|
2007-12-12 13:24:36 +00:00
|
|
|
xCAT::DSHCLI->parse_and_run_dsh($nodes, $args, $callback,
|
|
|
|
$command, $noderange);
|
2009-10-22 13:53:49 +00:00
|
|
|
#print $local_results[0];
|
|
|
|
#print "\n";
|
|
|
|
#`echo $local_results[0] >> /tmp/lissa/testxdsh`;
|
|
|
|
my $maxlines=10000;
|
|
|
|
my $arraylen=@local_results;
|
|
|
|
my $rsp = {};
|
|
|
|
my $i=0;
|
|
|
|
my $j;
|
|
|
|
while ($i < $arraylen) {
|
|
|
|
for ($j = 0 ; $j < $maxlines ; $j++) {
|
|
|
|
if ($i > $arraylen) {
|
|
|
|
last;
|
|
|
|
} else {
|
|
|
|
$rsp->{data}->[$j]= $local_results[$i]; # send max lines
|
|
|
|
}
|
|
|
|
$i++
|
|
|
|
}
|
|
|
|
xCAT::MsgUtils->message("D", $rsp, $callback);
|
|
|
|
}
|
2009-11-10 15:57:05 +00:00
|
|
|
# set return code
|
|
|
|
$rsp = {};
|
|
|
|
$rsp->{errorcode}= $::FAILED_NODES;
|
|
|
|
$callback->($rsp);
|
|
|
|
return();
|
2007-12-12 13:24:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#-------------------------------------------------------
|
|
|
|
|
2008-02-18 15:57:25 +00:00
|
|
|
=head3 xdcp
|
2007-12-12 13:24:36 +00:00
|
|
|
|
2008-02-18 15:57:25 +00:00
|
|
|
Parses, Builds and runs the dcp command
|
2007-12-12 13:24:36 +00:00
|
|
|
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
|
|
#-------------------------------------------------------
|
|
|
|
sub xdcp
|
|
|
|
{
|
|
|
|
my ($nodes, $args, $callback, $command, $noderange) = @_;
|
2008-03-31 18:17:00 +00:00
|
|
|
|
2008-03-10 18:25:22 +00:00
|
|
|
#`touch /tmp/lissadebug`;
|
2007-12-12 13:24:36 +00:00
|
|
|
# parse dcp input
|
2008-07-18 12:04:28 +00:00
|
|
|
my @local_results =
|
2007-12-12 13:24:36 +00:00
|
|
|
xCAT::DSHCLI->parse_and_run_dcp($nodes, $args, $callback,
|
|
|
|
$command, $noderange);
|
2008-10-17 16:04:13 +00:00
|
|
|
my $rsp = {};
|
|
|
|
my $i = 0;
|
2007-12-12 13:24:36 +00:00
|
|
|
## process return data
|
2007-10-26 22:44:33 +00:00
|
|
|
foreach my $line (@local_results)
|
|
|
|
{
|
|
|
|
$rsp->{data}->[$i] = $line;
|
|
|
|
$i++;
|
|
|
|
}
|
|
|
|
|
2009-09-16 14:55:13 +00:00
|
|
|
xCAT::MsgUtils->message("D", $rsp, $callback);
|
2009-06-25 18:17:53 +00:00
|
|
|
if (-e "/tmp/xcatrf.tmp")
|
|
|
|
{ # used tmp file for -F option
|
|
|
|
#`rm /tmp/xcatrf.tmp`;
|
2009-06-04 12:21:10 +00:00
|
|
|
}
|
2008-02-18 15:57:25 +00:00
|
|
|
return;
|
2007-10-26 22:44:33 +00:00
|
|
|
}
|
|
|
|
|