support for rinv in sinv -- still needs testing, some bugs to fix
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@2387 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
parent
072d8a5aa0
commit
1fb520d844
@ -27,6 +27,7 @@ my $errored = 0;
|
||||
my @dshresult;
|
||||
my $templatepath;
|
||||
my $processflg;
|
||||
my @cmdresult;
|
||||
|
||||
#
|
||||
# Subroutines
|
||||
@ -46,13 +47,13 @@ sub usage
|
||||
|
||||
my $usagemsg1 =
|
||||
"The sinv command is designed to check the configuration of nodes in a cluster.\nRun man sinv for more information.\n\nInput parameters are as follows:\n";
|
||||
my $usagemsg1a = "sinv -h \nsinv -v \nsinv [noderange]\n";
|
||||
my $usagemsg1a = "sinv -h \nsinv -v \nsinv \n";
|
||||
my $usagemsg2 = " [-V verbose] [-v version] [-h usage]\n ";
|
||||
my $usagemsg3 =
|
||||
" [-o output file ] [-p template path] [-t template count]\n";
|
||||
my $usagemsg4 = " [-r remove templates] [-s seednode]\n";
|
||||
" [-o output file ] [-p <template path>] [-t <template count>]\n";
|
||||
my $usagemsg4 = " [-r remove templates] [-s <seednode>]\n";
|
||||
my $usagemsg4a = " [-e exactmatch] [-i ignore]\n";
|
||||
my $usagemsg5 = " [-c xdsh command | -f xdsh command file] \n ";
|
||||
my $usagemsg5 = " [-c <command> | -f <command file>] \n ";
|
||||
my $usagemsg .= $usagemsg1 .= $usagemsg2 .= $usagemsg3 .= $usagemsg4 .=
|
||||
$usagemsg4a .= $usagemsg5;
|
||||
### end usage mesage
|
||||
@ -76,31 +77,14 @@ sub parse_and_run_sinv
|
||||
{
|
||||
my ($class, $request, $callback, $sub_req) = @_;
|
||||
my $rsp = {};
|
||||
my $rc = 0;
|
||||
$::CALLBACK = $callback;
|
||||
my $args = $request->{arg};
|
||||
@ARGV = @{$args}; # get arguments
|
||||
my @noderange;
|
||||
my $noderange = $ARGV[0];
|
||||
if ($noderange =~ /^-/)
|
||||
{ # no noderange, it is a flag
|
||||
@noderange = "NO_NODE_RANGE";
|
||||
}
|
||||
else
|
||||
{ # get noderange
|
||||
@noderange = noderange($noderange); # expand noderange
|
||||
my $tmp = shift(@ARGV); # shift the noderange from the args
|
||||
if (nodesmissed)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] =
|
||||
"Invalid nodes in noderange:" . join(',', nodesmissed);
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
my $args = $request->{arg};
|
||||
@ARGV = @{$args}; # get arguments
|
||||
my %options = ();
|
||||
$Getopt::Long::ignorecase = 0; #Checks case in GetOptions
|
||||
Getopt::Long::Configure("bundling");
|
||||
|
||||
if (
|
||||
!GetOptions(
|
||||
'h|help' => \$options{'help'},
|
||||
@ -111,8 +95,8 @@ sub parse_and_run_sinv
|
||||
's|seed=s' => \$options{'seed_node'},
|
||||
'e|exactmatch' => \$options{'exactmatch'},
|
||||
'i|ignorefirst' => \$options{'ignorefirst'},
|
||||
'c|cmd=s' => \$options{'xdsh_cmd'},
|
||||
'f|file=s' => \$options{'xdsh_file'},
|
||||
'c|cmd=s' => \$options{'sinv_cmd'},
|
||||
'f|file=s' => \$options{'sinv_cmd_file'},
|
||||
'v|version' => \$options{'version'},
|
||||
'V|Verbose' => \$options{'verbose'},
|
||||
)
|
||||
@ -141,62 +125,103 @@ sub parse_and_run_sinv
|
||||
$::VERBOSE = "yes";
|
||||
}
|
||||
|
||||
# if neither xdsh command or file, error
|
||||
if (!($options{'xdsh_cmd'}) && (!($options{'xdsh_file'})))
|
||||
# if neither command or file, error
|
||||
if (!($options{'sinv_cmd'}) && (!($options{'sinv_cmd_file'})))
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] =
|
||||
"Neither the xdsh command, nor the xdsh command file have been supplied.\n";
|
||||
"Neither the sinv command, nor the sinv command file have been supplied.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# if both xdsh command and file, error
|
||||
if (($options{'xdsh_cmd'}) && (($options{'xdsh_file'})))
|
||||
# if both command and file, error
|
||||
if (($options{'sinv_cmd'}) && (($options{'sinv_cmd_file'})))
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] =
|
||||
"Both the xdsh command, and the xdsh command file have been supplied. Only one or the other is allowed.\n";
|
||||
"Both the sinv command, and the sinv command file have been supplied. Only one or the other is allowed.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
exit 1;
|
||||
}
|
||||
|
||||
#
|
||||
# get the node list
|
||||
#
|
||||
if (!(@noderange))
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "No noderange specified on the command.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
exit 1;
|
||||
}
|
||||
my @nodelist = @noderange;
|
||||
|
||||
#
|
||||
# Get Command to run
|
||||
#
|
||||
my $cmd;
|
||||
if ($options{'xdsh_cmd'})
|
||||
if ($options{'sinv_cmd'})
|
||||
{
|
||||
$cmd = $options{'xdsh_cmd'};
|
||||
$cmd = $options{'sinv_cmd'};
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
# read the command from the file
|
||||
if (!(-e $options{'xdsh_file'}))
|
||||
if (!(-e $options{'sinv_cmd_file'}))
|
||||
{ # file does not exist
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] =
|
||||
"Input xdsh command file: $options{'xdsh_file'} does not exist.\n";
|
||||
"Input command file: $options{'sinv_cmd_file'} does not exist.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
exit 1;
|
||||
}
|
||||
$cmd = `cat $options{'xdsh_file'}`;
|
||||
$cmd = `cat $options{'sinv_cmd_file'}`;
|
||||
}
|
||||
chomp $cmd;
|
||||
|
||||
#
|
||||
# the command can be either xdsh or rinv for now
|
||||
# strip off the program and the noderange
|
||||
#
|
||||
my @nodelist = ();
|
||||
my ($cmdtype, $noderange, $args) = split(' ', $cmd, 3);
|
||||
$cmd = "";
|
||||
if ($noderange =~ /^-/)
|
||||
{ # no noderange
|
||||
$cmd .= "$noderange "; # put flag back on command
|
||||
}
|
||||
$cmd .= $args;
|
||||
if (($cmdtype ne "xdsh") && ($cmdtype ne "rinv"))
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] =
|
||||
"Only commands xdsh and rinv are currently supported.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
exit 1;
|
||||
}
|
||||
my $cmdoutput;
|
||||
if ($cmdtype eq "xdsh")
|
||||
{ # chose output routine to run
|
||||
$cmdoutput = "xdshoutput";
|
||||
}
|
||||
else
|
||||
{ # rinv
|
||||
$cmdoutput = "rinvoutput";
|
||||
}
|
||||
|
||||
# this must be a noderange or the flag indicating we are going to the
|
||||
# install image ( -i) for xdsh, only case where noderange is not required
|
||||
|
||||
if ($noderange =~ /^-/)
|
||||
{ # no noderange, it is a flag
|
||||
@nodelist = "NO_NODE_RANGE";
|
||||
|
||||
# add flag back to arguments
|
||||
$args .= $noderange;
|
||||
}
|
||||
else
|
||||
{ # get noderange
|
||||
@nodelist = noderange($noderange); # expand noderange
|
||||
if (nodesmissed)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] =
|
||||
"Invalid or missing noderange:" . join(',', nodesmissed);
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Get exact match request
|
||||
#
|
||||
@ -290,9 +315,9 @@ sub parse_and_run_sinv
|
||||
$::OUTPUT_FILE_HANDLE = \*OUTPUTFILE;
|
||||
|
||||
#
|
||||
#
|
||||
# For xdsh command
|
||||
# Get seed node if it exists to build the original template
|
||||
# if seed node does not exist and the admin did not submit a \
|
||||
# if seed node does not exist and the admin did not submit a
|
||||
# template, the the first node becomes the seed node
|
||||
#
|
||||
my @seed;
|
||||
@ -320,11 +345,11 @@ sub parse_and_run_sinv
|
||||
$rsp->{data}->[0] = "Command started with following input.\n";
|
||||
if ($cmd)
|
||||
{
|
||||
$rsp->{data}->[1] = "xdsh cmd:$cmd.\n";
|
||||
$rsp->{data}->[1] = "$cmdtype cmd:$cmd.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$rsp->{data}->[1] = "xdsh cmd:None.\n";
|
||||
$rsp->{data}->[1] = "$cmdtype cmd:None.\n";
|
||||
}
|
||||
$rsp->{data}->[2] = "Template path:$templatepath.\n";
|
||||
$rsp->{data}->[3] = "Template cnt:$templatecnt.\n";
|
||||
@ -340,9 +365,9 @@ sub parse_and_run_sinv
|
||||
{
|
||||
$rsp->{data}->[8] = "Seed node:None.\n";
|
||||
}
|
||||
if ($options{'xdsh_file'})
|
||||
if ($options{'sinv_cmd_file'})
|
||||
{
|
||||
$rsp->{data}->[9] = "file:$options{'xdsh_file'}.\n";
|
||||
$rsp->{data}->[9] = "file:$options{'sinv_cmd_file'}.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -362,63 +387,67 @@ sub parse_and_run_sinv
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
|
||||
# setup a tempfile for xdsh output
|
||||
# setup a tempfile for command output
|
||||
$tempfile = "/tmp/sinv.$$";
|
||||
|
||||
#
|
||||
# if we are to seed the original template,run the dsh command against the
|
||||
# seed node and save in template_path
|
||||
# already checked for rinv command above and exited, if seed node
|
||||
#
|
||||
if ($seednode)
|
||||
{
|
||||
|
||||
# Below code needed to run xdsh from the plugin
|
||||
# Below code needed to run xdsh or rinv from the plugin
|
||||
# and still support a hierarchial xdsh
|
||||
# this will run xdsh with input, return to xdshoutput routine
|
||||
# this will run xdsh or rinv with input, return to
|
||||
# xdshoutput routine or rinvoutput routine
|
||||
# and then return inline after this code.
|
||||
|
||||
$processflg = "seednode";
|
||||
$sub_req->(
|
||||
{
|
||||
command => ['xdsh'],
|
||||
command => [$cmdtype],
|
||||
node => \@seed,
|
||||
arg => [$cmd]
|
||||
},
|
||||
\&xdshoutput
|
||||
\&$cmdoutput
|
||||
);
|
||||
|
||||
# write the results to the tempfile after running through xdshbak
|
||||
$rc = &storeresults;
|
||||
|
||||
}
|
||||
$processflg = "node";
|
||||
|
||||
# Tell them we are running DSH
|
||||
# Tell them we are running the command
|
||||
if ($::VERBOSE)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "Running xdsh command.\n";
|
||||
$rsp->{data}->[0] = "Running $cmdtype command.\n";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
|
||||
#
|
||||
# Run the DSH command
|
||||
#
|
||||
|
||||
# Below code needed to run xdsh from the plugin
|
||||
# Below code needed to run xdsh/rinv from the plugin
|
||||
# and still support a hierarchial xdsh
|
||||
# this will run xdsh with input, return to xdshoutput routine
|
||||
# this will run the command with input, return to cmdoutput routine
|
||||
# and then return inline after this code.
|
||||
|
||||
$sub_req->(
|
||||
{
|
||||
command => ['xdsh'],
|
||||
command => [$cmdtype],
|
||||
node => \@nodelist,
|
||||
arg => [$cmd]
|
||||
},
|
||||
\&xdshoutput
|
||||
\&$cmdoutput
|
||||
);
|
||||
|
||||
# write the results to the tempfile after running through xdshbak
|
||||
$rc = &storeresults;
|
||||
|
||||
# Build report and write to output file
|
||||
# if file exist and has something in it
|
||||
if (-e $tempfile)
|
||||
{ # if dsh returned something
|
||||
if ((-e $tempfile) && ($rc == 0))
|
||||
{ # if cmd returned something
|
||||
|
||||
# Tell them we are building the report
|
||||
my $rsp = {};
|
||||
@ -436,23 +465,27 @@ sub parse_and_run_sinv
|
||||
else
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "No output from xdsh.\n";
|
||||
$rsp->{data}->[0] = "No output from $cmdtype.\n";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
|
||||
# Finally we need to cleanup and exit
|
||||
#
|
||||
system("/bin/rm $tempfile");
|
||||
if (-e $tempfile)
|
||||
{
|
||||
system("/bin/rm $tempfile");
|
||||
}
|
||||
close(OUTPUTFILE);
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "Command Complete. Check report in $outputfile.\n";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
|
||||
return $rc;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
=head3 buildreport
|
||||
=head3 buildreport (note originally written only for xdsh but
|
||||
now supports rinv also)
|
||||
|
||||
This routine will take the input template and compare against
|
||||
the output of the dsh command and build a report of the differences.
|
||||
@ -517,7 +550,7 @@ sub buildreport
|
||||
}
|
||||
}
|
||||
|
||||
# Read the output of the dsh command
|
||||
# Read the output of the dsh or rinv command
|
||||
|
||||
if (!open(DSHRESULTS, "<$dshrun"))
|
||||
{
|
||||
@ -590,12 +623,12 @@ sub buildreport
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ($dshline !~ /---------/)
|
||||
&& ($dshline !~ /^\s*$/))
|
||||
|
||||
# skip headers and blanks and stop on the next host
|
||||
if ($dshline !~ /^\s*$/) # skip blanks
|
||||
|
||||
# skip blanks and stop on the next host
|
||||
{
|
||||
push @Nodearray, $dshline; # build the node results dsh
|
||||
push @Nodearray, $dshline; # build the node results
|
||||
}
|
||||
}
|
||||
|
||||
@ -847,7 +880,7 @@ sub diffoutput
|
||||
my @template_noheader = ();
|
||||
my @nodearray_noheader = ();
|
||||
|
||||
# build a node arrray without the header
|
||||
# build a node array without the header
|
||||
foreach $nodeline (@Nodearray) # for each node line
|
||||
{
|
||||
if ($nodeline =~ /HOST:/)
|
||||
@ -859,7 +892,10 @@ sub diffoutput
|
||||
}
|
||||
else # build node array with no header
|
||||
{
|
||||
push(@nodearray_noheader, $nodeline);
|
||||
if ($nodeline !~ /---------/)
|
||||
{
|
||||
push(@nodearray_noheader, $nodeline);
|
||||
}
|
||||
}
|
||||
} # end foreach nodeline
|
||||
|
||||
@ -995,10 +1031,11 @@ sub writereport
|
||||
@nodenames = @{$nodehash{$template}};
|
||||
foreach my $nodename (@nodenames)
|
||||
{
|
||||
push @nodearray, $nodename; # build an array of all the nodes
|
||||
my @shortnodename = split(/\./, $nodename);
|
||||
push @nodearray, $shortnodename[0]; # build an array of the nodes
|
||||
if ($ignorefirsttemplate ne "YES")
|
||||
{ # report first template
|
||||
$rsp->{data}->[0] = "$nodename\n";
|
||||
{ # report first template
|
||||
$rsp->{data}->[0] = "$shortnodename[0]\n";
|
||||
print $::OUTPUT_FILE_HANDLE $rsp->{data}->[0];
|
||||
if ($::VERBOSE)
|
||||
{
|
||||
@ -1021,16 +1058,22 @@ sub writereport
|
||||
|
||||
#
|
||||
# Now check to see if we covered all nodes in the dsh
|
||||
# short names must match long names
|
||||
#
|
||||
my $firstpass = 0;
|
||||
my $nodefound = 0;
|
||||
foreach my $dshnodename (@dshnodearray)
|
||||
{
|
||||
my @shortdshnodename;
|
||||
my @shortnodename;
|
||||
chomp $dshnodename;
|
||||
$dshnodename =~ s/\s*//g; # remove blanks
|
||||
foreach my $nodename (@nodearray)
|
||||
{
|
||||
if ($dshnodename eq $nodename)
|
||||
@shortdshnodename = split(/\./, $dshnodename);
|
||||
@shortnodename = split(/\./, $nodename);
|
||||
|
||||
if ($shortdshnodename[0] eq $shortnodename[0])
|
||||
{
|
||||
$nodefound = 1; # we have a match
|
||||
last;
|
||||
@ -1040,8 +1083,7 @@ sub writereport
|
||||
{ # dsh node name missing
|
||||
if ($firstpass == 0)
|
||||
{ # put out header
|
||||
$rsp->{data}->[0] =
|
||||
"The following nodes had no output from xdsh:\n";
|
||||
$rsp->{data}->[0] = "The following nodes had no output:\n";
|
||||
print $::OUTPUT_FILE_HANDLE $rsp->{data}->[0];
|
||||
if ($::VERBOSE)
|
||||
{
|
||||
@ -1051,7 +1093,7 @@ sub writereport
|
||||
}
|
||||
|
||||
# add missing node
|
||||
$rsp->{data}->[0] = "$dshnodename\n";
|
||||
$rsp->{data}->[0] = "$shortdshnodename[0]\n";
|
||||
print $::OUTPUT_FILE_HANDLE $rsp->{data}->[0];
|
||||
if ($::VERBOSE)
|
||||
{
|
||||
@ -1065,69 +1107,174 @@ sub writereport
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
=head3 dshoutput
|
||||
=head3 xdshoutput
|
||||
|
||||
Check xdsh output - get output from xdsh and pipe to xdshbak and
|
||||
store results in $tempfile or $templatepath ( for seed node) based on
|
||||
$processflag = seednode
|
||||
Check xdsh output - get output from command and pipe to xdshbak
|
||||
|
||||
=cut
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
sub xdshoutput
|
||||
{
|
||||
my $resp = shift;
|
||||
my $i = 0;
|
||||
@dshresult = ();
|
||||
foreach (@{$resp->{info}})
|
||||
my $rsp = shift;
|
||||
|
||||
my $rc = 0;
|
||||
|
||||
# Handle info structure, like xdsh returns
|
||||
if ($rsp->{warning})
|
||||
{
|
||||
my $line = $_;
|
||||
$line .= "\n";
|
||||
push(@dshresult, $line);
|
||||
my $msg = {};
|
||||
$msg->{data}->[0] = $rsp->{warning}->[0];
|
||||
xCAT::MsgUtils->message("E", $msg, $::CALLBACK, 1);
|
||||
return 1;
|
||||
}
|
||||
if ($rsp->{info})
|
||||
{
|
||||
foreach (@{$rsp->{info}})
|
||||
{
|
||||
my $line = $_;
|
||||
$line .= "\n";
|
||||
push(@cmdresult, $line);
|
||||
}
|
||||
}
|
||||
|
||||
# open file to write results of xdsh
|
||||
return $rc;
|
||||
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
=head3 rinvoutput
|
||||
|
||||
Check rinv output - get output from command
|
||||
|
||||
=cut
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
sub rinvoutput
|
||||
{
|
||||
my $rsp = shift;
|
||||
|
||||
# Handle node structure, like rinv returns
|
||||
my $errflg = 0;
|
||||
|
||||
#if (scalar @{$rsp->{node}})
|
||||
if ($rsp->{node})
|
||||
{
|
||||
|
||||
my $nodes = ($rsp->{node});
|
||||
my $node;
|
||||
foreach $node (@$nodes)
|
||||
{
|
||||
my $desc = $node->{name}->[0];
|
||||
if ($node->{errorcode})
|
||||
{
|
||||
if (ref($node->{errorcode}) eq 'ARRAY')
|
||||
{
|
||||
foreach my $ecode (@{$node->{errorcode}})
|
||||
{
|
||||
$xCAT::Client::EXITCODE |= $ecode;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$xCAT::Client::EXITCODE |= $node->{errorcode};
|
||||
} # assume it is a non-reference scalar
|
||||
}
|
||||
if ($node->{error})
|
||||
{
|
||||
$desc .= ": Error: " . $node->{error}->[0];
|
||||
$errflg = 1;
|
||||
}
|
||||
if ($node->{data})
|
||||
{
|
||||
if (ref(\($node->{data}->[0])) eq 'SCALAR')
|
||||
{
|
||||
$desc = $desc . ": " . $node->{data}->[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($node->{data}->[0]->{desc})
|
||||
{
|
||||
$desc = $desc . ": " . $node->{data}->[0]->{desc}->[0];
|
||||
}
|
||||
if ($node->{data}->[0]->{contents})
|
||||
{
|
||||
$desc = "$desc: " . $node->{data}->[0]->{contents}->[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($desc)
|
||||
{
|
||||
|
||||
my $line = $desc;
|
||||
$line .= "\n";
|
||||
|
||||
push(@cmdresult, $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
=head3 storeresults
|
||||
|
||||
Runs command output through xdshbak and stores in /tmp/<tempfile>
|
||||
store results in $tempfile or $templatepath ( for seed node) based on
|
||||
$processflag = seednode
|
||||
=cut
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
sub storeresults
|
||||
{
|
||||
|
||||
# open file to write results of xdsh or rinv command
|
||||
my $newtempfile = $tempfile;
|
||||
$newtempfile .= "temp";
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "Could not open $newtempfile\n";
|
||||
open(FILE, ">$newtempfile");
|
||||
if ($? > 0)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "Could not open $newtempfile\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
return 1;
|
||||
}
|
||||
foreach my $line (@dshresult)
|
||||
foreach my $line (@cmdresult)
|
||||
{
|
||||
print FILE $line;
|
||||
}
|
||||
close FILE;
|
||||
my $outputfile;
|
||||
if ($processflg eq "seednode")
|
||||
{ # xdsh to seednode
|
||||
{ # cmd to seednode
|
||||
$outputfile = $templatepath;
|
||||
}
|
||||
else
|
||||
{ # xdsh to nodelist
|
||||
{ # cmd to nodelist
|
||||
$outputfile = $tempfile;
|
||||
}
|
||||
|
||||
# open file to put results of xdshbak
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "Could not open $outputfile\n";
|
||||
open(FILE, ">$outputfile");
|
||||
if ($? > 0)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "Could not open $outputfile\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
return 1;
|
||||
}
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "Could not call xdshbak \n";
|
||||
my $cmd = " /opt/xcat/bin/xdshbak <$newtempfile |";
|
||||
|
||||
open(DSHBAK, "$cmd");
|
||||
if ($? > 0)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "Could not call xdshbak \n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
return 1;
|
||||
}
|
||||
@ -1143,10 +1290,8 @@ sub xdshoutput
|
||||
|
||||
close(DSHBAK);
|
||||
close FILE;
|
||||
|
||||
system("/bin/rm $newtempfile");
|
||||
return 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -4,7 +4,7 @@ B<sinv> - Checks the software configuration of the nodes in the cluster.
|
||||
|
||||
=head1 B<SYNOPSIS>
|
||||
|
||||
B<sinv> I<noderange> [B<-o> I<output>] [B<-p> <template path>] [B<-t> I<template count>] [B<-s> I<seed node>] [B<-i>] [B<-e>] [B<-r>] [B<-V>] [[B<-f> I<xdsh command file>] | [B<-c> I<xdsh command>]]
|
||||
B<sinv> [B<-o> I<output>] [B<-p> I<template path>] [B<-t> I<template count>] [B<-s> I<seed node>] [B<-i>] [B<-e>] [B<-r>] [B<-V>] [[B<-f> I<command file>] | [B<-c> I<command>]]
|
||||
|
||||
B<sinv> [B<-h> | B<-v>]
|
||||
|
||||
@ -14,20 +14,17 @@ B<sinv> [B<-h> | B<-v>]
|
||||
The B<sinv> command is designed to check the configuration of the nodes in a cluster.
|
||||
The command takes as input command line flags, and one or more templates which will be compared against the output of the xdsh command, designated to be run by the -c or -f flag, on the nodes in the noderange.
|
||||
|
||||
The nodes will then be grouped according to the template they match and a report returned to the administrator in the output file designated by the -o flag.
|
||||
The nodes will then be grouped according to the template they match and a report returned to the administrator in the output file designated by the -o flag.
|
||||
|
||||
B<sinv> supports checking the output from the B<rinv> or B<xdsh> command.
|
||||
|
||||
The B<sinv> command is an xCAT Distributed Shell Utility.
|
||||
|
||||
|
||||
B<TARGET> B<SPECIFICATION>:
|
||||
|
||||
The target are node(s) where xdsh will be executed. Node
|
||||
targets are specified by the I<noderange>.
|
||||
|
||||
|
||||
B<COMMAND> B<SPECIFICATION>:
|
||||
|
||||
The xdsh command to execute on the remote targets is specified by the
|
||||
The xdsh or rinv command to execute on the remote targets is specified by the
|
||||
B<-c> flag, or by the B<-f> flag
|
||||
which is followed by the fully qualified path to a file containing the command.
|
||||
|
||||
@ -48,8 +45,7 @@ those that read from standard input.
|
||||
|
||||
B<REMOTE> B<SHELL> B<COMMAND>:
|
||||
|
||||
The B<sinv> command uses B<xdsh> which uses a configurable remote shell command to execute
|
||||
remote commands on the remote targets. Support is explicitly provided
|
||||
For xdsh, support is explicitly provided
|
||||
for AIX Remote Shell and OpenSSH, but any secure remote command that
|
||||
conforms to the IETF (Internet Engineering Task Force) Secure Remote
|
||||
Command Protocol can be used. See man B<xdsh> for more details.
|
||||
@ -106,10 +102,10 @@ be compared against the first template.
|
||||
|
||||
This is the node that will be used to build the first template
|
||||
that is stored in template path. You can use this parameter instead of running
|
||||
the xdsh command yourself to build the template.
|
||||
the command yourself to build the template.
|
||||
|
||||
B<Note:> If no template path file exists, and no seed node is supplied,
|
||||
the seed node automatically is the first node from the
|
||||
the seed node automatically is the first node in the
|
||||
noderange.
|
||||
|
||||
=item B<-i>|B<--ignorefirst>
|
||||
@ -136,7 +132,7 @@ to the template.
|
||||
|
||||
=item B<-c>|B<--command>
|
||||
|
||||
The command that will be run by xdsh. The command should be enclosed in
|
||||
The xdsh or rinv command that will be run. The command should be enclosed in
|
||||
double quotes to insure correct shell interpretation.
|
||||
|
||||
B<Note:> do not add the | xdshbak to the command,
|
||||
@ -144,7 +140,7 @@ it is automatically added by sinv.
|
||||
|
||||
=item B<-f>|B<--file>
|
||||
|
||||
The file containing the command that will be run by xdsh
|
||||
The file containing the xdsh or rinv command that will be run.
|
||||
This should be the fully qualified name of the file.
|
||||
|
||||
B<Note:> do not add the | xdshbak to the command in the file,
|
||||
@ -184,7 +180,7 @@ Verbose mode.
|
||||
|
||||
=item *
|
||||
|
||||
To setup sinv.template for input to the B<sinv> command , enter:
|
||||
To setup sinv.template (name optional) for input to the B<sinv> command , enter:
|
||||
|
||||
B<xdsh> I<node1,node2 "rpm -qa | grep xCAT | xdshbak "> /tmp/sinv.template>
|
||||
|
||||
@ -193,12 +189,21 @@ Note: when setting up the template the output of xdsh must be piped
|
||||
|
||||
=item *
|
||||
|
||||
To setup rinv.template for input to the B<sinv> command , enter:
|
||||
|
||||
B<rinv> I<node1-node2 serial> /tmp/rinv.template>
|
||||
|
||||
Note: when setting up the template the output of rinv must be piped
|
||||
to xdshbak, sinv processing depends on it.
|
||||
|
||||
=item *
|
||||
|
||||
To execute B<sinv> using the sinv.template generated above
|
||||
on the nodegroup, B<testnodes> ,possibly generating up to two
|
||||
new templates, and removing all generated templates in the end, and writing
|
||||
output report to /tmp/sinv.output, enter:
|
||||
|
||||
B<sinv> I<testnodes -c "rpm -qa | grep xCAT" -p /tmp/sinv.template -t 2 -r -o /tmp/sinv.output>
|
||||
B<sinv> I< -c "xdsh testnodes rpm -qa | grep xCAT" -p /tmp/sinv.template -t 2 -r -o /tmp/sinv.output>
|
||||
|
||||
Note: do not add the pipe to xdshbak on the -c flag, it is automatically
|
||||
added by the sinv routine.
|
||||
@ -210,16 +215,24 @@ to generate the first template, using the xdsh command (-c),
|
||||
possibly generating up to two additional
|
||||
templates and not removing any templates at the end, enter:
|
||||
|
||||
B<xsinv> I<node1-node4 -c "lslpp -l | grep bos.adt" -s node8 -p /tmp/sinv.template -t 2 -o /tmp/sinv.output>
|
||||
B<xsinv> I<-c "xdsh node1-node4 lslpp -l | grep bos.adt" -s node8 -p /tmp/sinv.template -t 2 -o /tmp/sinv.output>
|
||||
|
||||
=item *
|
||||
|
||||
To execute B<sinv> on noderange, node1-node4, using the seed node, node8,
|
||||
to generate the first template, using the rinv command (-c),
|
||||
possibly generating up to two additional
|
||||
templates and removing any generated templates at the end, enter:
|
||||
|
||||
B<xsinv> I<-c "rinv node1-node4 serial" -s node8 -p /tmp/sinv.template -t 2 -r -o /tmp/rinv.output>
|
||||
=item *
|
||||
|
||||
To execute B<sinv> on noderange, node1-node4, automatically using node1 as
|
||||
the seed node, to generate the sinv.template from the xdsh command (-c),
|
||||
using the exact match option, generating no additional templates, enter:
|
||||
|
||||
|
||||
B<xsinv> I<node1-node4 -c "lslpp -l | grep bos.adt" -e -p /tmp/sinv.template -o /tmp/sinv.output>
|
||||
B<xsinv> I<-c "xdsh node1-node4 lslpp -l | grep bos.adt" -e -p /tmp/sinv.template -o /tmp/sinv.output>
|
||||
|
||||
Note: the /tmp/sinv.template file must be empty, otherwise it will be used
|
||||
as an admin generated template.
|
||||
@ -232,7 +245,7 @@ using the exact match option, generating no additional templates, and
|
||||
reporting only nodes that do not match enter:
|
||||
|
||||
|
||||
B<xsinv> I<node1-node4 -c "lslpp -l | grep bos.adt" -e -i -p /tmp/sinv.template -o /tmp/sinv.output>
|
||||
B<xsinv> I< -c "xdsh node1-node4 lslpp -l | grep bos.adt" -e -i -p /tmp/sinv.template -o /tmp/sinv.output>
|
||||
|
||||
Note: the /tmp/sinv.template file must be empty, otherwise it will be used
|
||||
as an admin generated template.
|
||||
|
@ -5,7 +5,8 @@
|
||||
xCAT plugin package to handle sinv
|
||||
|
||||
Supported command:
|
||||
sinv
|
||||
sinv - software/firmware inventory program
|
||||
run xdsh or rinv. See man sinv.
|
||||
|
||||
=cut
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user