2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-05-21 03:02:05 +00:00

perltidy all perl files, part 2

This commit is contained in:
Mark Gurevich 2016-07-21 13:27:40 -04:00
parent 5515eb2592
commit fb911143fe
146 changed files with 25471 additions and 24077 deletions

View File

@ -16,12 +16,12 @@ use xCAT::Table;
use Pod::Man;
use Pod::Html;
my $poddir = 'pods';
my $mandir = 'share/man';
my $htmldir = 'share/doc';
my $poddir = 'pods';
my $mandir = 'share/man';
my $htmldir = 'share/doc';
my $cachedir = "$ENV{'HOME'}/tmp";
if (system("mkdir -p $cachedir")) { die "Error: could not create $cachedir.\n"; }
my $isaix = ($^O =~ /^aix/i);
my $isaix = ($^O =~ /^aix/i);
my $skiponaix = 'route|group';
my $poddir5 = 'pods/man5';
@ -36,51 +36,53 @@ writesummarypage("$poddir5/xcatdb.5.pod", xCAT::Table->getDescriptions(), \%{xCA
# Build the pod man page for each object definition
my $defspecref = \%{xCAT::Schema::defspec};
foreach my $defkey (keys %$defspecref) {
my $def = $defspecref->{$defkey};
my $attrs = $def->{'attrs'};
my $def = $defspecref->{$defkey};
my $attrs = $def->{'attrs'};
writedefmanpage("$poddir7/$defkey.7.pod", $defkey, $attrs);
}
# Build the pod man page for each table.
my $tabspecref = \%xCAT::Schema::tabspec;
foreach my $tablekey (keys %$tabspecref) {
my $table = $tabspecref->{$tablekey};
my $summary = $table->{table_desc};
my $colorder = $table->{cols};
my $table = $tabspecref->{$tablekey};
my $summary = $table->{table_desc};
my $colorder = $table->{cols};
my $descriptions = $table->{descriptions};
writepodmanpage("$poddir5/$tablekey.5.pod", $tablekey, $summary, $colorder, $descriptions);
}
my @pods = getPodList($poddir);
#foreach (@pods) { print "$_\n"; } exit;
# Build the man page for each pod.
#mkdir($mandir) or die "Error: could not create $mandir.\n";
print "Converting PODs to man pages...\n";
foreach my $podfile (@pods) {
if ($isaix && grep(/\/($skiponaix)\.\d\.pod$/, $podfile)) { print "Skipping $podfile\n"; next; }
if ($isaix && grep(/\/($skiponaix)\.\d\.pod$/, $podfile)) { print "Skipping $podfile\n"; next; }
my $manfile = $podfile;
$manfile =~ s/^$poddir/$mandir/; # change the beginning of the path
$manfile =~ s/\.pod$//; # change the ending
$manfile =~ s/^$poddir/$mandir/; # change the beginning of the path
$manfile =~ s/\.pod$//; # change the ending
my $mdir = $manfile;
$mdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $mdir")) { die "Error: could not create $mdir.\n"; }
my ($section) = $podfile =~ /\.(\d+)\.pod$/;
$mdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $mdir")) { die "Error: could not create $mdir.\n"; }
my ($section) = $podfile =~ /\.(\d+)\.pod$/;
convertpod2man($podfile, $manfile, $section);
}
# Build the html page for each pod.
#mkdir($htmldir) or die "Error: could not create $htmldir.\n";
print "Converting PODs to HTML pages...\n";
# have to clear the cache, because old entries can cause a problem
unlink("$cachedir/pod2htmd.tmp", "$cachedir/pod2htmi.tmp");
foreach my $podfile (@pods) {
my $htmlfile = $podfile;
$htmlfile =~ s/^$poddir/$htmldir/; # change the beginning of the path
$htmlfile =~ s/\.pod$/\.html/; # change the ending
$htmlfile =~ s/^$poddir/$htmldir/; # change the beginning of the path
$htmlfile =~ s/\.pod$/\.html/; # change the ending
my $hdir = $htmlfile;
$hdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $hdir")) { die "Error: could not create $hdir.\n"; }
$hdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $hdir")) { die "Error: could not create $hdir.\n"; }
convertpod2html($podfile, $htmlfile, $poddir, $htmldir);
}
@ -89,62 +91,62 @@ exit;
# Recursively get the list of pod man page files.
sub getPodList {
my $poddir = shift;
my @files;
my $poddir = shift;
my @files;
# 1st get toplevel dir listing
opendir(DIR, $poddir) or die "Error: could not read $poddir.\n";
my @topdir = grep !/^\./, readdir(DIR); # /
close(DIR);
# 1st get toplevel dir listing
opendir(DIR, $poddir) or die "Error: could not read $poddir.\n";
my @topdir = grep !/^\./, readdir(DIR); # /
close(DIR);
# Now go thru each subdir (these are man1, man3, etc.)
foreach my $mandir (@topdir) {
opendir(DIR, "$poddir/$mandir") or die "Error: could not read $poddir/$mandir.\n";
my @dir = grep !/^\./, readdir(DIR); # /
close(DIR);
foreach my $file (@dir) {
push @files, "$poddir/$mandir/$file";
}
}
return sort @files;
# Now go thru each subdir (these are man1, man3, etc.)
foreach my $mandir (@topdir) {
opendir(DIR, "$poddir/$mandir") or die "Error: could not read $poddir/$mandir.\n";
my @dir = grep !/^\./, readdir(DIR); # /
close(DIR);
foreach my $file (@dir) {
push @files, "$poddir/$mandir/$file";
}
}
return sort @files;
}
# Create the html page for one pod.
sub convertpod2html {
my ($podfile, $htmlfile, $poddir, $htmldir) = @_;
my ($podfile, $htmlfile, $poddir, $htmldir) = @_;
#TODO: use --css=<stylesheet> and --title=<pagetitle> to make the pages look better
pod2html($podfile,
"--outfile=$htmlfile",
"--podpath=man5:man7",
"--podroot=$poddir",
"--htmldir=$htmldir",
"--recurse",
"--cachedir=$cachedir",
);
#TODO: use --css=<stylesheet> and --title=<pagetitle> to make the pages look better
pod2html($podfile,
"--outfile=$htmlfile",
"--podpath=man5:man7",
"--podroot=$poddir",
"--htmldir=$htmldir",
"--recurse",
"--cachedir=$cachedir",
);
}
# Create the man page for one pod.
sub convertpod2man {
my ($podfile, $manfile, $section) = @_;
my ($podfile, $manfile, $section) = @_;
my $parser = Pod::Man->new(section => $section);
my $parser = Pod::Man->new(section => $section);
$parser->parse_from_file($podfile, $manfile);
}
# Create the xcatdb man page that gives a summary description of each table.
sub writesummarypage {
my $file = shift; # relative path file name of the man page
my $descriptions = shift; # a hash containing the description of each table
my $defdescriptions = shift; # a hash containing the description of each object definition
my $file = shift; # relative path file name of the man page
my $descriptions = shift; # a hash containing the description of each table
my $defdescriptions = shift; # a hash containing the description of each object definition
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
print FILE <<'EOS1';
print FILE <<'EOS1';
=head1 NAME
An overview of the xCAT database.
@ -316,11 +318,11 @@ The object types are:
=over 2
EOS1
foreach my $def (sort keys %$defdescriptions) {
print FILE "\n=item L<$def(7)|$def.7>\n";
}
foreach my $def (sort keys %$defdescriptions) {
print FILE "\n=item L<$def(7)|$def.7>\n";
}
print FILE <<"EOS2";
print FILE <<"EOS2";
=back
@ -336,11 +338,11 @@ The tables are:
=over 2
EOS2
foreach my $table (sort keys %$descriptions) {
print FILE "\n=item L<$table(5)|$table.5>\n\n".$descriptions->{$table}."\n";
}
foreach my $table (sort keys %$descriptions) {
print FILE "\n=item L<$table(5)|$table.5>\n\n" . $descriptions->{$table} . "\n";
}
print FILE <<"EOS3";
print FILE <<"EOS3";
=back
@ -349,47 +351,49 @@ foreach my $table (sort keys %$descriptions) {
B<nodels(1)>, B<chtab(8)>, B<tabdump(8)>, B<tabedit(8)>, B<lsdef(1)>, B<mkdef(1)>, B<chdef(1)>, B<rmdef(1)>
EOS3
close FILE;
close FILE;
}
# Create the man page for one object definition.
sub writedefmanpage {
my $file = shift; # relative path file name of the man page
my $defname = shift; # name of object
my $attrs = shift; # reference to the array of attributes
my $file = shift; # relative path file name of the man page
my $defname = shift; # name of object
my $attrs = shift; # reference to the array of attributes
# Go thru the attributes, collecting the descriptions
# Note: this logic is loosely taken from DBobjectdefs.pm
my %attrlist; # holds the attr name as the key, and the description & tables as value
foreach my $this_attr (@$attrs) {
# Go thru the attributes, collecting the descriptions
# Note: this logic is loosely taken from DBobjectdefs.pm
my %attrlist; # holds the attr name as the key, and the description & tables as value
foreach my $this_attr (@$attrs) {
my $attr = $this_attr->{attr_name};
my $desc = $this_attr->{description};
my ($table, $at) = split(/\./, $this_attr->{tabentry});
if (!defined($desc)) {
# description key not there, so go to the corresponding
# entry in tabspec to get the description
# description key not there, so go to the corresponding
# entry in tabspec to get the description
my $schema = xCAT::Table->getTableSchema($table);
$desc = $schema->{descriptions}->{$at};
}
# Attr names can appear more than once, if they are in multiple tables.
# We will keep track of that based on the table attribute, because that can be duplicated too
if (!defined($attrlist{$attr})) {
$attrlist{$attr}->{'tables'} = []; # initialize the array, so we can check it below
}
my $tableattr = "$table.$at";
if (!grep(/^$tableattr$/, @{$attrlist{$attr}->{'tables'}})) {
# there can be multiple entries that refer to the same table attribute
# if this is a new table attribute, then save the attr name and description
push @{$attrlist{$attr}->{'tables'}}, $tableattr;
push @{$attrlist{$attr}->{'descriptions'}}, $desc;
}
}
# Attr names can appear more than once, if they are in multiple tables.
# We will keep track of that based on the table attribute, because that can be duplicated too
if (!defined($attrlist{$attr})) {
$attrlist{$attr}->{'tables'} = []; # initialize the array, so we can check it below
}
my $tableattr = "$table.$at";
if (!grep(/^$tableattr$/, @{ $attrlist{$attr}->{'tables'} })) {
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
# there can be multiple entries that refer to the same table attribute
# if this is a new table attribute, then save the attr name and description
push @{ $attrlist{$attr}->{'tables'} }, $tableattr;
push @{ $attrlist{$attr}->{'descriptions'} }, $desc;
}
}
print FILE <<"EOS1";
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
print FILE <<"EOS1";
=head1 NAME
B<$defname> - a logical object definition in the xCAT database.
@ -398,9 +402,9 @@ B<$defname> - a logical object definition in the xCAT database.
EOS1
print FILE "B<$defname Attributes:> I<" . join('>, I<',sort(keys(%attrlist))) . ">\n";
print FILE "B<$defname Attributes:> I<" . join('>, I<', sort(keys(%attrlist))) . ">\n";
print FILE <<"EOS2";
print FILE <<"EOS2";
=head1 DESCRIPTION
@ -415,15 +419,17 @@ parentheses, what tables each attribute is stored in.
EOS2
foreach my $a (sort keys %attrlist) {
my $d = join("\n\nor\n\n", @{$attrlist{$a}->{'descriptions'}});
#$d =~ s/\n/\n\n/sg; # if there are newlines, double them so pod sees a blank line, otherwise pod will ignore them
my $t = '(' . join(', ',@{$attrlist{$a}->{'tables'}}) . ')';
#print FILE "\nB<$a> - $d\n";
print FILE "\n=item B<$a> $t\n\n$d\n";
}
foreach my $a (sort keys %attrlist) {
my $d = join("\n\nor\n\n", @{ $attrlist{$a}->{'descriptions'} });
print FILE <<"EOS3";
#$d =~ s/\n/\n\n/sg; # if there are newlines, double them so pod sees a blank line, otherwise pod will ignore them
my $t = '(' . join(', ', @{ $attrlist{$a}->{'tables'} }) . ')';
#print FILE "\nB<$a> - $d\n";
print FILE "\n=item B<$a> $t\n\n$d\n";
}
print FILE <<"EOS3";
=back
@ -432,21 +438,21 @@ foreach my $a (sort keys %attrlist) {
B<mkdef(1)>, B<chdef(1)>, B<lsdef(1)>, B<rmdef(1)>
EOS3
close FILE;
close FILE;
}
# Create the man page for one table.
sub writepodmanpage {
my $file = shift; # relative path file name of the man page
my $tablename = shift; # name of table
my $summary = shift; # description of table
my $colorder = shift; # the order in which the table attributes should be presented in
my $descriptions = shift; # a hash containing the description of each attribute
my $file = shift; # relative path file name of the man page
my $tablename = shift; # name of table
my $summary = shift; # description of table
my $colorder = shift; # the order in which the table attributes should be presented in
my $descriptions = shift; # a hash containing the description of each attribute
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
print FILE <<"EOS1";
print FILE <<"EOS1";
=head1 NAME
B<$tablename> - a table in the xCAT database.
@ -455,9 +461,9 @@ B<$tablename> - a table in the xCAT database.
EOS1
print FILE "B<$tablename Attributes:> I<" . join('>, I<',@$colorder) . ">\n";
print FILE "B<$tablename Attributes:> I<" . join('>, I<', @$colorder) . ">\n";
print FILE <<"EOS2";
print FILE <<"EOS2";
=head1 DESCRIPTION
@ -469,14 +475,15 @@ $summary
EOS2
foreach my $a (@$colorder) {
my $d = $descriptions->{$a};
#$d =~ s/\n/\n\n/sg; # if there are newlines, double them so pod sees a blank line, otherwise pod will ignore them
#print FILE "\nB<$a> - $d\n";
print FILE "\n=item B<$a>\n\n$d\n";
}
foreach my $a (@$colorder) {
my $d = $descriptions->{$a};
print FILE <<"EOS3";
#$d =~ s/\n/\n\n/sg; # if there are newlines, double them so pod sees a blank line, otherwise pod will ignore them
#print FILE "\nB<$a> - $d\n";
print FILE "\n=item B<$a>\n\n$d\n";
}
print FILE <<"EOS3";
=back
@ -485,5 +492,5 @@ foreach my $a (@$colorder) {
B<nodels(1)>, B<chtab(8)>, B<tabdump(8)>, B<tabedit(8)>
EOS3
close FILE;
close FILE;
}

View File

@ -8,16 +8,18 @@
# done relative to that.
use strict;
#use lib '.';
use Pod::Man;
use Pod::Html;
my $poddir = 'pods';
my $mandir = 'share/man';
my $htmldir = 'share/doc';
my $poddir = 'pods';
my $mandir = 'share/man';
my $htmldir = 'share/doc';
my $cachedir = '/tmp';
my @pods = getPodList($poddir);
#foreach (@pods) { print "$_\n"; } exit;
# Build the cmd overview page.
@ -28,12 +30,12 @@ my @pods = getPodList($poddir);
print "Converting PODs to man pages...\n";
foreach my $podfile (@pods) {
my $manfile = $podfile;
$manfile =~ s/^$poddir/$mandir/; # change the beginning of the path
$manfile =~ s/\.pod$//; # change the ending
$manfile =~ s/^$poddir/$mandir/; # change the beginning of the path
$manfile =~ s/\.pod$//; # change the ending
my $mdir = $manfile;
$mdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $mdir")) { die "Error: could not create $mdir.\n"; }
my ($section) = $podfile =~ /\.(\d+)\.pod$/;
$mdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $mdir")) { die "Error: could not create $mdir.\n"; }
my ($section) = $podfile =~ /\.(\d+)\.pod$/;
convertpod2man($podfile, $manfile, $section);
}
@ -42,15 +44,17 @@ my @dummyPods = createDummyPods($poddir, \@pods);
# Build the html page for each pod.
#mkdir($htmldir) or die "Error: could not create $htmldir.\n";
print "Converting PODs to HTML pages...\n";
# have to clear the cache, because old entries can cause a problem
unlink("$cachedir/pod2htmd.tmp", "$cachedir/pod2htmi.tmp");
foreach my $podfile (@pods) {
my $htmlfile = $podfile;
$htmlfile =~ s/^$poddir/$htmldir/; # change the beginning of the path
$htmlfile =~ s/\.pod$/\.html/; # change the ending
$htmlfile =~ s/^$poddir/$htmldir/; # change the beginning of the path
$htmlfile =~ s/\.pod$/\.html/; # change the ending
my $hdir = $htmlfile;
$hdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $hdir")) { die "Error: could not create $hdir.\n"; }
$hdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $hdir")) { die "Error: could not create $hdir.\n"; }
#print "$podfile, $htmlfile, $poddir, $htmldir\n";
convertpod2html($podfile, $htmlfile, $poddir, $htmldir);
}
@ -67,73 +71,78 @@ exit;
# if that pod does not exist, create an empty one that will satisfy pod2html
# keep track of all dummy pods created, so they can be removed later
sub createDummyPods {
my ($poddir, $pods) = @_;
my $cmd = "grep -r -E 'L<.+\\([57]\\)\\|.+\\.[57]>' " . $poddir;
#print "Running cmd: ", $cmd, "\n";
my @lines = `$cmd`;
if ($?) { print "Did not find any section 5 man page, creating dummy pods...\n"; print join('', @lines); }
#my @lines;
#system($cmd);
my @dummyPods;
foreach my $l (@lines) {
#print "$l\n";
my @matches = $l =~ /L<([^\(]+)\(([57])\)\|\1\.[57]>/g; # get all the matches in the line
# The above line should create the array with every other entry being the man page name
# and every other entry is the section # (5 or 7)
my $cmd;
while ($cmd=shift @matches) {
#foreach my $m (@matches) {
my $section = shift @matches;
my $filename = "$poddir/man$section/$cmd.$section.pod";
#print "$filename\n";
if (!(grep /^$filename$/, @$pods) && !(grep /^$filename$/, @dummyPods)) { push @dummyPods, $filename; }
}
}
# Create these empty files
print "Creating empty linked-to files: ", join(', ', @dummyPods), "\n";
mkdir "$poddir/man7";
foreach my $d (@dummyPods) {
if (!open(TMP, ">>$d")) { warn "Could not create dummy pod file $d ($!)\n"; }
else { close TMP; }
}
return @dummyPods;
my ($poddir, $pods) = @_;
my $cmd = "grep -r -E 'L<.+\\([57]\\)\\|.+\\.[57]>' " . $poddir;
#print "Running cmd: ", $cmd, "\n";
my @lines = `$cmd`;
if ($?) { print "Did not find any section 5 man page, creating dummy pods...\n"; print join('', @lines); }
#my @lines;
#system($cmd);
my @dummyPods;
foreach my $l (@lines) {
#print "$l\n";
my @matches = $l =~ /L<([^\(]+)\(([57])\)\|\1\.[57]>/g; # get all the matches in the line
# The above line should create the array with every other entry being the man page name
# and every other entry is the section # (5 or 7)
my $cmd;
while ($cmd = shift @matches) {
#foreach my $m (@matches) {
my $section = shift @matches;
my $filename = "$poddir/man$section/$cmd.$section.pod";
#print "$filename\n";
if (!(grep /^$filename$/, @$pods) && !(grep /^$filename$/, @dummyPods)) { push @dummyPods, $filename; }
}
}
# Create these empty files
print "Creating empty linked-to files: ", join(', ', @dummyPods), "\n";
mkdir "$poddir/man7";
foreach my $d (@dummyPods) {
if (!open(TMP, ">>$d")) { warn "Could not create dummy pod file $d ($!)\n"; }
else { close TMP; }
}
return @dummyPods;
}
# Recursively get the list of pod man page files.
sub getPodList {
my $poddir = shift;
my @files;
my $poddir = shift;
my @files;
# 1st get toplevel dir listing
opendir(DIR, $poddir) or die "Error: could not read $poddir.\n";
my @topdir = grep !/^\./, readdir(DIR); # /
close(DIR);
# 1st get toplevel dir listing
opendir(DIR, $poddir) or die "Error: could not read $poddir.\n";
my @topdir = grep !/^\./, readdir(DIR); # /
close(DIR);
# Now go thru each subdir (these are man1, man3, etc.)
foreach my $mandir (@topdir) {
opendir(DIR, "$poddir/$mandir") or die "Error: could not read $poddir/$mandir.\n";
my @dir = grep !/^\./, readdir(DIR); # /
close(DIR);
foreach my $file (@dir) {
push @files, "$poddir/$mandir/$file";
}
}
return sort @files;
# Now go thru each subdir (these are man1, man3, etc.)
foreach my $mandir (@topdir) {
opendir(DIR, "$poddir/$mandir") or die "Error: could not read $poddir/$mandir.\n";
my @dir = grep !/^\./, readdir(DIR); # /
close(DIR);
foreach my $file (@dir) {
push @files, "$poddir/$mandir/$file";
}
}
return sort @files;
}
# Create the xcat man page that gives a summary description of each xcat cmd.
# Not used
sub writesummarypage {
my $file = shift; # relative path file name of the man page
# the rest of @_ contains the pod files that describe each cmd
my $file = shift; # relative path file name of the man page
# the rest of @_ contains the pod files that describe each cmd
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
print FILE <<'EOS1';
print FILE <<'EOS1';
=head1 NAME
B<xcat> - extreme Cluster Administration Tool.
@ -159,56 +168,58 @@ i.e. all the commands in section 1, then the commands in section 3, etc.
=over 12
EOS1
# extract the summary for each cmd from its man page
foreach my $manpage (@_) {
my ($sectionnum) = $manpage =~ /\.(\d+)\.pod$/;
# Suck in the whole file, then we will parse it.
open(MANPAGE, "$manpage") or die "Error: could not open $manpage for reading.\n";
my @contents = <MANPAGE>;
my $wholemanpage = join('', @contents);
close(MANPAGE);
# This regex matches: optional space, =head1, space, title, space, cmd, space, description, newline
my ($cmd, $description) = $wholemanpage =~ /^\s*=head1\s+\S+\s+(\S+)\s+(.+?)\n/si;
if (!defined($cmd)) { print "Warning: $manpage is not in a recognized structure. It will be ignored.\n"; next; }
if (!defined($description)) { print "Warning: $manpage does not have a description for $cmd. It will be ignored.\n"; next; }
$cmd =~ s/^.<(.+)>$/$1/; # if the cmd name has pod formatting around it, strip it off
$description =~ s/^-\s*//; # if the description has a leading hypen, strip it off
print FILE "\n=item L<$cmd($sectionnum)|$cmd.$sectionnum>\n\n".$description."\n";
}
# extract the summary for each cmd from its man page
foreach my $manpage (@_) {
my ($sectionnum) = $manpage =~ /\.(\d+)\.pod$/;
# Artificially add the xcattest cmd, because the xCAT-test rpm will add this
print FILE "\n=item L<xcattest(1)|xcattest.1>\n\nRun automated xCAT test cases.\n";
# Suck in the whole file, then we will parse it.
open(MANPAGE, "$manpage") or die "Error: could not open $manpage for reading.\n";
my @contents = <MANPAGE>;
my $wholemanpage = join('', @contents);
close(MANPAGE);
print FILE <<"EOS3";
# This regex matches: optional space, =head1, space, title, space, cmd, space, description, newline
my ($cmd, $description) = $wholemanpage =~ /^\s*=head1\s+\S+\s+(\S+)\s+(.+?)\n/si;
if (!defined($cmd)) { print "Warning: $manpage is not in a recognized structure. It will be ignored.\n"; next; }
if (!defined($description)) { print "Warning: $manpage does not have a description for $cmd. It will be ignored.\n"; next; }
$cmd =~ s/^.<(.+)>$/$1/; # if the cmd name has pod formatting around it, strip it off
$description =~ s/^-\s*//; # if the description has a leading hypen, strip it off
print FILE "\n=item L<$cmd($sectionnum)|$cmd.$sectionnum>\n\n" . $description . "\n";
}
# Artificially add the xcattest cmd, because the xCAT-test rpm will add this
print FILE "\n=item L<xcattest(1)|xcattest.1>\n\nRun automated xCAT test cases.\n";
print FILE <<"EOS3";
=back
EOS3
close FILE;
close FILE;
}
# Create the html page for one pod.
sub convertpod2html {
my ($podfile, $htmlfile, $poddir, $htmldir) = @_;
my ($podfile, $htmlfile, $poddir, $htmldir) = @_;
#TODO: use --css=<stylesheet> and --title=<pagetitle> to make the pages look better
pod2html($podfile,
"--outfile=$htmlfile",
"--podpath=man1",
"--podroot=$poddir",
"--htmldir=$htmldir",
"--recurse",
"--cachedir=$cachedir",
);
#TODO: use --css=<stylesheet> and --title=<pagetitle> to make the pages look better
pod2html($podfile,
"--outfile=$htmlfile",
"--podpath=man1",
"--podroot=$poddir",
"--htmldir=$htmldir",
"--recurse",
"--cachedir=$cachedir",
);
}
# Create the man page for one pod.
sub convertpod2man {
my ($podfile, $manfile, $section) = @_;
my ($podfile, $manfile, $section) = @_;
my $parser = Pod::Man->new(section => $section);
my $parser = Pod::Man->new(section => $section);
$parser->parse_from_file($podfile, $manfile);
}

View File

@ -18,14 +18,15 @@ use strict;
use lib 'lib/perl';
use xCAT_schema::Clouds;
#use xCAT::Table;
use Pod::Man;
use Pod::Html;
my $VERBOSE = 1; # set this to 1 for debugging
my $poddir = 'pods';
my $mandir = 'share/man';
my $htmldir = 'share/doc';
my $VERBOSE = 1; # set this to 1 for debugging
my $poddir = 'pods';
my $mandir = 'share/man';
my $htmldir = 'share/doc';
my $cachedir = '/tmp';
my $poddir5 = 'pods/man5';
@ -40,21 +41,21 @@ writesummarypage("$poddir5/xcat-openstack-db.5.pod", getTableDescriptions(), get
# Build the pod man page for each object definition
my $defspecref = getDefRef();
foreach my $defkey (keys %$defspecref) {
my $def = $defspecref->{$defkey};
my $attrs = $def->{'attrs'};
my $podfile = "$poddir7/$defkey.7.pod";
verbose("Writing pod file for $defkey");
my $def = $defspecref->{$defkey};
my $attrs = $def->{'attrs'};
my $podfile = "$poddir7/$defkey.7.pod";
verbose("Writing pod file for $defkey");
writedefmanpage($podfile, $defkey, $attrs);
}
# Build the pod man page for each table.
my $tabspecref = getTableRef();
foreach my $tablekey (keys %$tabspecref) {
my $table = $tabspecref->{$tablekey};
my $summary = $table->{table_desc};
my $colorder = $table->{cols};
my $table = $tabspecref->{$tablekey};
my $summary = $table->{table_desc};
my $colorder = $table->{cols};
my $descriptions = $table->{descriptions};
verbose("Writing pod file for $tablekey");
verbose("Writing pod file for $tablekey");
writepodmanpage("$poddir5/$tablekey.5.pod", $tablekey, $summary, $colorder, $descriptions);
}
@ -65,13 +66,13 @@ verbose('Pod list:' . "@pods");
print "Converting PODs to man pages...\n";
foreach my $podfile (@pods) {
my $manfile = $podfile;
$manfile =~ s/^$poddir/$mandir/; # change the beginning of the path
$manfile =~ s/\.pod$//; # change the ending
$manfile =~ s/^$poddir/$mandir/; # change the beginning of the path
$manfile =~ s/\.pod$//; # change the ending
my $mdir = $manfile;
$mdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $mdir")) { die "Error: could not create $mdir.\n"; }
my ($section) = $podfile =~ /\.(\d+)\.pod$/;
verbose("Converting $podfile to $manfile");
$mdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $mdir")) { die "Error: could not create $mdir.\n"; }
my ($section) = $podfile =~ /\.(\d+)\.pod$/;
verbose("Converting $podfile to $manfile");
convertpod2man($podfile, $manfile, $section);
}
@ -79,16 +80,17 @@ my @dummyPods = createDummyPods($poddir);
# Build the html page for each pod.
print "Converting PODs to HTML pages...\n";
# have to clear the cache, because old entries can cause a problem
unlink("$cachedir/pod2htmd.tmp", "$cachedir/pod2htmi.tmp");
foreach my $podfile (@pods) {
my $htmlfile = $podfile;
$htmlfile =~ s/^$poddir/$htmldir/; # change the beginning of the path
$htmlfile =~ s/\.pod$/\.html/; # change the ending
$htmlfile =~ s/^$poddir/$htmldir/; # change the beginning of the path
$htmlfile =~ s/\.pod$/\.html/; # change the ending
my $hdir = $htmlfile;
$hdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $hdir")) { die "Error: could not create $hdir.\n"; }
verbose("Converting $podfile to $htmlfile");
$hdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $hdir")) { die "Error: could not create $hdir.\n"; }
verbose("Converting $podfile to $htmlfile");
convertpod2html($podfile, $htmlfile, $poddir, $htmldir);
}
@ -107,76 +109,78 @@ sub getTableRef { return \%xCAT_schema::Clouds::tabspec; }
sub getTableList { return keys %xCAT_schema::Clouds::tabspec; }
# Returns a reference to the db schema hash for the specified table.
sub getTableSchema { return $xCAT_schema::Clouds::tabspec{$_[0]}; }
sub getTableSchema { return $xCAT_schema::Clouds::tabspec{ $_[0] }; }
# Return a reference to a hash where each key is the table name and each value is the table description.
sub getTableDescriptions {
# List each table name and the value for table_desc.
my $ret = {};
#my @a = keys %{$xCAT_schema::Clouds::tabspec{nodelist}}; print 'a=', @a, "\n";
foreach my $t (getTableList()) { $ret->{$t} = getTableSchema($t)->{table_desc}; }
return $ret;
# List each table name and the value for table_desc.
my $ret = {};
#my @a = keys %{$xCAT_schema::Clouds::tabspec{nodelist}}; print 'a=', @a, "\n";
foreach my $t (getTableList()) { $ret->{$t} = getTableSchema($t)->{table_desc}; }
return $ret;
}
# Recursively get the list of pod man page files.
sub getPodList {
my $poddir = shift;
my @files;
my $poddir = shift;
my @files;
# 1st get toplevel dir listing
opendir(DIR, $poddir) or die "Error: could not read $poddir.\n";
my @topdir = grep !/^\./, readdir(DIR); # /
close(DIR);
# 1st get toplevel dir listing
opendir(DIR, $poddir) or die "Error: could not read $poddir.\n";
my @topdir = grep !/^\./, readdir(DIR); # /
close(DIR);
# Now go thru each subdir (these are man1, man3, etc.)
foreach my $mandir (@topdir) {
opendir(DIR, "$poddir/$mandir") or die "Error: could not read $poddir/$mandir.\n";
my @dir = grep !/^\./, readdir(DIR); # /
close(DIR);
foreach my $file (@dir) {
push @files, "$poddir/$mandir/$file";
}
}
return sort @files;
# Now go thru each subdir (these are man1, man3, etc.)
foreach my $mandir (@topdir) {
opendir(DIR, "$poddir/$mandir") or die "Error: could not read $poddir/$mandir.\n";
my @dir = grep !/^\./, readdir(DIR); # /
close(DIR);
foreach my $file (@dir) {
push @files, "$poddir/$mandir/$file";
}
}
return sort @files;
}
# Create the html page for one pod.
sub convertpod2html {
my ($podfile, $htmlfile, $poddir, $htmldir) = @_;
my ($podfile, $htmlfile, $poddir, $htmldir) = @_;
#TODO: use --css=<stylesheet> and --title=<pagetitle> to make the pages look better
pod2html($podfile,
"--outfile=$htmlfile",
"--podpath=man5:man7",
"--podroot=$poddir",
"--htmldir=$htmldir",
"--recurse",
"--cachedir=$cachedir",
);
#TODO: use --css=<stylesheet> and --title=<pagetitle> to make the pages look better
pod2html($podfile,
"--outfile=$htmlfile",
"--podpath=man5:man7",
"--podroot=$poddir",
"--htmldir=$htmldir",
"--recurse",
"--cachedir=$cachedir",
);
}
# Create the man page for one pod.
sub convertpod2man {
my ($podfile, $manfile, $section) = @_;
my ($podfile, $manfile, $section) = @_;
my $parser = Pod::Man->new(section => $section);
my $parser = Pod::Man->new(section => $section);
$parser->parse_from_file($podfile, $manfile);
}
# Create the xcat-openstack-db man page that gives a summary description of each table.
sub writesummarypage {
my $file = shift; # relative path file name of the man page
my $descriptions = shift; # a hash containing the description of each table
my $defdescriptions = shift; # a hash containing the description of each object definition
my $file = shift; # relative path file name of the man page
my $descriptions = shift; # a hash containing the description of each table
my $defdescriptions = shift; # a hash containing the description of each object definition
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
print FILE <<'EOS1';
print FILE <<'EOS1';
=head1 NAME
An overview of the xCAT OpenStack database objects and tables.
@ -205,12 +209,12 @@ The object types are:
=over 2
EOS1
foreach my $def (sort keys %$defdescriptions) {
if ($def eq 'node') { print FILE "\n=item L<$def(7)|node-openstack.7>\n"; } # can not overwrite the node man page in xcat-core
else { print FILE "\n=item L<$def(7)|$def.7>\n"; }
}
foreach my $def (sort keys %$defdescriptions) {
if ($def eq 'node') { print FILE "\n=item L<$def(7)|node-openstack.7>\n"; } # can not overwrite the node man page in xcat-core
else { print FILE "\n=item L<$def(7)|$def.7>\n"; }
}
print FILE <<"EOS2";
print FILE <<"EOS2";
=back
@ -226,11 +230,11 @@ The tables are:
=over 2
EOS2
foreach my $table (sort keys %$descriptions) {
print FILE "\n=item L<$table(5)|$table.5>\n\n".$descriptions->{$table}."\n";
}
foreach my $table (sort keys %$descriptions) {
print FILE "\n=item L<$table(5)|$table.5>\n\n" . $descriptions->{$table} . "\n";
}
print FILE <<"EOS3";
print FILE <<"EOS3";
=back
@ -239,50 +243,52 @@ foreach my $table (sort keys %$descriptions) {
B<nodels(1)>, B<chtab(8)>, B<tabdump(8)>, B<tabedit(8)>, B<lsdef(1)>, B<mkdef(1)>, B<chdef(1)>, B<rmdef(1)>
EOS3
close FILE;
close FILE;
}
# Create the man page for one object definition.
sub writedefmanpage {
my $file = shift; # relative path file name of the man page
my $defname = shift; # name of object
my $attrs = shift; # reference to the array of attributes
my $file = shift; # relative path file name of the man page
my $defname = shift; # name of object
my $attrs = shift; # reference to the array of attributes
# Make exception for the node object, because we can not overwrite the node man page from xcat-core
if ($defname eq 'node') { $file = "$poddir7/node-openstack.7.pod"; }
# Make exception for the node object, because we can not overwrite the node man page from xcat-core
if ($defname eq 'node') { $file = "$poddir7/node-openstack.7.pod"; }
# Go thru the attributes, collecting the descriptions
# Note: this logic is loosely taken from DBobjectdefs.pm
my %attrlist; # holds the attr name as the key, and the description & tables as value
foreach my $this_attr (@$attrs) {
# Go thru the attributes, collecting the descriptions
# Note: this logic is loosely taken from DBobjectdefs.pm
my %attrlist; # holds the attr name as the key, and the description & tables as value
foreach my $this_attr (@$attrs) {
my $attr = $this_attr->{attr_name};
my $desc = $this_attr->{description};
my ($table, $at) = split(/\./, $this_attr->{tabentry});
if (!defined($desc)) {
# description key not there, so go to the corresponding
# entry in tabspec to get the description
# description key not there, so go to the corresponding
# entry in tabspec to get the description
my $schema = getTableSchema($table);
$desc = $schema->{descriptions}->{$at};
}
# Attr names can appear more than once, if they are in multiple tables.
# We will keep track of that based on the table attribute, because that can be duplicated too
if (!defined($attrlist{$attr})) {
$attrlist{$attr}->{'tables'} = []; # initialize the array, so we can check it below
}
my $tableattr = "$table.$at";
if (!grep(/^$tableattr$/, @{$attrlist{$attr}->{'tables'}})) {
# there can be multiple entries that refer to the same table attribute
# if this is a new table attribute, then save the attr name and description
push @{$attrlist{$attr}->{'tables'}}, $tableattr;
push @{$attrlist{$attr}->{'descriptions'}}, $desc;
}
}
# Attr names can appear more than once, if they are in multiple tables.
# We will keep track of that based on the table attribute, because that can be duplicated too
if (!defined($attrlist{$attr})) {
$attrlist{$attr}->{'tables'} = []; # initialize the array, so we can check it below
}
my $tableattr = "$table.$at";
if (!grep(/^$tableattr$/, @{ $attrlist{$attr}->{'tables'} })) {
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
# there can be multiple entries that refer to the same table attribute
# if this is a new table attribute, then save the attr name and description
push @{ $attrlist{$attr}->{'tables'} }, $tableattr;
push @{ $attrlist{$attr}->{'descriptions'} }, $desc;
}
}
print FILE <<"EOS1";
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
print FILE <<"EOS1";
=head1 NAME
B<$defname> - a logical object definition in the xCAT database.
@ -291,9 +297,9 @@ B<$defname> - a logical object definition in the xCAT database.
EOS1
print FILE "B<$defname Attributes:> I<" . join('>, I<',sort(keys(%attrlist))) . ">\n";
print FILE "B<$defname Attributes:> I<" . join('>, I<', sort(keys(%attrlist))) . ">\n";
print FILE <<"EOS2";
print FILE <<"EOS2";
=head1 DESCRIPTION
@ -308,45 +314,46 @@ parentheses, what tables each attribute is stored in.
EOS2
foreach my $a (sort keys %attrlist) {
my $d = join("\nor\n", @{$attrlist{$a}->{'descriptions'}});
$d =~ s/\n/\n\n/sg; # if there are newlines, double them so pod sees a blank line, otherwise pod will ignore them
my $t = '(' . join(', ',@{$attrlist{$a}->{'tables'}}) . ')';
#print FILE "\nB<$a> - $d\n";
print FILE "\n=item B<$a> $t\n\n$d\n";
}
foreach my $a (sort keys %attrlist) {
my $d = join("\nor\n", @{ $attrlist{$a}->{'descriptions'} });
$d =~ s/\n/\n\n/sg; # if there are newlines, double them so pod sees a blank line, otherwise pod will ignore them
my $t = '(' . join(', ', @{ $attrlist{$a}->{'tables'} }) . ')';
print FILE <<"EOS3";
#print FILE "\nB<$a> - $d\n";
print FILE "\n=item B<$a> $t\n\n$d\n";
}
print FILE <<"EOS3";
=back
EOS3
if ($defname eq 'node') {
print FILE "B<The node attributes listed above are just the ones that the xCAT-OpenStack RPM adds to the node object definition. For the rest of the node attributes from xcat-core, see the L<node(7)|node.7> man page.>\n\n";
}
if ($defname eq 'node') {
print FILE "B<The node attributes listed above are just the ones that the xCAT-OpenStack RPM adds to the node object definition. For the rest of the node attributes from xcat-core, see the L<node(7)|node.7> man page.>\n\n";
}
print FILE <<"EOS4";
print FILE <<"EOS4";
=head1 SEE ALSO
B<mkdef(1)>, B<chdef(1)>, B<lsdef(1)>, B<rmdef(1)>
EOS4
close FILE;
close FILE;
}
# Create the man page for one table.
sub writepodmanpage {
my $file = shift; # relative path file name of the man page
my $tablename = shift; # name of table
my $summary = shift; # description of table
my $colorder = shift; # the order in which the table attributes should be presented in
my $descriptions = shift; # a hash containing the description of each attribute
my $file = shift; # relative path file name of the man page
my $tablename = shift; # name of table
my $summary = shift; # description of table
my $colorder = shift; # the order in which the table attributes should be presented in
my $descriptions = shift; # a hash containing the description of each attribute
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
print FILE <<"EOS1";
print FILE <<"EOS1";
=head1 NAME
B<$tablename> - a table in the xCAT database.
@ -355,9 +362,9 @@ B<$tablename> - a table in the xCAT database.
EOS1
print FILE "B<$tablename Attributes:> I<" . join('>, I<',@$colorder) . ">\n";
print FILE "B<$tablename Attributes:> I<" . join('>, I<', @$colorder) . ">\n";
print FILE <<"EOS2";
print FILE <<"EOS2";
=head1 DESCRIPTION
@ -369,14 +376,15 @@ $summary
EOS2
foreach my $a (@$colorder) {
my $d = $descriptions->{$a};
#$d =~ s/\n/\n\n/sg; # if there are newlines, double them so pod sees a blank line, otherwise pod will ignore them
#print FILE "\nB<$a> - $d\n";
print FILE "\n=item B<$a>\n\n$d\n";
}
foreach my $a (@$colorder) {
my $d = $descriptions->{$a};
print FILE <<"EOS3";
#$d =~ s/\n/\n\n/sg; # if there are newlines, double them so pod sees a blank line, otherwise pod will ignore them
#print FILE "\nB<$a> - $d\n";
print FILE "\n=item B<$a>\n\n$d\n";
}
print FILE <<"EOS3";
=back
@ -385,7 +393,7 @@ foreach my $a (@$colorder) {
B<nodels(1)>, B<chtab(8)>, B<tabdump(8)>, B<tabedit(8)>
EOS3
close FILE;
close FILE;
}
@ -393,19 +401,20 @@ EOS3
# we need to create an empty one that will satisfy pod2html.
# Returns all dummy pods created, so they can be removed later
sub createDummyPods {
my $poddir = shift @_;
my $poddir = shift @_;
# Also add xcattest.1.pod and buildkit.1.pod, because the xcat.1.pod summary page refers to it
push @dummyPods, "$poddir/man7/node.7.pod";
push @dummyPods, "$poddir/man5/xcatdb.5.pod";
# Create these empty files
print "Creating empty linked-to files: ", join(', ', @dummyPods), "\n";
#mkdir "$poddir/man7";
foreach my $d (@dummyPods) {
if (!open(TMP, ">>$d")) { warn "Could not create dummy pod file $d ($!)\n"; }
else { close TMP; }
}
return @dummyPods;
# Also add xcattest.1.pod and buildkit.1.pod, because the xcat.1.pod summary page refers to it
push @dummyPods, "$poddir/man7/node.7.pod";
push @dummyPods, "$poddir/man5/xcatdb.5.pod";
# Create these empty files
print "Creating empty linked-to files: ", join(', ', @dummyPods), "\n";
#mkdir "$poddir/man7";
foreach my $d (@dummyPods) {
if (!open(TMP, ">>$d")) { warn "Could not create dummy pod file $d ($!)\n"; }
else { close TMP; }
}
return @dummyPods;
}

View File

@ -4,7 +4,7 @@
# Used as a standard client cmd that can be used for xcat cmds that do not have
# noderange as an argument. See xcatclient for additional documentation.
# To put the cloud command only in xCAT-OpenStack, just copy the ../bin/xcatclientnnr
# To put the cloud command only in xCAT-OpenStack, just copy the ../bin/xcatclientnnr
# as makeclouddata command here. we couldn't sym link the command makecloudata
# to this script ../bin/xcatclientnnr in xCAT-OpenStack.spec.
@ -17,40 +17,41 @@ use strict;
my $bname = basename($0);
my $cmdref;
if ($bname =~ /xcatclientnnr/) { $cmdref->{command}->[0]=shift @ARGV; } # xcatclientnnr was invoked directly and the 1st arg is cmd name that is used to locate the plugin
else { $cmdref->{command}->[0] = $bname; } # the cmd was sym linked to xcatclientnnr
if ($bname =~ /xcatclientnnr/) { $cmdref->{command}->[0] = shift @ARGV; } # xcatclientnnr was invoked directly and the 1st arg is cmd name that is used to locate the plugin
else { $cmdref->{command}->[0] = $bname; } # the cmd was sym linked to xcatclientnnr
$cmdref->{cwd}->[0] = cwd();
my $data;
# allows our plugins to get the stdin of the cmd that invoked the plugin
if ( (($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}) )
if ((($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}))
{
my $rout;
my $rin="";
vec($rin,fileno(STDIN),1)=1;
my $nfound=select($rout=$rin,"","",1);
my $rin = "";
vec($rin, fileno(STDIN), 1) = 1;
my $nfound = select($rout = $rin, "", "", 1);
if ($nfound)
{
while ( <STDIN> ) { $data.=$_; }
$cmdref->{stdin}->[0]=$data;
while (<STDIN>) { $data .= $_; }
$cmdref->{stdin}->[0] = $data;
}
}
else
{
if (-p STDIN) {
while ( <STDIN> ) { $data.=$_; }
$cmdref->{stdin}->[0]=$data;
while (<STDIN>) { $data .= $_; }
$cmdref->{stdin}->[0] = $data;
}
}
push (@{$cmdref->{arg}}, @ARGV);
push(@{ $cmdref->{arg} }, @ARGV);
foreach (keys %ENV) {
if (/^XCAT_/) {
$cmdref->{environment}->{$_} = $ENV{$_};
}
}
xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response);
xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response);
exit $xCAT::Client::EXITCODE;

View File

@ -7,37 +7,39 @@
use strict;
use Getopt::Long;
use Data::Dumper;
#$Data::Dumper::Maxdepth=2;
# Globals - these are set once and then only read.
my $HELP;
my $VERBOSE;
my %CONFIG; # attributes read from config file
my %CONFIG; # attributes read from config file
my $usage = sub {
my $exitcode = shift @_;
print "Usage: getslnodes [-?|-h|--help] [-v|--verbose] [<hostname-match>]\n\n";
if (!$exitcode) {
print "getslnodes queries your SoftLayer account and gets attributes for each\n";
print "server. The attributes can be piped to 'mkdef -z' to define the nodes\n";
print "in the xCAT DB so that xCAT can manage them. getslnodes\n";
print "requires a .slconfig file in your home directory that contains your\n";
print "SoftLayer userid, API key, and location of API perl module, in attr=val format.\n";
}
exit $exitcode;
my $exitcode = shift @_;
print "Usage: getslnodes [-?|-h|--help] [-v|--verbose] [<hostname-match>]\n\n";
if (!$exitcode) {
print "getslnodes queries your SoftLayer account and gets attributes for each\n";
print "server. The attributes can be piped to 'mkdef -z' to define the nodes\n";
print "in the xCAT DB so that xCAT can manage them. getslnodes\n";
print "requires a .slconfig file in your home directory that contains your\n";
print "SoftLayer userid, API key, and location of API perl module, in attr=val format.\n";
}
exit $exitcode;
};
# Process the cmd line args
Getopt::Long::Configure("bundling");
#Getopt::Long::Configure("pass_through");
Getopt::Long::Configure("no_pass_through");
if (!GetOptions('h|?|help' => \$HELP, 'v|verbose' => \$VERBOSE)) { $usage->(1); }
if (!GetOptions('h|?|help' => \$HELP, 'v|verbose' => \$VERBOSE)) { $usage->(1); }
if ($HELP) { $usage->(0); }
if (scalar(@ARGV)>1) { $usage->(1); }
my $hnmatch = $ARGV[0]; # if they specified a hostname match, only show svrs that start with that
if ($HELP) { $usage->(0); }
if (scalar(@ARGV) > 1) { $usage->(1); }
my $hnmatch = $ARGV[0]; # if they specified a hostname match, only show svrs that start with that
readconf("$ENV{HOME}/.slconfig"); # get the userid and api key from the config file
readconf("$ENV{HOME}/.slconfig"); # get the userid and api key from the config file
my $slinstalled = eval { push @INC, $CONFIG{apidir}; require SoftLayer::API::SOAP; };
if (!$slinstalled) { die "$@\nError: either the SoftLayer::API::SOAP perl module is not installed, or some dependencies are missing. Download it using 'git clone https://github.com/softlayer/softlayer-api-perl-client', put the directory in ~/.slconfig , and ensure its dependencies are installed."; }
@ -50,43 +52,47 @@ $client->setObjectMask($mask);
#print $client->fault;
#print $client->faultstring;
#print "\n";
my $hw = $client->getHardware();
my $hw = $client->getHardware();
my $servers = $hw->result;
foreach my $server (@$servers) {
if ($server->{fullyQualifiedDomainName} =~ m/$hnmatch/) {
print "\n".$server->{hostname}.":\n";
print "\tobjtype=node\n";
print "\tgroups=slnode,ipmi,all\n";
print "\tmgt=ipmi\n";
print "\tbmc=".$server->{remoteManagementComponent}->{ipmiIpAddress}."\n";
print "\tbmcusername=".$server->{remoteManagementAccounts}->[0]->{username}."\n";
print "\tbmcpassword=".$server->{remoteManagementAccounts}->[0]->{password}."\n";
if ($server->{fullyQualifiedDomainName} =~ m/$hnmatch/) {
print "\n" . $server->{hostname} . ":\n";
print "\tobjtype=node\n";
print "\tgroups=slnode,ipmi,all\n";
print "\tmgt=ipmi\n";
print "\tbmc=" . $server->{remoteManagementComponent}->{ipmiIpAddress} . "\n";
print "\tbmcusername=" . $server->{remoteManagementAccounts}->[0]->{username} . "\n";
print "\tbmcpassword=" . $server->{remoteManagementAccounts}->[0]->{password} . "\n";
# find the 1st active private nic that is not the bmc
foreach my $nic (@{$server->{backendNetworkComponents}}) {
#print "nic:\n"; foreach my $key (keys(%$nic)) { print " $key = ", $nic->{$key}, "\n"; }
if ($nic->{status} eq 'ACTIVE' && $nic->{name} eq 'eth' && $nic->{macAddress} && $nic->{primaryIpAddress}) {
# found it
print "\tmac=".$nic->{macAddress}."\n";
print "\tip=".$nic->{primaryIpAddress}."\n";
}
}
#print "\tip=".$server->{privateIpAddress}."\n"; # getting this from the backendNetworkComponents instead
print "\tserial=".$server->{manufacturerSerialNumber}."\n";
print "\tnetboot=xnba\n";
print "\tarch=x86_64\n";
print "\tusercomment=hostname:".$server->{fullyQualifiedDomainName}.", user:".$server->{operatingSystem}->{passwords}->[0]->{username}.", pw:".$server->{operatingSystem}->{passwords}->[0]->{password}."\n";
# find the 1st active private nic that is not the bmc
foreach my $nic (@{ $server->{backendNetworkComponents} }) {
verbose('SoftLayer API bare metal server entry: ' . Dumper($server));
#print Dumper($server->{remoteManagementAccounts});
#print "#Softlayer_account_info_for ".$server->{fullyQualifiedDomainName} . " Username: ";
#print $server->{operatingSystem}->{passwords}->[0]->{username} . " Password: ";
#print $server->{operatingSystem}->{passwords}->[0]->{password}. "\n";
#print "nodeadd ".$server->{hostname}." groups=saptest ipmi.password=".$server->{remoteManagementAccounts}->[0]->{password}." ipmi.bmc=".$server->{remoteManagementComponent}->{ipmiIpAddress};
#print " mac.mac=".$server->{backendNetworkComponents}->[0]->{macAddress};
#print " hosts.ip=".$server->{privateIpAddress} ."\n";
}
#print "nic:\n"; foreach my $key (keys(%$nic)) { print " $key = ", $nic->{$key}, "\n"; }
if ($nic->{status} eq 'ACTIVE' && $nic->{name} eq 'eth' && $nic->{macAddress} && $nic->{primaryIpAddress}) {
# found it
print "\tmac=" . $nic->{macAddress} . "\n";
print "\tip=" . $nic->{primaryIpAddress} . "\n";
}
}
#print "\tip=".$server->{privateIpAddress}."\n"; # getting this from the backendNetworkComponents instead
print "\tserial=" . $server->{manufacturerSerialNumber} . "\n";
print "\tnetboot=xnba\n";
print "\tarch=x86_64\n";
print "\tusercomment=hostname:" . $server->{fullyQualifiedDomainName} . ", user:" . $server->{operatingSystem}->{passwords}->[0]->{username} . ", pw:" . $server->{operatingSystem}->{passwords}->[0]->{password} . "\n";
verbose('SoftLayer API bare metal server entry: ' . Dumper($server));
#print Dumper($server->{remoteManagementAccounts});
#print "#Softlayer_account_info_for ".$server->{fullyQualifiedDomainName} . " Username: ";
#print $server->{operatingSystem}->{passwords}->[0]->{username} . " Password: ";
#print $server->{operatingSystem}->{passwords}->[0]->{password}. "\n";
#print "nodeadd ".$server->{hostname}." groups=saptest ipmi.password=".$server->{remoteManagementAccounts}->[0]->{password}." ipmi.bmc=".$server->{remoteManagementComponent}->{ipmiIpAddress};
#print " mac.mac=".$server->{backendNetworkComponents}->[0]->{macAddress};
#print " hosts.ip=".$server->{privateIpAddress} ."\n";
}
}
exit(0);
@ -98,23 +104,23 @@ sub verbose { if ($VERBOSE) { print shift, "\n"; } }
# Read the config file. Format is attr=val on each line. Should contain at leas the userid and apikey.
# This function fills in the global %CONFIG hash.
sub readconf {
my $conffile = shift @_;
open(FILE, $conffile) || die "Error: can not open config file $conffile: $!\n";
while (<FILE>) {
my $line = $_;
chomp($line);
if ($line =~ /^#/ || $line =~/^\s*$/) { next; } # skip comment lines
my ($key, $value) = split(/\s*=\s*/, $line, 2);
if (!defined($value)) { die "Error: line '$line' does not have format attribute=value\n"; }
$CONFIG{$key} = $value;
}
close FILE;
verbose('%CONFIG hash: ' . Dumper(\%CONFIG));
my $conffile = shift @_;
open(FILE, $conffile) || die "Error: can not open config file $conffile: $!\n";
while (<FILE>) {
my $line = $_;
chomp($line);
if ($line =~ /^#/ || $line =~ /^\s*$/) { next; } # skip comment lines
my ($key, $value) = split(/\s*=\s*/, $line, 2);
if (!defined($value)) { die "Error: line '$line' does not have format attribute=value\n"; }
$CONFIG{$key} = $value;
}
close FILE;
verbose('%CONFIG hash: ' . Dumper(\%CONFIG));
# the config file needs to contain at least the userid and api key
if (!defined($CONFIG{userid}) || !defined($CONFIG{apikey}) || !defined($CONFIG{apidir})) {
die "Error: the config file must contain values for userid, apikey, and apidir.\n";
}
# the config file needs to contain at least the userid and api key
if (!defined($CONFIG{userid}) || !defined($CONFIG{apikey}) || !defined($CONFIG{apidir})) {
die "Error: the config file must contain values for userid, apikey, and apidir.\n";
}
}
#$mask = "mask[operatingSystem.passwords]";

View File

@ -5,6 +5,7 @@
use strict;
use Getopt::Long;
use Data::Dumper;
#$Data::Dumper::Maxdepth=2;
# Globals - these are set once and then only read.
@ -13,37 +14,41 @@ my $VERBOSE;
my $file = '~/.ssh/known_hosts';
my $usage = sub {
my $exitcode = shift @_;
print "Usage: khrem <node>\n";
my $exitcode = shift @_;
print "Usage: khrem <node>\n";
print " Removes the entries in the .ssh/known_hosts file associated with this node.\n";
exit $exitcode;
exit $exitcode;
};
# Process the cmd line args
Getopt::Long::Configure("bundling");
#Getopt::Long::Configure("pass_through");
Getopt::Long::Configure("no_pass_through");
if (!GetOptions('h|?|help' => \$HELP, 'v|verbose' => \$VERBOSE)) { $usage->(1); }
if (!GetOptions('h|?|help' => \$HELP, 'v|verbose' => \$VERBOSE)) { $usage->(1); }
if ($HELP) { $usage->(0); }
if (scalar(@ARGV)!=1) { $usage->(1); }
my $node = $ARGV[0]; # if they specified a hostname match, only show svrs that start with that
if (scalar(@ARGV) != 1) { $usage->(1); }
my $node = $ARGV[0]; # if they specified a hostname match, only show svrs that start with that
my @output = runcmd("host $node");
my $hostname;
my $line = shift @output;
#print "line=$line\n";
if ($line =~ m/is an alias for /) {
($hostname) = $line =~ m/is an alias for ([^\.]+)/;
#print "hostname=$hostname\n";
$line = shift @output;
}
}
#print "line=$line\n";
my ($ip) = $line =~ m/has address (.+)$/;
if (defined($hostname)) {
print "Removing entries from $file for: $node, $hostname, $ip\n";
runcmd("sed -i '/^$node/d;/^$hostname/d;/^$ip/d' $file");
}
}
else {
print "Removing entries from $file for: $node, $ip\n";
runcmd("sed -i '/^$node/d;/^$ip/d' $file");
@ -66,23 +71,23 @@ sub runcmd
my ($cmd) = @_;
my $rc;
$cmd .= ' 2>&1' ;
$cmd .= ' 2>&1';
verbose($cmd);
my @output;
if (wantarray) {
@output = `$cmd`;
$rc = $?;
}
else {
system($cmd);
$rc = $?;
}
my @output;
if (wantarray) {
@output = `$cmd`;
$rc = $?;
}
else {
system($cmd);
$rc = $?;
}
if ($rc) {
$rc = $rc >> 8;
if ($rc > 0) { die "Error: rc $rc return from cmd: $cmd\n"; }
else { die "Error: system error returned from cmd: $cmd\n"; }
if ($rc > 0) { die "Error: rc $rc return from cmd: $cmd\n"; }
else { die "Error: system error returned from cmd: $cmd\n"; }
}
elsif (wantarray) { return @output; }
}

View File

@ -18,226 +18,235 @@ my $PROVMETHOD;
my $XCATNETBOOTTITLE = 'xCAT network boot kernel and initrd';
my $usage = sub {
my $exitcode = shift @_;
print "Usage: modifygrub [-?|-h|--help] [-v|--verbose] [--dryrun] [-w <waittime>] [-p <provmethod] <kernel-path> <initrd-path> <kernel-parms> <mn-ip>\n\n";
if (!$exitcode) {
print "Modify the grub config file on the node to boot the specified kernel and initrd.\n";
}
exit $exitcode;
my $exitcode = shift @_;
print "Usage: modifygrub [-?|-h|--help] [-v|--verbose] [--dryrun] [-w <waittime>] [-p <provmethod] <kernel-path> <initrd-path> <kernel-parms> <mn-ip>\n\n";
if (!$exitcode) {
print "Modify the grub config file on the node to boot the specified kernel and initrd.\n";
}
exit $exitcode;
};
my $file = '/etc/os-release';
if (-f $file) {
#
# SLES and RHEL also have /etc/os-release file, so actually need to open the file
# and look for Ubuntu in the 'NAME=' lines before declaring Ubuntu
#
open my $info, $file or die "Could not open $file: $!";
while( my $line = <$info>) {
if (index($line, 'NAME=') != -1) {
if ($line =~ /Ubuntu/i) {
die "This script does not support Ubuntu at this time.\n";
}
}
}
close $info;
if (-f $file) {
#
# SLES and RHEL also have /etc/os-release file, so actually need to open the file
# and look for Ubuntu in the 'NAME=' lines before declaring Ubuntu
#
open my $info, $file or die "Could not open $file: $!";
while (my $line = <$info>) {
if (index($line, 'NAME=') != -1) {
if ($line =~ /Ubuntu/i) {
die "This script does not support Ubuntu at this time.\n";
}
}
}
close $info;
}
# Process the cmd line args
Getopt::Long::Configure("bundling");
#Getopt::Long::Configure("pass_through");
Getopt::Long::Configure("no_pass_through");
if (!GetOptions('h|?|help' => \$HELP, 'v|verbose' => \$VERBOSE, 'dryrun' => \$DRYRUN, 'w|waittime=s' => \$WAITTIME, 'p|provmethod=s' => \$PROVMETHOD)) { $usage->(1); }
if (!GetOptions('h|?|help' => \$HELP, 'v|verbose' => \$VERBOSE, 'dryrun' => \$DRYRUN, 'w|waittime=s' => \$WAITTIME, 'p|provmethod=s' => \$PROVMETHOD)) { $usage->(1); }
if ($HELP) { $usage->(0); }
if (scalar(@ARGV) != 4) { $usage->(1); }
if (!defined($WAITTIME)) { $WAITTIME = 60; } # seconds to wait after configuring the nic (to let the switch handle the state change)
if (!defined($WAITTIME)) { $WAITTIME = 60; } # seconds to wait after configuring the nic (to let the switch handle the state change)
my %args;
$args{kernelpath} = $ARGV[0];
$args{initrdpath} = $ARGV[1];
$args{kernelpath} = $ARGV[0];
$args{initrdpath} = $ARGV[1];
$args{kernelparms} = $ARGV[2];
$args{mnip} = $ARGV[3];
$args{mnip} = $ARGV[3];
addKernelParms(\%args); # replace and add some parms to args{kernelparms}
updateGrub(\%args); # update the grub config with an entry filled with the info in args
addKernelParms(\%args); # replace and add some parms to args{kernelparms}
updateGrub(\%args); # update the grub config with an entry filled with the info in args
exit(0);
# Add ip and net info to the kernel parms. Modifies the kernelparms value of the args hash passed in.
sub addKernelParms {
my $args = shift @_;
my $args = shift @_;
# replace '!myipfn!' with the mn ip
my $mnip = $args->{mnip};
$args->{kernelparms} =~ s/!myipfn!/$mnip/g;
# replace '!myipfn!' with the mn ip
my $mnip = $args->{mnip};
$args->{kernelparms} =~ s/!myipfn!/$mnip/g;
# replace <nodename> with the nodename
my $nodename = $ENV{NODE}; # this env var is set by xdsh
$args->{kernelparms} =~ s/<nodename>/$nodename/g;
# get node ip and add it to the kernel parms
my ($nic, $ip, $netmask, $network, $broadcast, $gateway, $mac) = getNodeIpInfo($args);
if (!$ip) { die "Error: could not find the NIC that would connect to the xCAT mgmt node's IP (".$args->{mnip}.").\n"; }
# replace <nodename> with the nodename
my $nodename = $ENV{NODE}; # this env var is set by xdsh
$args->{kernelparms} =~ s/<nodename>/$nodename/g;
#if (defined($PROVMETHOD) && $PROVMETHOD eq 'sysclone') {
if ($args->{kernelpath} =~ m/genesis\.kernel\.x86_64/) {
# genesis case, add additional parms for sysclone or nodeset shell
my $bootif = $mac;
$bootif =~ s/:/-/g;
$bootif = "BOOTIF=01-$bootif";
# DEVICE=eth0 IPADDR=10.0.0.99 NETMASK=255.255.255.0 NETWORK=10.0.0.0 BROADCAST=10.0.0.255 GATEWAY=10.0.0.1 GATEWAYDEV=eth0
#todo: should we also add ETHER_SLEEP=$WAITTIME textmode=1 dns=$mnip ?
$args->{kernelparms} .= " $bootif IPADDR=$ip NETMASK=$netmask NETWORK=$network BROADCAST=$broadcast GATEWAY=$gateway HOSTNAME=$nodename DEVICE=$nic GATEWAYDEV=$nic";
}
else { # scripted install (kickstart or autoyast)
if ($args->{kernelparms} =~ m/autoyast=/) { # sles
# if site.managedaddressmode=static is set, it will put several of these kernel parms on there for us. Do not duplicate in that case.
if ($args->{kernelparms} !~ m/ hostip=/) { $args->{kernelparms} .= " hostip=$ip"; }
if ($args->{kernelparms} !~ m/ netmask=/) { $args->{kernelparms} .= " netmask=$netmask"; }
if ($args->{kernelparms} !~ m/ gateway=/) { $args->{kernelparms} .= " gateway=$gateway"; }
if ($args->{kernelparms} !~ m/ hostname=/) { $args->{kernelparms} .= " hostname=$nodename"; }
if ($args->{kernelparms} !~ m/ dns=/) { $args->{kernelparms} .= " dns=$mnip"; }
# If they set installnic=mac (recommended), the netdevice will already be set to the mac.
# If they explicitly set installnic=<nic>, then ksdevice will be set to that and we will not disturb it here.
# Otherwise add netdevice set to the nic we calculated it should be.
if ($args->{kernelparms} !~ m/ netdevice=/) { $args->{kernelparms} .= " netdevice=$nic"; }
$args->{kernelparms} .= " netwait=$WAITTIME textmode=1";
# print Dumper($args->{kernelparms})
}
elsif ($args->{kernelparms} =~ m/ks=/) { # rhel/centos
# See https://www.centos.org/docs/5/html/Installation_Guide-en-US/s1-kickstart2-startinginstall.html
# and http://fedoraproject.org/wiki/Anaconda/NetworkIssues for description of kickstart kernel parms
# if site.managedaddressmode=static is set, it will put several of these kernel parms on there for us. Do not duplicate in that case.
if ($args->{kernelparms} !~ m/ ip=/) { $args->{kernelparms} .= " ip=$ip"; }
if ($args->{kernelparms} !~ m/ netmask=/) { $args->{kernelparms} .= " netmask=$netmask"; }
if ($args->{kernelparms} !~ m/ gateway=/) { $args->{kernelparms} .= " gateway=$gateway"; }
if ($args->{kernelparms} !~ m/ hostname=/) { $args->{kernelparms} .= " hostname=$nodename"; }
if ($args->{kernelparms} !~ m/ dns=/) { $args->{kernelparms} .= " dns=$mnip"; }
# If they set installnic=mac (recommended), the ksdevice will already be set to the mac.
# If they explicitly set installnic=<nic>, then ksdevice will be set to that and we will not disturb it here.
# Otherwise ksdevice will be set to bootif, and we change it to the nic we calculated it should be.
if ($args->{kernelparms} =~ m/ ksdevice=bootif/) { $args->{kernelparms} =~ s/ ksdevice=bootif/ ksdevice=$nic/; }
elsif ($args->{kernelparms} !~ m/ ksdevice=/) { $args->{kernelparms} .= " ksdevice=$nic"; }
$args->{kernelparms} .= " nicdelay=$WAITTIME linksleep=$WAITTIME textmode=1";
# print Dumper($args->{kernelparms})
}
else { die "Error: for scripted installs, only support SLES or RHEL/CentOS as the target OS.\n"; }
}
# get node ip and add it to the kernel parms
my ($nic, $ip, $netmask, $network, $broadcast, $gateway, $mac) = getNodeIpInfo($args);
if (!$ip) { die "Error: could not find the NIC that would connect to the xCAT mgmt node's IP (" . $args->{mnip} . ").\n"; }
#if (defined($PROVMETHOD) && $PROVMETHOD eq 'sysclone') {
if ($args->{kernelpath} =~ m/genesis\.kernel\.x86_64/) {
# genesis case, add additional parms for sysclone or nodeset shell
my $bootif = $mac;
$bootif =~ s/:/-/g;
$bootif = "BOOTIF=01-$bootif";
# DEVICE=eth0 IPADDR=10.0.0.99 NETMASK=255.255.255.0 NETWORK=10.0.0.0 BROADCAST=10.0.0.255 GATEWAY=10.0.0.1 GATEWAYDEV=eth0
#todo: should we also add ETHER_SLEEP=$WAITTIME textmode=1 dns=$mnip ?
$args->{kernelparms} .= " $bootif IPADDR=$ip NETMASK=$netmask NETWORK=$network BROADCAST=$broadcast GATEWAY=$gateway HOSTNAME=$nodename DEVICE=$nic GATEWAYDEV=$nic";
}
else { # scripted install (kickstart or autoyast)
if ($args->{kernelparms} =~ m/autoyast=/) { # sles
# if site.managedaddressmode=static is set, it will put several of these kernel parms on there for us. Do not duplicate in that case.
if ($args->{kernelparms} !~ m/ hostip=/) { $args->{kernelparms} .= " hostip=$ip"; }
if ($args->{kernelparms} !~ m/ netmask=/) { $args->{kernelparms} .= " netmask=$netmask"; }
if ($args->{kernelparms} !~ m/ gateway=/) { $args->{kernelparms} .= " gateway=$gateway"; }
if ($args->{kernelparms} !~ m/ hostname=/) { $args->{kernelparms} .= " hostname=$nodename"; }
if ($args->{kernelparms} !~ m/ dns=/) { $args->{kernelparms} .= " dns=$mnip"; }
# If they set installnic=mac (recommended), the netdevice will already be set to the mac.
# If they explicitly set installnic=<nic>, then ksdevice will be set to that and we will not disturb it here.
# Otherwise add netdevice set to the nic we calculated it should be.
if ($args->{kernelparms} !~ m/ netdevice=/) { $args->{kernelparms} .= " netdevice=$nic"; }
$args->{kernelparms} .= " netwait=$WAITTIME textmode=1";
# print Dumper($args->{kernelparms})
}
elsif ($args->{kernelparms} =~ m/ks=/) { # rhel/centos
# See https://www.centos.org/docs/5/html/Installation_Guide-en-US/s1-kickstart2-startinginstall.html
# and http://fedoraproject.org/wiki/Anaconda/NetworkIssues for description of kickstart kernel parms
# if site.managedaddressmode=static is set, it will put several of these kernel parms on there for us. Do not duplicate in that case.
if ($args->{kernelparms} !~ m/ ip=/) { $args->{kernelparms} .= " ip=$ip"; }
if ($args->{kernelparms} !~ m/ netmask=/) { $args->{kernelparms} .= " netmask=$netmask"; }
if ($args->{kernelparms} !~ m/ gateway=/) { $args->{kernelparms} .= " gateway=$gateway"; }
if ($args->{kernelparms} !~ m/ hostname=/) { $args->{kernelparms} .= " hostname=$nodename"; }
if ($args->{kernelparms} !~ m/ dns=/) { $args->{kernelparms} .= " dns=$mnip"; }
# If they set installnic=mac (recommended), the ksdevice will already be set to the mac.
# If they explicitly set installnic=<nic>, then ksdevice will be set to that and we will not disturb it here.
# Otherwise ksdevice will be set to bootif, and we change it to the nic we calculated it should be.
if ($args->{kernelparms} =~ m/ ksdevice=bootif/) { $args->{kernelparms} =~ s/ ksdevice=bootif/ ksdevice=$nic/; }
elsif ($args->{kernelparms} !~ m/ ksdevice=/) { $args->{kernelparms} .= " ksdevice=$nic"; }
$args->{kernelparms} .= " nicdelay=$WAITTIME linksleep=$WAITTIME textmode=1";
# print Dumper($args->{kernelparms})
}
else { die "Error: for scripted installs, only support SLES or RHEL/CentOS as the target OS.\n"; }
}
}
# get this nodes nic, ip, netmask, gateway, and mac. Returns them in a 5 element array.
sub getNodeIpInfo {
my $args = shift @_;
my ($ipprefix) = $args->{mnip}=~m/^(\d+)\./; #todo: this is a hack, just using the 1st octet of the mn ip addr
verbose("using IP prefix $ipprefix");
my $args = shift @_;
my ($ipprefix) = $args->{mnip} =~ m/^(\d+)\./; #todo: this is a hack, just using the 1st octet of the mn ip addr
verbose("using IP prefix $ipprefix");
# parse ip addr show output, looking for ipprefix, to determine nic, ip, mac
my @output = runcmd("/sbin/ip addr show");
my ($nic, $mac, $ipandmask);
foreach my $line (@output) {
my ($nictmp, $mactmp, $iptmp);
if (($nictmp) = $line=~m/^\d+:\s+(\S+): /) { $nic = $nictmp; } # new stanza, remember it
if (($mactmp) = $line=~m|^\s+link/ether\s+(\S+) |) { $mac = $mactmp; } # got mac, remember it
if (($iptmp) = $line=~m/^\s+inet\s+($ipprefix\S+) /) { $ipandmask = $iptmp; last; } # got ip, we are done
}
if (!defined($ipandmask)) { die "Error: can't find a NIC with a prefix $ipprefix that communicates with".$args->{mnip}.".\n"; }
my ($ip, $netmask, $network, $broadcast) = convertIpAndMask($ipandmask);
# parse ip addr show output, looking for ipprefix, to determine nic, ip, mac
my @output = runcmd("/sbin/ip addr show");
my ($nic, $mac, $ipandmask);
foreach my $line (@output) {
my ($nictmp, $mactmp, $iptmp);
if (($nictmp) = $line =~ m/^\d+:\s+(\S+): /) { $nic = $nictmp; } # new stanza, remember it
if (($mactmp) = $line =~ m|^\s+link/ether\s+(\S+) |) { $mac = $mactmp; } # got mac, remember it
if (($iptmp) = $line =~ m/^\s+inet\s+($ipprefix\S+) /) { $ipandmask = $iptmp; last; } # got ip, we are done
}
if (!defined($ipandmask)) { die "Error: can't find a NIC with a prefix $ipprefix that communicates with" . $args->{mnip} . ".\n"; }
my ($ip, $netmask, $network, $broadcast) = convertIpAndMask($ipandmask);
# if the nic is a bonded nic (common on sl), then find the 1st real nic that is up that is part of it.
# also find that real nics real mac
my $realnic;
if ($nic =~ /^bond/) {
my @nics = grep(m/\s+master\s+$nic\s+/, @output);
if (!scalar(@nics)) { die "Error: can't find the NICs that are part of $nic.\n"; }
foreach my $line (@nics) {
my ($nictmp, $state) = $line=~m/^\d+:\s+(\S+): .* state\s+(\S+)/;
if (defined($nictmp) && defined($state) && $state eq 'UP') { $realnic = $nictmp; last; } # got ip, we are done
}
if (!defined($realnic)) { die "Error: can't find a physical NIC that is up and part of $nic.\n"; }
# if the nic is a bonded nic (common on sl), then find the 1st real nic that is up that is part of it.
# also find that real nics real mac
my $realnic;
if ($nic =~ /^bond/) {
my @nics = grep(m/\s+master\s+$nic\s+/, @output);
if (!scalar(@nics)) { die "Error: can't find the NICs that are part of $nic.\n"; }
foreach my $line (@nics) {
my ($nictmp, $state) = $line =~ m/^\d+:\s+(\S+): .* state\s+(\S+)/;
if (defined($nictmp) && defined($state) && $state eq 'UP') { $realnic = $nictmp; last; } # got ip, we are done
}
if (!defined($realnic)) { die "Error: can't find a physical NIC that is up and part of $nic.\n"; }
# now get the real mac of this real nic (when 2 nics are bonded, ip addr show displays one of the nics
# macs for both nics and the bond). So we have to depend on /proc/net/bonding/$bond instead.
my @bondout = runcmd("cat /proc/net/bonding/$nic");
my $foundnic;
foreach my $line (@bondout) {
my $mactmp;
if ($line=~m/^Slave Interface:\s+$realnic/) { $foundnic = 1; } # found the stanza for this nic, remember it
if ($foundnic && (($mactmp) = $line=~m/^Permanent HW addr:\s+(\S+)/)) { $mac = $mactmp; last; }
}
}
else { $realnic = $nic; }
# now get the real mac of this real nic (when 2 nics are bonded, ip addr show displays one of the nics
# macs for both nics and the bond). So we have to depend on /proc/net/bonding/$bond instead.
my @bondout = runcmd("cat /proc/net/bonding/$nic");
my $foundnic;
foreach my $line (@bondout) {
my $mactmp;
if ($line =~ m/^Slave Interface:\s+$realnic/) { $foundnic = 1; } # found the stanza for this nic, remember it
if ($foundnic && (($mactmp) = $line =~ m/^Permanent HW addr:\s+(\S+)/)) { $mac = $mactmp; last; }
}
}
else { $realnic = $nic; }
# centos/redhat seems to name the nic in a different order than sles on some svrs.
# sles seems to name them in the same order as 'ip addr show' displays them, centos does not.
# so if we are on centos right now, we need to count down to determine the number that sles
# will give the nic that we have selected, because it is the sles naming that we care about,
# because that is the initrd that will be running in the scripted install case.
# This works similarly (at least in some case) when rhel is the target OS.
# The preferred way is for the user to set installnic=mac, then we do not need to run this code.
# For the sysclone case, genesis doxcat uses the mac to find the nic.
if (isRedhat() && $args->{kernelparms} !~ m/ ksdevice=\S*:/ && $args->{kernelparms} !~ m/ netdevice=\S*:/) {
my @nics = grep(m/^\d+:\s+eth/, @output);
my $i = 0;
foreach my $line (@nics) {
my ($nictmp) = $line=~m/^\d+:\s+(\S+):/;
if (defined($nictmp) && $nictmp eq $realnic) { $realnic = "eth$i"; last; } # got ip, we are done
$i++;
}
print "Determined that SLES/RHEL will call the install NIC $realnic (it has mac $mac)\n";
}
# centos/redhat seems to name the nic in a different order than sles on some svrs.
# sles seems to name them in the same order as 'ip addr show' displays them, centos does not.
# so if we are on centos right now, we need to count down to determine the number that sles
# will give the nic that we have selected, because it is the sles naming that we care about,
# because that is the initrd that will be running in the scripted install case.
# This works similarly (at least in some case) when rhel is the target OS.
# The preferred way is for the user to set installnic=mac, then we do not need to run this code.
# For the sysclone case, genesis doxcat uses the mac to find the nic.
if (isRedhat() && $args->{kernelparms} !~ m/ ksdevice=\S*:/ && $args->{kernelparms} !~ m/ netdevice=\S*:/) {
my @nics = grep(m/^\d+:\s+eth/, @output);
my $i = 0;
foreach my $line (@nics) {
my ($nictmp) = $line =~ m/^\d+:\s+(\S+):/;
if (defined($nictmp) && $nictmp eq $realnic) { $realnic = "eth$i"; last; } # got ip, we are done
$i++;
}
print "Determined that SLES/RHEL will call the install NIC $realnic (it has mac $mac)\n";
}
# finally, find the gateway
my $gateway;
my @output = runcmd("/sbin/ip route");
# we are looking for a line like: 10.0.0.0/8 via 10.54.51.1 dev bond0
my @networks = grep(m/ via .* $nic\s*$/, @output);
if (scalar(@networks)) { ($gateway) = $networks[0]=~m/ via\s+(\S+)/; }
else {
# use the mn ip as a fall back
$gateway = $args->{mnip};
verbose("using xCAT mgmt node IP as the fall back gateway.");
}
# finally, find the gateway
my $gateway;
my @output = runcmd("/sbin/ip route");
verbose("IP info: realnic=$realnic, ip=$ip, netmask=$netmask, gateway=$gateway, mac=$mac");
return ($realnic, $ip, $netmask, $network, $broadcast, $gateway, $mac);
# we are looking for a line like: 10.0.0.0/8 via 10.54.51.1 dev bond0
my @networks = grep(m/ via .* $nic\s*$/, @output);
if (scalar(@networks)) { ($gateway) = $networks[0] =~ m/ via\s+(\S+)/; }
else {
# use the mn ip as a fall back
$gateway = $args->{mnip};
verbose("using xCAT mgmt node IP as the fall back gateway.");
}
verbose("IP info: realnic=$realnic, ip=$ip, netmask=$netmask, gateway=$gateway, mac=$mac");
return ($realnic, $ip, $netmask, $network, $broadcast, $gateway, $mac);
}
# Convert an ip/mask in slash notation (like 10.1.1.1/26) to separate ip, netmask, network, and broadcast values,
# like: 10.1.1.1, 255.255.255.192, 10.1.1.0, 10.1.1.63
sub convertIpAndMask {
my $ipandmask = shift @_;
my ($ip, $masknum) = split('/', $ipandmask);
my $ipandmask = shift @_;
my ($ip, $masknum) = split('/', $ipandmask);
# build the netmask
my $nmbin = oct("0b" . '1' x $masknum . '0' x (32-$masknum)); # create a str like '1111100', then convert to binary
my @nmarr=unpack('C4',pack('N',$nmbin)); # separate into the 4 octets
my $netmask=join('.',@nmarr); # put them together into the normal looking netmask
# build the netmask
my $nmbin = oct("0b" . '1' x $masknum . '0' x (32 - $masknum)); # create a str like '1111100', then convert to binary
my @nmarr = unpack('C4', pack('N', $nmbin)); # separate into the 4 octets
my $netmask = join('.', @nmarr); # put them together into the normal looking netmask
# create binary form of ip
my @iparr=split(/\./,$ip);
my ( $ipbin ) = unpack('N', pack('C4',@iparr ) );
# create binary form of ip
my @iparr = split(/\./, $ip);
my ($ipbin) = unpack('N', pack('C4', @iparr));
# Calculate network address by logical AND operation of ip & netmask and convert network address to IP address format
my $netbin = ( $ipbin & $nmbin );
my @netarr=unpack('C4', pack('N',$netbin ) );
my $network=join(".",@netarr);
# Calculate network address by logical AND operation of ip & netmask and convert network address to IP address format
my $netbin = ($ipbin & $nmbin);
my @netarr = unpack('C4', pack('N', $netbin));
my $network = join(".", @netarr);
# Calculate broadcast address by inverting the netmask and adding it to the network address
my $bcbin = ( $ipbin & $nmbin ) + ( ~ $nmbin );
my @bcarr=unpack('C4', pack('N',$bcbin ) ) ;
my $broadcast=join(".",@bcarr);
# Calculate broadcast address by inverting the netmask and adding it to the network address
my $bcbin = ($ipbin & $nmbin) + (~$nmbin);
my @bcarr = unpack('C4', pack('N', $bcbin));
my $broadcast = join(".", @bcarr);
return ($ip, $netmask, $network, $broadcast);
return ($ip, $netmask, $network, $broadcast);
}
# not used - resolve the hostname to an ip addr
sub getipaddr {
my $hostname = shift @_;
my $packed_ip;
my $hostname = shift @_;
my $packed_ip;
$packed_ip = inet_aton($hostname);
if (!$packed_ip) { return undef; }
return inet_ntoa($packed_ip);
@ -246,102 +255,106 @@ sub getipaddr {
# Update the grub config file with a new stanza for booting our kernel and initrd
sub updateGrub {
my $args = shift @_;
my $args = shift @_;
# how we specify the path for the kernel and initrd is different on redhat and suse
my $fileprefix;
if (isRedhat()) { $fileprefix = '/'; }
elsif (isSuse()) { $fileprefix = '/boot/'; }
else { die "Error: currently only support red hat or suse distros.\n"; }
# how we specify the path for the kernel and initrd is different on redhat and suse
my $fileprefix;
if (isRedhat()) { $fileprefix = '/'; }
elsif (isSuse()) { $fileprefix = '/boot/'; }
else { die "Error: currently only support red hat or suse distros.\n"; }
# open the grub file and see if it is in there or if we have to add it
my $grubfile = findGrubPath();
verbose("reading $grubfile");
open(FILE, $grubfile) || die "Error: can not open config file $grubfile for reading: $!\n";
my @lines = <FILE>;
close FILE;
# open the grub file and see if it is in there or if we have to add it
my $grubfile = findGrubPath();
verbose("reading $grubfile");
open(FILE, $grubfile) || die "Error: can not open config file $grubfile for reading: $!\n";
my @lines = <FILE>;
close FILE;
# this is the entry we want in the grub file
my @rootlines = grep(/^\s+root\s+/, @lines); # copy one of the existing root lines
if (!scalar(@rootlines)) { die "Error: can't find an existing line for 'root' in the grub config file\n"; }
my ($rootline) = $rootlines[0] =~ m/^\s*(.*?)\s*$/;
my @entry = (
"title $XCATNETBOOTTITLE\n",
"\t$rootline\n",
"\tkernel " . $fileprefix . $args->{kernelpath} . ' ' . $args->{kernelparms} . "\n",
"\tinitrd " . $fileprefix . $args->{initrdpath} . "\n",
);
if ($DRYRUN) {
print "Dry run: would add this stanza to $grubfile:\n";
foreach my $l (@entry) { print $l; }
return;
}
# this is the entry we want in the grub file
my @rootlines = grep(/^\s+root\s+/, @lines); # copy one of the existing root lines
if (!scalar(@rootlines)) { die "Error: can't find an existing line for 'root' in the grub config file\n"; }
my ($rootline) = $rootlines[0] =~ m/^\s*(.*?)\s*$/;
my @entry = (
"title $XCATNETBOOTTITLE\n",
"\t$rootline\n",
"\tkernel " . $fileprefix . $args->{kernelpath} . ' ' . $args->{kernelparms} . "\n",
"\tinitrd " . $fileprefix . $args->{initrdpath} . "\n",
);
if ($DRYRUN) {
print "Dry run: would add this stanza to $grubfile:\n";
foreach my $l (@entry) { print $l; }
return;
}
my $needtowritefile = 1;
if (grep(/^title\s+$XCATNETBOOTTITLE/, @lines)) { $needtowritefile = updateGrubEntry(\@lines, \@entry); } # there is already an entry in there
else { addGrubEntry (\@lines, \@entry); }
my $needtowritefile = 1;
if (grep(/^title\s+$XCATNETBOOTTITLE/, @lines)) { $needtowritefile = updateGrubEntry(\@lines, \@entry); } # there is already an entry in there
else { addGrubEntry(\@lines, \@entry); }
# write the file with the new/updated xcat entry
if ($needtowritefile) {
verbose("updating $grubfile");
open(FILE, '>', $grubfile) || die "Error: can not open config file $grubfile for writing: $!\n";
print FILE @lines;
close FILE;
}
else { print "Info: $grubfile did not need modifying. It was already up to date.\n"; }
# write the file with the new/updated xcat entry
if ($needtowritefile) {
verbose("updating $grubfile");
open(FILE, '>', $grubfile) || die "Error: can not open config file $grubfile for writing: $!\n";
print FILE @lines;
close FILE;
}
else { print "Info: $grubfile did not need modifying. It was already up to date.\n"; }
}
# add our entry as the 1st one in the grub file
sub addGrubEntry {
my ($lines, $entry) = @_;
# find the index of the 1st stanza (it starts with 'title')
my $i;
for ($i=0; $i<scalar(@$lines); $i++) {
if ($lines->[$i] =~ m/^title\s+/) { verbose('adding xcat entry before:'.$lines->[$i]); last; } # found it
}
# splice the entry right before the i-th line (which may also be 1 past the end)
splice(@$lines, $i, 0, @$entry);
my ($lines, $entry) = @_;
# find the index of the 1st stanza (it starts with 'title')
my $i;
for ($i = 0 ; $i < scalar(@$lines) ; $i++) {
if ($lines->[$i] =~ m/^title\s+/) { verbose('adding xcat entry before:' . $lines->[$i]); last; } # found it
}
# splice the entry right before the i-th line (which may also be 1 past the end)
splice(@$lines, $i, 0, @$entry);
}
# check the xcat entry in the grub file and see if it needs to be updated. Return 1 if it does.
sub updateGrubEntry {
my ($lines, $entry) = @_;
#print Dumper($lines), Dumper($entry);
# find the index of the xcat stanza
my $i;
for ($i=0; $i<scalar(@$lines); $i++) {
if ($lines->[$i] =~ m/^title\s+$XCATNETBOOTTITLE/) { last; } # found it
}
my ($lines, $entry) = @_;
# compare the next few lines with the corresponding line in @$entries and replace if different
my $replaced = 0;
for (my $j=0; $j<scalar(@$entry); $j++) {
#print "comparing:\n ", $lines->[$i+$j], "\n ", $entry->[$j], "\n";
if ($lines->[$i+$j] ne $entry->[$j]) { # this line was different
$lines->[$i+$j] = $entry->[$j];
$replaced = 1;
}
}
return $replaced;
#print Dumper($lines), Dumper($entry);
# find the index of the xcat stanza
my $i;
for ($i = 0 ; $i < scalar(@$lines) ; $i++) {
if ($lines->[$i] =~ m/^title\s+$XCATNETBOOTTITLE/) { last; } # found it
}
# compare the next few lines with the corresponding line in @$entries and replace if different
my $replaced = 0;
for (my $j = 0 ; $j < scalar(@$entry) ; $j++) {
#print "comparing:\n ", $lines->[$i+$j], "\n ", $entry->[$j], "\n";
if ($lines->[ $i + $j ] ne $entry->[$j]) { # this line was different
$lines->[ $i + $j ] = $entry->[$j];
$replaced = 1;
}
}
return $replaced;
}
# depending on the distro, find the correct grub file and return its path
sub findGrubPath {
# for rhel/centos it is /boot/grub/grub.conf, for sles it is /boot/grub/menu.lst
my @paths = qw(/boot/grub/grub.conf /boot/grub/menu.lst);
foreach my $p (@paths) {
if (-f $p) { return $p; }
}
die "Error: Can't find grub config file.\n";
#todo: support ubuntu: you add an executable file in /etc/grub.d named 06_xcatnetboot that prints out the
# entry to add. Then run grub-mkconfig.
# for rhel/centos it is /boot/grub/grub.conf, for sles it is /boot/grub/menu.lst
my @paths = qw(/boot/grub/grub.conf /boot/grub/menu.lst);
foreach my $p (@paths) {
if (-f $p) { return $p; }
}
die "Error: Can't find grub config file.\n";
#todo: support ubuntu: you add an executable file in /etc/grub.d named 06_xcatnetboot that prints out the
# entry to add. Then run grub-mkconfig.
}
@ -350,7 +363,7 @@ sub verbose { if ($VERBOSE) { print shift, "\n"; } }
# Check the distro we are running on
sub isSuse { return (-e '/etc/SuSE-release'); }
sub isRedhat { return (-e '/etc/redhat-release' || -e '/etc/centos-release' || -e '/etc/fedora-release'); } # add chk for fedora
sub isRedhat { return (-e '/etc/redhat-release' || -e '/etc/centos-release' || -e '/etc/fedora-release'); } # add chk for fedora
@ -362,23 +375,23 @@ sub runcmd
my ($cmd) = @_;
my $rc;
$cmd .= ' 2>&1' ;
$cmd .= ' 2>&1';
verbose($cmd);
my @output;
if (wantarray) {
@output = `$cmd`;
$rc = $?;
}
else {
system($cmd);
$rc = $?;
}
my @output;
if (wantarray) {
@output = `$cmd`;
$rc = $?;
}
else {
system($cmd);
$rc = $?;
}
if ($rc) {
$rc = $rc >> 8;
if ($rc > 0) { die "Error: rc $rc return from cmd: $cmd\n"; }
else { die "Error: system error returned from cmd: $cmd\n"; }
if ($rc > 0) { die "Error: rc $rc return from cmd: $cmd\n"; }
else { die "Error: system error returned from cmd: $cmd\n"; }
}
elsif (wantarray) { return @output; }
}

View File

@ -18,30 +18,31 @@ my $WAITTIME;
my $NOAUTOINST;
my $usage = sub {
my $exitcode = shift @_;
print "Usage: pushinitrd [-?|-h|--help] [-v|--verbose] [--dryrun] [-w <waittime>] [--noautoinst] <noderange>\n\n";
if (!$exitcode) {
print "Copy the initrd, kernel, params, and static IP info to nodes, so they can net install\n";
print "even across vlans (w/o setting up pxe/dhcp broadcast relay). This assumes a working\n";
print "OS is on the node, that you've run nodeset for these nodes, and that all of the nodes\n";
print "in this noderange are using the same osimage.\n";
}
exit $exitcode;
my $exitcode = shift @_;
print "Usage: pushinitrd [-?|-h|--help] [-v|--verbose] [--dryrun] [-w <waittime>] [--noautoinst] <noderange>\n\n";
if (!$exitcode) {
print "Copy the initrd, kernel, params, and static IP info to nodes, so they can net install\n";
print "even across vlans (w/o setting up pxe/dhcp broadcast relay). This assumes a working\n";
print "OS is on the node, that you've run nodeset for these nodes, and that all of the nodes\n";
print "in this noderange are using the same osimage.\n";
}
exit $exitcode;
};
# Process the cmd line args
Getopt::Long::Configure("bundling");
# Getopt::Long::Configure("pass_through");
Getopt::Long::Configure("no_pass_through");
if (!GetOptions('h|?|help' => \$HELP, 'v|verbose' => \$VERBOSE, 'dryrun' => \$DRYRUN, 'w|waittime=s' => \$WAITTIME, 'a|noautoinst' => \$NOAUTOINST)) { $usage->(1); }
if (!GetOptions('h|?|help' => \$HELP, 'v|verbose' => \$VERBOSE, 'dryrun' => \$DRYRUN, 'w|waittime=s' => \$WAITTIME, 'a|noautoinst' => \$NOAUTOINST)) { $usage->(1); }
if ($HELP) { $usage->(0); }
if (scalar(@ARGV) != 1) { $usage->(1); }
if (!defined($WAITTIME)) { $WAITTIME = 75; } # seconds to wait after configuring the nic (to let the switch handle the state change)
if (!defined($WAITTIME)) { $WAITTIME = 75; } # seconds to wait after configuring the nic (to let the switch handle the state change)
my $noderange = $ARGV[0];
#
# Run some Node verification before starting pushinitrd
# Run some Node verification before starting pushinitrd
#
verifyNodeConfiguration($noderange);
@ -51,7 +52,7 @@ updateGrubOnNodes($noderange, \%bootparms);
if ($DRYRUN) { exit(0); }
if ($bootparms{osimageprovmethod} eq 'install' && $bootparms{osimageosvers}=~ m/^sles/ && !$NOAUTOINST) { modifyAutoinstFiles($noderange, \%bootparms); }
if ($bootparms{osimageprovmethod} eq 'install' && $bootparms{osimageosvers} =~ m/^sles/ && !$NOAUTOINST) { modifyAutoinstFiles($noderange, \%bootparms); }
if ($bootparms{osimageprovmethod} eq 'sysclone') { copySyscloneFiles(); }
@ -59,307 +60,321 @@ exit(0);
# Query the db for the kernel, initrd, and kcmdline attributes of the 1st node in the noderange
sub getBootParms {
my $nr = shift @_;
my %bootparms;
my @output = runcmd("nodels $nr bootparams.kernel bootparams.initrd bootparams.kcmdline nodetype.provmethod");
my $nr = shift @_;
my %bootparms;
my @output = runcmd("nodels $nr bootparams.kernel bootparams.initrd bootparams.kcmdline nodetype.provmethod");
# the attributes can be displayed in a different order than requested, so need to grep for them
foreach my $attr (qw(bootparams.kernel bootparams.initrd bootparams.kcmdline nodetype.provmethod)) {
my ($a) = $attr =~ m/\.(.*)$/;
my @gresults = grep(/^\S+:\s+$attr:/, @output);
if (!scalar(@gresults)) { die "Error: attribute $attr not defined for the noderange. Did you run 'nodeset <noderange> osimage=<osimage>' ?\n"; }
# for now just pick the 1st one. They should all be the same, except for the node name in kcmdline
chomp($gresults[0]);
$gresults[0] =~ s/^\S+:\s+$attr:\s*//;
#print "gresults='$gresults[0]'\n";
if ($gresults[0] !~ m/\S/) { die "Error: attribute $attr not defined for the noderange. Did you run 'nodeset <noderange> osimage=<osimage>' ?\n"; }
$bootparms{$a} = $gresults[0];
}
$bootparms{kcmdline} =~ s|/install/autoinst/\S+|/install/autoinst/<nodename>|;
# the attributes can be displayed in a different order than requested, so need to grep for them
foreach my $attr (qw(bootparams.kernel bootparams.initrd bootparams.kcmdline nodetype.provmethod)) {
my ($a) = $attr =~ m/\.(.*)$/;
my @gresults = grep(/^\S+:\s+$attr:/, @output);
if (!scalar(@gresults)) { die "Error: attribute $attr not defined for the noderange. Did you run 'nodeset <noderange> osimage=<osimage>' ?\n"; }
# from the nodes provmethod, get the osimage provmethod, so we know the type of install
@output = runcmd("lsdef -t osimage $bootparms{provmethod} -ci provmethod,osvers");
foreach my $line (@output) {
chomp($line);
if ($line =~ m/^Could not find/) { die "Error: provmethod $bootparms{provmethod} is set for the node, but there is no osimage definition by that name."; }
if ($line =~ m/ provmethod=/) {
my ($junk, $provmethod) = split(/=/, $line);
$bootparms{osimageprovmethod} = $provmethod;
}
if ($line =~ m/ osvers=/) {
my ($junk, $osvers) = split(/=/, $line);
$bootparms{osimageosvers} = $osvers;
}
}
#print "provmethod=$bootparms{osimageprovmethod}, osvers=$bootparms{osimageosvers}\n"; exit;
# for now just pick the 1st one. They should all be the same, except for the node name in kcmdline
chomp($gresults[0]);
$gresults[0] =~ s/^\S+:\s+$attr:\s*//;
# get the mgmt node cluster-facing ip addr
@output = runcmd('lsdef -t site -ci master');
chomp($output[0]);
my ($junk, $ip) = split(/=/, $output[0]);
$bootparms{mnip} = $ip;
#print "gresults='$gresults[0]'\n";
if ($gresults[0] !~ m/\S/) { die "Error: attribute $attr not defined for the noderange. Did you run 'nodeset <noderange> osimage=<osimage>' ?\n"; }
$bootparms{$a} = $gresults[0];
}
$bootparms{kcmdline} =~ s|/install/autoinst/\S+|/install/autoinst/<nodename>|;
verbose(Dumper(\%bootparms));
return %bootparms;
# from the nodes provmethod, get the osimage provmethod, so we know the type of install
@output = runcmd("lsdef -t osimage $bootparms{provmethod} -ci provmethod,osvers");
foreach my $line (@output) {
chomp($line);
if ($line =~ m/^Could not find/) { die "Error: provmethod $bootparms{provmethod} is set for the node, but there is no osimage definition by that name."; }
if ($line =~ m/ provmethod=/) {
my ($junk, $provmethod) = split(/=/, $line);
$bootparms{osimageprovmethod} = $provmethod;
}
if ($line =~ m/ osvers=/) {
my ($junk, $osvers) = split(/=/, $line);
$bootparms{osimageosvers} = $osvers;
}
}
#print "provmethod=$bootparms{osimageprovmethod}, osvers=$bootparms{osimageosvers}\n"; exit;
# get the mgmt node cluster-facing ip addr
@output = runcmd('lsdef -t site -ci master');
chomp($output[0]);
my ($junk, $ip) = split(/=/, $output[0]);
$bootparms{mnip} = $ip;
verbose(Dumper(\%bootparms));
return %bootparms;
}
# Copy the kernel and initrd to the nodes
# Args: noderange, reference to the bootparms hash
sub copyFilesToNodes {
my $nr = shift @_;
my $bootparms = shift @_;
foreach my $a (qw(kernel initrd)) {
my $file = $bootparms->{$a};
my $localfile = "/tftpboot/$file";
# for the
my $remotefile = '/boot/' . remoteFilename($file);
my $cmd = "xdcp $nr -p $localfile $remotefile";
if ($DRYRUN) {
print "Dry run: Copying $localfile to $nr:$remotefile\n";
print "Dry run: $cmd\n";
}
else {
print "Copying $localfile to $nr:$remotefile\n";
runcmd($cmd);
}
}
my $nr = shift @_;
my $bootparms = shift @_;
foreach my $a (qw(kernel initrd)) {
my $file = $bootparms->{$a};
my $localfile = "/tftpboot/$file";
# for the
my $remotefile = '/boot/' . remoteFilename($file);
my $cmd = "xdcp $nr -p $localfile $remotefile";
if ($DRYRUN) {
print "Dry run: Copying $localfile to $nr:$remotefile\n";
print "Dry run: $cmd\n";
}
else {
print "Copying $localfile to $nr:$remotefile\n";
runcmd($cmd);
}
}
}
# Form the remote file name, using the last 2 parts of the path, separated by "-"
sub remoteFilename {
my $f = shift @_;
$f =~ s|^.*?([^/]+)/([^/]+)$|$1-$2|;
return $f;
my $f = shift @_;
$f =~ s|^.*?([^/]+)/([^/]+)$|$1-$2|;
return $f;
}
# Run the modifygrub script on the nodes to update the grub config file
# Args: noderange, reference to the bootparms hash
sub updateGrubOnNodes {
my $nr = shift @_;
my $bootparms = shift @_;
my $vtxt = ($VERBOSE ? '-v' : '');
my $dtxt = ($DRYRUN ? '--dryrun' : '');
my @output = runcmd('which modifygrub');
my $modifygrub = $output[0];
chomp($modifygrub);
my $euser ="root";
my $cmd = "xdsh $nr -l $euser -e $modifygrub $vtxt $dtxt -w $WAITTIME -p " . $bootparms->{osimageprovmethod} . ' ' . remoteFilename($bootparms->{kernel}) . ' ' . remoteFilename($bootparms->{initrd}) . ' ';
# we need to quote the kernel parms, both here when passing it to xdsh, and on the node
# when xdsh is passing it to modifygrub. The way to get single quotes inside single quotes
# is to quote each of the outer single quotes with double quotes.
$cmd .= q("'"') . $bootparms->{kcmdline} . q('"'");
$cmd .= ' ' . $bootparms->{mnip};
print "Running modifygrub on $nr to update the grub configuration.\n";
runcmd($cmd);
my $nr = shift @_;
my $bootparms = shift @_;
my $vtxt = ($VERBOSE ? '-v' : '');
my $dtxt = ($DRYRUN ? '--dryrun' : '');
my @output = runcmd('which modifygrub');
my $modifygrub = $output[0];
chomp($modifygrub);
my $euser = "root";
my $cmd = "xdsh $nr -l $euser -e $modifygrub $vtxt $dtxt -w $WAITTIME -p " . $bootparms->{osimageprovmethod} . ' ' . remoteFilename($bootparms->{kernel}) . ' ' . remoteFilename($bootparms->{initrd}) . ' ';
# we need to quote the kernel parms, both here when passing it to xdsh, and on the node
# when xdsh is passing it to modifygrub. The way to get single quotes inside single quotes
# is to quote each of the outer single quotes with double quotes.
$cmd .= q("'"') . $bootparms->{kcmdline} . q('"'");
$cmd .= ' ' . $bootparms->{mnip};
print "Running modifygrub on $nr to update the grub configuration.\n";
runcmd($cmd);
}
# Hack the autoinst files to overcome the nic coming up delay.
#todo: this has only been tested with SLES nodes
sub modifyAutoinstFiles {
my $nr = shift @_;
my $bootparms = shift @_;
my $nr = shift @_;
my $bootparms = shift @_;
# expand the noderange into a list of nodes
my @nodes = runcmd("nodels $nr");
chomp(@nodes);
# expand the noderange into a list of nodes
my @nodes = runcmd("nodels $nr");
chomp(@nodes);
# Modify chroot.sles to insert a wait in the /etc/init.d/network of each node. This is
# necessary because even tho compute.sles11.softlayer.tmpl configures bonding, when autoyast
# reboots the node after installing the rpms, it does not bring up the network in the normal way
# at first and seems to skip any bonding and the if-up.d scripts. So we are left doing this.
# (After autoyast is done with all of its post-configuration, it brings up the network in the
# normal way, so bonding gets done then, which is good at least.)
# Modify chroot.sles to insert a wait in the /etc/init.d/network of each node. This is
# necessary because even tho compute.sles11.softlayer.tmpl configures bonding, when autoyast
# reboots the node after installing the rpms, it does not bring up the network in the normal way
# at first and seems to skip any bonding and the if-up.d scripts. So we are left doing this.
# (After autoyast is done with all of its post-configuration, it brings up the network in the
# normal way, so bonding gets done then, which is good at least.)
# Edit each file to have chroot.sles insert a wait at the end of /etc/init.d/network
# this finds the end of boot.sh script (which is chroot.sles)
my $search = '\n\]\]>\s*</source>\s*</script>\s*</chroot-scripts>';
# hack the /etc/init.d/network script to put a wait in it
my $file = '/mnt/etc/init.d/network'; # at this point in the installation, the permanent file system is just mounted
# this is the string to insert in the nodes /etc/init.d/network script. It is a while loop pinging the mn, but some of the chars need to be escaped for sed
my $waitstring = 'echo -n Waiting to reach xCAT mgmt node ' . $bootparms->{mnip} . '.;xcatretries=60;while \[ \$\(\(xcati+=1\)\) -le \$xcatretries \] \&\& ! ping -c2 -w3 ' . $bootparms->{mnip} .' \>\/dev\/null 2\>\&1; do echo -n .; done; if \[ \$xcati -le \$xcatretries \]; then echo success; else echo failed; fi';
# this crazy sed string is from google. It gathers up the whole file into the hold buffer, and then the substitution is done on the whole file
my $sedstring = q|sed -n '1h;1!H;${;g;s/\(\t\treload_firewall\n\)\n/\1\t\t| . $waitstring . q(\n\n/g;p;}') . " $file > $file.new";
# finally create the perl replace string that will be used to modify the autoinst file
my $replace = "$sedstring\nchmod 755 $file.new; mv -f $file.new $file";
# Edit each file to have chroot.sles insert a wait at the end of /etc/init.d/network
# this finds the end of boot.sh script (which is chroot.sles)
my $search = '\n\]\]>\s*</source>\s*</script>\s*</chroot-scripts>';
# Add a script that gets invoked by the OS after the nic is brought up
# Note: this does not work, because midway thru the autoyast process, the if-up.d scripts do not seem to get invoked
# so autoyast fails to get the media
# these are specific to SLES
#my $netdir = '/etc/sysconfig/network';
#my $filename = '/etc/sysconfig/network/if-up.d/xcat-sl-wait';
#my $mnip = $bootparms->{mnip};
#todo: to support rhel, use these values instead
#my $netdir='/etc/sysconfig/network-scripts';
#my $filename='/sbin/ifup-local';
#my $replace = qq(
#FILENAME=$filename
#NETDIR=$netdir
#MNIP=$mnip
#);
# $replace .= q(
#cat >$FILENAME << EOF1
#MNIP=$MNIP
#NETDIR=$NETDIR
#EOF1
#
# this part of the file we do NOT want to expand the variables in the content
#cat >>$FILENAME << 'EOF2'
#NIC="$1"
# look in this ifcfg script to get the nics ip to see if this is the one we should be waiting on
#NICIP=`awk -F= '/^IPADDR/ {print $2}' $NETDIR/ifcfg-$NIC | tr -d \' `
#if [ "${NICIP%.*.*}" != "${MNIP%.*.*}" ]; then exit; fi # hack: compare the 1st 2 octets
#echo -n Waiting to reach xCAT mgmt node $MNIP.
#xcatretries=60
#while [ $((xcati+=1)) -le $xcatretries ] && ! ping -c2 -w3 $MNIP >/dev/null 2>&1; do echo -n .; done
#if [ $xcati -le $xcatretries ]; then echo " success"; else echo " failed"; fi
#sleep 3
#EOF2
#
#chmod +x $FILENAME
#);
# hack the /etc/init.d/network script to put a wait in it
my $file = '/mnt/etc/init.d/network'; # at this point in the installation, the permanent file system is just mounted
# this is the string to insert in the nodes /etc/init.d/network script. It is a while loop pinging the mn, but some of the chars need to be escaped for sed
my $waitstring = 'echo -n Waiting to reach xCAT mgmt node ' . $bootparms->{mnip} . '.;xcatretries=60;while \[ \$\(\(xcati+=1\)\) -le \$xcatretries \] \&\& ! ping -c2 -w3 ' . $bootparms->{mnip} . ' \>\/dev\/null 2\>\&1; do echo -n .; done; if \[ \$xcati -le \$xcatretries \]; then echo success; else echo failed; fi';
# The compute.sles11.softlayer.tmpl file contains 2 variables (node ip and netmask) that are
# not replaced by Template.pm. Substitute those in the autoinst files now.
# Also use our own multiline sed to put the network script hack in.
print "Updating /install/autoinst files.\n";
foreach my $n (@nodes) {
my $f = "/install/autoinst/$n";
my ($ip, $netmask, $gateway) = getNodeIpInfo($n);
runcmd("sudo sed -i 's/#NODEIPADDR#/$ip/;s/#NODENETMASK#/$netmask/;s/#NODEGATEWAY#/$gateway/' $f");
my $matches = sed($f, $search, $replace, mode=>'insertbefore');
if (!$matches) { die "Error: could not find the right place in $f to insert the sed of the network wait.\n"; }
}
# this crazy sed string is from google. It gathers up the whole file into the hold buffer, and then the substitution is done on the whole file
my $sedstring = q|sed -n '1h;1!H;${;g;s/\(\t\treload_firewall\n\)\n/\1\t\t| . $waitstring . q(\n\n/g;p;}') . " $file > $file.new";
# finally create the perl replace string that will be used to modify the autoinst file
my $replace = "$sedstring\nchmod 755 $file.new; mv -f $file.new $file";
# Add a script that gets invoked by the OS after the nic is brought up
# Note: this does not work, because midway thru the autoyast process, the if-up.d scripts do not seem to get invoked
# so autoyast fails to get the media
# these are specific to SLES
#my $netdir = '/etc/sysconfig/network';
#my $filename = '/etc/sysconfig/network/if-up.d/xcat-sl-wait';
#my $mnip = $bootparms->{mnip};
#todo: to support rhel, use these values instead
#my $netdir='/etc/sysconfig/network-scripts';
#my $filename='/sbin/ifup-local';
#my $replace = qq(
#FILENAME=$filename
#NETDIR=$netdir
#MNIP=$mnip
#);
# $replace .= q(
#cat >$FILENAME << EOF1
#MNIP=$MNIP
#NETDIR=$NETDIR
#EOF1
#
# this part of the file we do NOT want to expand the variables in the content
#cat >>$FILENAME << 'EOF2'
#NIC="$1"
# look in this ifcfg script to get the nics ip to see if this is the one we should be waiting on
#NICIP=`awk -F= '/^IPADDR/ {print $2}' $NETDIR/ifcfg-$NIC | tr -d \' `
#if [ "${NICIP%.*.*}" != "${MNIP%.*.*}" ]; then exit; fi # hack: compare the 1st 2 octets
#echo -n Waiting to reach xCAT mgmt node $MNIP.
#xcatretries=60
#while [ $((xcati+=1)) -le $xcatretries ] && ! ping -c2 -w3 $MNIP >/dev/null 2>&1; do echo -n .; done
#if [ $xcati -le $xcatretries ]; then echo " success"; else echo " failed"; fi
#sleep 3
#EOF2
#
#chmod +x $FILENAME
#);
# The compute.sles11.softlayer.tmpl file contains 2 variables (node ip and netmask) that are
# not replaced by Template.pm. Substitute those in the autoinst files now.
# Also use our own multiline sed to put the network script hack in.
print "Updating /install/autoinst files.\n";
foreach my $n (@nodes) {
my $f = "/install/autoinst/$n";
my ($ip, $netmask, $gateway) = getNodeIpInfo($n);
runcmd("sudo sed -i 's/#NODEIPADDR#/$ip/;s/#NODENETMASK#/$netmask/;s/#NODEGATEWAY#/$gateway/' $f");
my $matches = sed($f, $search, $replace, mode => 'insertbefore');
if (!$matches) { die "Error: could not find the right place in $f to insert the sed of the network wait.\n"; }
}
}
sub verifyNodeConfiguration {
my $nr = shift @_;
sub verifyNodeConfiguration {
my $nr = shift @_;
my @nodes = runcmd("nodels $nr");
chomp(@nodes);
my @nodes = runcmd("nodels $nr");
chomp(@nodes);
foreach my $n (@nodes) {
# Verify the IP is set for the node
my @output = runcmd("nodels $n hosts.ip");
chomp($output[0]);
my ($junk, $ip) = split(/\s+/, $output[0]);
#todo: also support getting the ip from name resolution
if (!$ip) {
die "Error: The ip attribute must be set for $n.\n";
}
}
foreach my $n (@nodes) {
# Verify the IP is set for the node
my @output = runcmd("nodels $n hosts.ip");
chomp($output[0]);
my ($junk, $ip) = split(/\s+/, $output[0]);
#todo: also support getting the ip from name resolution
if (!$ip) {
die "Error: The ip attribute must be set for $n.\n";
}
}
}
# Copy softlayer specific systemimager post-install scripts to the systemimager location.
# These cause si to use static ip and insert a wait into the bring up of the network.
sub copySyscloneFiles {
my $cmd = "cp -f /opt/xcat/share/xcat/sysclone/post-install/* /install/sysclone/scripts/post-install";
print "Copying SoftLayer-specific post scripts to the SystemImager post-install directory.\n";
runcmd($cmd);
my $cmd = "cp -f /opt/xcat/share/xcat/sysclone/post-install/* /install/sysclone/scripts/post-install";
print "Copying SoftLayer-specific post scripts to the SystemImager post-install directory.\n";
runcmd($cmd);
}
# Get IP and network of a node
sub getNodeIpInfo {
my $node = shift;
my $node = shift;
# get ip for the node
my @output = runcmd("nodels $node hosts.ip");
chomp($output[0]);
my ($junk, $ip) = split(/\s+/, $output[0]);
#todo: also support getting the ip from name resolution
# get ip for the node
my @output = runcmd("nodels $node hosts.ip");
chomp($output[0]);
my ($junk, $ip) = split(/\s+/, $output[0]);
# find relevant network in the networks table
# first get the networks in a hash
my %networks;
@output = runcmd("lsdef -t network -ci net,mask,gateway");
foreach my $line (@output) {
chomp($line);
my ($netname, $attr, $val) = $line =~ m/^(.+):\s+(.+?)=(.+)$/;
$networks{$netname}->{$attr} = $val;
}
# now go thru the networks looking for the correct one
my ($netmask, $gateway);
foreach my $key (keys %networks) {
if (isIPinNet($ip, $networks{$key}->{net}, $networks{$key}->{mask})) { # found it
$netmask = $networks{$key}->{mask};
$gateway = $networks{$key}->{gateway};
last;
}
}
if (!$netmask) { die "Error: could not find a network in the networks table that $node $ip is part of.\n"; }
if (!$gateway) { die "Error: gateway not specified in the networks table for the network that $node $ip is part of.\n"; }
#todo: also support getting the ip from name resolution
verbose("IP info for $node: ip=$ip, netmask=$netmask, gateway=$gateway");
return ($ip, $netmask, $gateway);
# find relevant network in the networks table
# first get the networks in a hash
my %networks;
@output = runcmd("lsdef -t network -ci net,mask,gateway");
foreach my $line (@output) {
chomp($line);
my ($netname, $attr, $val) = $line =~ m/^(.+):\s+(.+?)=(.+)$/;
$networks{$netname}->{$attr} = $val;
}
# now go thru the networks looking for the correct one
my ($netmask, $gateway);
foreach my $key (keys %networks) {
if (isIPinNet($ip, $networks{$key}->{net}, $networks{$key}->{mask})) { # found it
$netmask = $networks{$key}->{mask};
$gateway = $networks{$key}->{gateway};
last;
}
}
if (!$netmask) { die "Error: could not find a network in the networks table that $node $ip is part of.\n"; }
if (!$gateway) { die "Error: gateway not specified in the networks table for the network that $node $ip is part of.\n"; }
verbose("IP info for $node: ip=$ip, netmask=$netmask, gateway=$gateway");
return ($ip, $netmask, $gateway);
}
# Is the IP in the network/netmask combo
sub isIPinNet {
my ($ip, $net, $mask) = @_;
my $ipbin = convert2bin($ip);
my $netbin = convert2bin($net);
my $maskbin = convert2bin($mask);
my ($ip, $net, $mask) = @_;
my $ipbin = convert2bin($ip);
my $netbin = convert2bin($net);
my $maskbin = convert2bin($mask);
$ipbin &= $maskbin;
if ($ipbin && $netbin && ($ipbin == $netbin)) { return 1; }
else { return 0; }
if ($ipbin && $netbin && ($ipbin == $netbin)) { return 1; }
else { return 0; }
}
# Convert dotted decimal format (1.2.3.4) to a binary number
sub convert2bin {
my @arr=split(/\./, shift);
my ($bin) = unpack('N', pack('C4',@arr ) );
return $bin;
my @arr = split(/\./, shift);
my ($bin) = unpack('N', pack('C4', @arr));
return $bin;
}
# this is like multi-line sed replace function
# Args: filename, search-string, replace-string, options (mode=>{insertbefore,insertafter,replace})
sub sed {
my ($file, $search, $replace, %options) = @_;
#my $opts = 's';
#if ($options{global}) { $opts .= 'g'; }
my ($file, $search, $replace, %options) = @_;
# open the file for reading
verbose("reading $file");
open(FILE, $file) || die "Error: can not open file $file for reading: $!\n";
my $lines;
while (<FILE>) { $lines .= $_; }
#verbose('file length is '.length($lines));
close FILE;
#my $opts = 's';
#if ($options{global}) { $opts .= 'g'; }
# we also need to look for this string 1st
my $replacecopy = $replace; # a search string can't have special chars in it
$replacecopy =~ s/(\W)/\\$1/g; # so escape all of the meta characters
#print "replacecopy=$replacecopy\n";
# check to see if the replace string is already in the file
if ($lines =~ m/$replacecopy/s) {
print "$file did not need updating.\n";
return 1;
}
# open the file for reading
verbose("reading $file");
open(FILE, $file) || die "Error: can not open file $file for reading: $!\n";
my $lines;
while (<FILE>) { $lines .= $_; }
# search/replace and see if there were any matches
my $matches;
if ($options{mode} eq 'insertbefore') { $matches = $lines =~ s/($search)/\n$replace\n$1/s; }
elsif ($options{mode} eq 'insertafter') { $matches = $lines =~ s/($search)/$1\n$replace\n/s; }
elsif ($options{mode} eq 'replace') { $matches = $lines =~ s/$search/$replace/s; }
else { die "Internal error: don't suppor sed mode of $options{mode}.\n"; }
#verbose('file length is '.length($lines));
close FILE;
# we also need to look for this string 1st
my $replacecopy = $replace; # a search string can't have special chars in it
$replacecopy =~ s/(\W)/\\$1/g; # so escape all of the meta characters
#print "replacecopy=$replacecopy\n";
# check to see if the replace string is already in the file
if ($lines =~ m/$replacecopy/s) {
print "$file did not need updating.\n";
return 1;
}
# search/replace and see if there were any matches
my $matches;
if ($options{mode} eq 'insertbefore') { $matches = $lines =~ s/($search)/\n$replace\n$1/s; }
elsif ($options{mode} eq 'insertafter') { $matches = $lines =~ s/($search)/$1\n$replace\n/s; }
elsif ($options{mode} eq 'replace') { $matches = $lines =~ s/$search/$replace/s; }
else { die "Internal error: don't suppor sed mode of $options{mode}.\n"; }
# write file if necessary
if ($matches) {
verbose("updating $file");
open(FILE, '>', $file) || die "Error: can not open file $file for writing: $!\n";
print FILE $lines;
close FILE;
}
return $matches;
# write file if necessary
if ($matches) {
verbose("updating $file");
open(FILE, '>', $file) || die "Error: can not open file $file for writing: $!\n";
print FILE $lines;
close FILE;
}
return $matches;
}
@ -376,23 +391,23 @@ sub runcmd
my ($cmd) = @_;
my $rc;
$cmd .= ' 2>&1' ;
$cmd .= ' 2>&1';
verbose($cmd);
my @output;
if (wantarray) {
@output = `$cmd`;
$rc = $?;
}
else {
system($cmd);
$rc = $?;
}
my @output;
if (wantarray) {
@output = `$cmd`;
$rc = $?;
}
else {
system($cmd);
$rc = $?;
}
if ($rc) {
$rc = $rc >> 8;
if ($rc > 0) { die "Error: rc $rc return from cmd: $cmd\n"; }
else { die "Error: system error returned from cmd: $cmd\n"; }
if ($rc > 0) { die "Error: rc $rc return from cmd: $cmd\n"; }
else { die "Error: system error returned from cmd: $cmd\n"; }
}
elsif (wantarray) { return @output; }
}

View File

@ -8,17 +8,19 @@
# done relative to that.
use strict;
#use lib '.';
use Pod::Man;
use Pod::Html;
my $poddir = 'pods';
my $mandir = 'share/man';
my $htmldir = 'share/doc';
my $poddir = 'pods';
my $mandir = 'share/man';
my $htmldir = 'share/doc';
my $cachedir = "$ENV{'HOME'}/tmp";
if (system("mkdir -p $cachedir")) { die "Error: could not create $cachedir.\n"; }
my @pods = getPodList($poddir);
#foreach (@pods) { print "$_\n"; } exit;
# Build the cmd overview page.
@ -29,12 +31,12 @@ my @pods = getPodList($poddir);
print "Converting PODs to man pages...\n";
foreach my $podfile (@pods) {
my $manfile = $podfile;
$manfile =~ s/^$poddir/$mandir/; # change the beginning of the path
$manfile =~ s/\.pod$//; # change the ending
$manfile =~ s/^$poddir/$mandir/; # change the beginning of the path
$manfile =~ s/\.pod$//; # change the ending
my $mdir = $manfile;
$mdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $mdir")) { die "Error: could not create $mdir.\n"; }
my ($section) = $podfile =~ /\.(\d+)\.pod$/;
$mdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $mdir")) { die "Error: could not create $mdir.\n"; }
my ($section) = $podfile =~ /\.(\d+)\.pod$/;
convertpod2man($podfile, $manfile, $section);
}
@ -43,15 +45,17 @@ my @dummyPods = createDummyPods($poddir, \@pods);
# Build the html page for each pod.
#mkdir($htmldir) or die "Error: could not create $htmldir.\n";
print "Converting PODs to HTML pages...\n";
# have to clear the cache, because old entries can cause a problem
unlink("$cachedir/pod2htmd.tmp", "$cachedir/pod2htmi.tmp");
foreach my $podfile (@pods) {
my $htmlfile = $podfile;
$htmlfile =~ s/^$poddir/$htmldir/; # change the beginning of the path
$htmlfile =~ s/\.pod$/\.html/; # change the ending
$htmlfile =~ s/^$poddir/$htmldir/; # change the beginning of the path
$htmlfile =~ s/\.pod$/\.html/; # change the ending
my $hdir = $htmlfile;
$hdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $hdir")) { die "Error: could not create $hdir.\n"; }
$hdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $hdir")) { die "Error: could not create $hdir.\n"; }
#print "$podfile, $htmlfile, $poddir, $htmldir\n";
convertpod2html($podfile, $htmlfile, $poddir, $htmldir);
}
@ -68,73 +72,78 @@ exit;
# if that pod does not exist, create an empty one that will satisfy pod2html
# keep track of all dummy pods created, so they can be removed later
sub createDummyPods {
my ($poddir, $pods) = @_;
my $cmd = "grep -r -E 'L<.+\\([57]\\)\\|.+\\.[57]>' " . $poddir;
#print "Running cmd: ", $cmd, "\n";
my @lines = `$cmd`;
if ($?) { print "Did not find any section 5 man page, creating dummy pods...\n"; print join('', @lines); }
#my @lines;
#system($cmd);
my @dummyPods;
foreach my $l (@lines) {
#print "$l\n";
my @matches = $l =~ /L<([^\(]+)\(([57])\)\|\1\.[57]>/g; # get all the matches in the line
# The above line should create the array with every other entry being the man page name
# and every other entry is the section # (5 or 7)
my $cmd;
while ($cmd=shift @matches) {
#foreach my $m (@matches) {
my $section = shift @matches;
my $filename = "$poddir/man$section/$cmd.$section.pod";
#print "$filename\n";
if (!(grep /^$filename$/, @$pods) && !(grep /^$filename$/, @dummyPods)) { push @dummyPods, $filename; }
}
}
# Create these empty files
print "Creating empty linked-to files: ", join(', ', @dummyPods), "\n";
mkdir "$poddir/man7";
foreach my $d (@dummyPods) {
if (!open(TMP, ">>$d")) { warn "Could not create dummy pod file $d ($!)\n"; }
else { close TMP; }
}
return @dummyPods;
my ($poddir, $pods) = @_;
my $cmd = "grep -r -E 'L<.+\\([57]\\)\\|.+\\.[57]>' " . $poddir;
#print "Running cmd: ", $cmd, "\n";
my @lines = `$cmd`;
if ($?) { print "Did not find any section 5 man page, creating dummy pods...\n"; print join('', @lines); }
#my @lines;
#system($cmd);
my @dummyPods;
foreach my $l (@lines) {
#print "$l\n";
my @matches = $l =~ /L<([^\(]+)\(([57])\)\|\1\.[57]>/g; # get all the matches in the line
# The above line should create the array with every other entry being the man page name
# and every other entry is the section # (5 or 7)
my $cmd;
while ($cmd = shift @matches) {
#foreach my $m (@matches) {
my $section = shift @matches;
my $filename = "$poddir/man$section/$cmd.$section.pod";
#print "$filename\n";
if (!(grep /^$filename$/, @$pods) && !(grep /^$filename$/, @dummyPods)) { push @dummyPods, $filename; }
}
}
# Create these empty files
print "Creating empty linked-to files: ", join(', ', @dummyPods), "\n";
mkdir "$poddir/man7";
foreach my $d (@dummyPods) {
if (!open(TMP, ">>$d")) { warn "Could not create dummy pod file $d ($!)\n"; }
else { close TMP; }
}
return @dummyPods;
}
# Recursively get the list of pod man page files.
sub getPodList {
my $poddir = shift;
my @files;
my $poddir = shift;
my @files;
# 1st get toplevel dir listing
opendir(DIR, $poddir) or die "Error: could not read $poddir.\n";
my @topdir = grep !/^\./, readdir(DIR); # /
close(DIR);
# 1st get toplevel dir listing
opendir(DIR, $poddir) or die "Error: could not read $poddir.\n";
my @topdir = grep !/^\./, readdir(DIR); # /
close(DIR);
# Now go thru each subdir (these are man1, man3, etc.)
foreach my $mandir (@topdir) {
opendir(DIR, "$poddir/$mandir") or die "Error: could not read $poddir/$mandir.\n";
my @dir = grep !/^\./, readdir(DIR); # /
close(DIR);
foreach my $file (@dir) {
push @files, "$poddir/$mandir/$file";
}
}
return sort @files;
# Now go thru each subdir (these are man1, man3, etc.)
foreach my $mandir (@topdir) {
opendir(DIR, "$poddir/$mandir") or die "Error: could not read $poddir/$mandir.\n";
my @dir = grep !/^\./, readdir(DIR); # /
close(DIR);
foreach my $file (@dir) {
push @files, "$poddir/$mandir/$file";
}
}
return sort @files;
}
# Create the xcat man page that gives a summary description of each xcat cmd.
# Not used.
sub writesummarypage {
my $file = shift; # relative path file name of the man page
# the rest of @_ contains the pod files that describe each cmd
my $file = shift; # relative path file name of the man page
# the rest of @_ contains the pod files that describe each cmd
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
print FILE <<'EOS1';
print FILE <<'EOS1';
=head1 NAME
B<xcat> - extreme Cluster Administration Tool.
@ -160,56 +169,58 @@ i.e. all the commands in section 1, then the commands in section 3, etc.
=over 12
EOS1
# extract the summary for each cmd from its man page
foreach my $manpage (@_) {
my ($sectionnum) = $manpage =~ /\.(\d+)\.pod$/;
# Suck in the whole file, then we will parse it.
open(MANPAGE, "$manpage") or die "Error: could not open $manpage for reading.\n";
my @contents = <MANPAGE>;
my $wholemanpage = join('', @contents);
close(MANPAGE);
# This regex matches: optional space, =head1, space, title, space, cmd, space, description, newline
my ($cmd, $description) = $wholemanpage =~ /^\s*=head1\s+\S+\s+(\S+)\s+(.+?)\n/si;
if (!defined($cmd)) { print "Warning: $manpage is not in a recognized structure. It will be ignored.\n"; next; }
if (!defined($description)) { print "Warning: $manpage does not have a description for $cmd. It will be ignored.\n"; next; }
$cmd =~ s/^.<(.+)>$/$1/; # if the cmd name has pod formatting around it, strip it off
$description =~ s/^-\s*//; # if the description has a leading hypen, strip it off
print FILE "\n=item L<$cmd($sectionnum)|$cmd.$sectionnum>\n\n".$description."\n";
}
# extract the summary for each cmd from its man page
foreach my $manpage (@_) {
my ($sectionnum) = $manpage =~ /\.(\d+)\.pod$/;
# Artificially add the xcattest cmd, because the xCAT-test rpm will add this
print FILE "\n=item L<xcattest(1)|xcattest.1>\n\nRun automated xCAT test cases.\n";
# Suck in the whole file, then we will parse it.
open(MANPAGE, "$manpage") or die "Error: could not open $manpage for reading.\n";
my @contents = <MANPAGE>;
my $wholemanpage = join('', @contents);
close(MANPAGE);
print FILE <<"EOS3";
# This regex matches: optional space, =head1, space, title, space, cmd, space, description, newline
my ($cmd, $description) = $wholemanpage =~ /^\s*=head1\s+\S+\s+(\S+)\s+(.+?)\n/si;
if (!defined($cmd)) { print "Warning: $manpage is not in a recognized structure. It will be ignored.\n"; next; }
if (!defined($description)) { print "Warning: $manpage does not have a description for $cmd. It will be ignored.\n"; next; }
$cmd =~ s/^.<(.+)>$/$1/; # if the cmd name has pod formatting around it, strip it off
$description =~ s/^-\s*//; # if the description has a leading hypen, strip it off
print FILE "\n=item L<$cmd($sectionnum)|$cmd.$sectionnum>\n\n" . $description . "\n";
}
# Artificially add the xcattest cmd, because the xCAT-test rpm will add this
print FILE "\n=item L<xcattest(1)|xcattest.1>\n\nRun automated xCAT test cases.\n";
print FILE <<"EOS3";
=back
EOS3
close FILE;
close FILE;
}
# Create the html page for one pod.
sub convertpod2html {
my ($podfile, $htmlfile, $poddir, $htmldir) = @_;
my ($podfile, $htmlfile, $poddir, $htmldir) = @_;
#TODO: use --css=<stylesheet> and --title=<pagetitle> to make the pages look better
pod2html($podfile,
"--outfile=$htmlfile",
"--podpath=man1",
"--podroot=$poddir",
"--htmldir=$htmldir",
"--recurse",
"--cachedir=$cachedir",
);
#TODO: use --css=<stylesheet> and --title=<pagetitle> to make the pages look better
pod2html($podfile,
"--outfile=$htmlfile",
"--podpath=man1",
"--podroot=$poddir",
"--htmldir=$htmldir",
"--recurse",
"--cachedir=$cachedir",
);
}
# Create the man page for one pod.
sub convertpod2man {
my ($podfile, $manfile, $section) = @_;
my ($podfile, $manfile, $section) = @_;
my $parser = Pod::Man->new(section => $section);
my $parser = Pod::Man->new(section => $section);
$parser->parse_from_file($podfile, $manfile);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +1,28 @@
#!/usr/bin/env perl
my $go=1;
my $go = 1;
my $file;
my $opts = "";
$file = pop @ARGV;
if (!$file) {
print "No device given, assuming /dev/cdrom.\n";
$file = "/dev/cdrom";
}
print "No device given, assuming /dev/cdrom.\n";
$file = "/dev/cdrom";
}
while ($go) {
$go = 0;
#print "copycds $opts $file";
system("copycds $opts $file");
print "Would you like to copy another CD (y/N)? ";
if (<STDIN> =~ /^y/i) {
$go = 1;
system("eject");
print "Replace the CD and press enter.";
<STDIN>;
}
$go = 0;
#print "copycds $opts $file";
system("copycds $opts $file");
print "Would you like to copy another CD (y/N)? ";
if (<STDIN> =~ /^y/i) {
$go = 1;
system("eject");
print "Replace the CD and press enter.";
<STDIN>;
}
}
# vim: set ts=2 sts=2 sw=2 et ai :

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,9 @@
BEGIN
{
$::XCATROOT =
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
}
use lib "$::XCATROOT/lib/perl";
use strict;
@ -19,16 +19,16 @@ use xCAT::TableUtils;
use File::Basename;
$::XCATROOT = "/opt/xcat";
my $os = "";
my $profile = "";
my $os = "";
my $profile = "";
my $interface = "";
my $version;
my $drivers = "";
my $drivers = "";
my $otherInterfaces = "";
my $kernel = "";
my @oses; # available OSes.
my @profiles; # available profiles
my $profDir; # root where you do ./genimage from
my $kernel = "";
my @oses; # available OSes.
my @profiles; # available profiles
my $profDir; # root where you do ./genimage from
my $help;
my $match = 0;
my $imagename;
@ -44,6 +44,7 @@ my $onlyinitrd;
my $dryrun;
my $ignorekernelchk;
my $noupdate;
#-----------------------------------------------------------------------------
=head3 print_usage - usage message
@ -56,7 +57,7 @@ sub print_usage
print "Usage:\n";
print " genimage\n\n";
print " genimage --dryrun\n\n";
print ' genimage [-o <osver>] [-a <arch>] [-p <profile>] [-i <nodebootif>] [-n <nodenetdrivers>] [--onlyinitrd] [-r <otherifaces>] [-k <kernelver>] [-g <krpmver>] [-m statelite] [-l rootlimitsize] [-t tmplimitsize] [--permission <permission>] [--interactive] [--dryrun] [--noupdate] <imagename>'."\n\n";
print ' genimage [-o <osver>] [-a <arch>] [-p <profile>] [-i <nodebootif>] [-n <nodenetdrivers>] [--onlyinitrd] [-r <otherifaces>] [-k <kernelver>] [-g <krpmver>] [-m statelite] [-l rootlimitsize] [-t tmplimitsize] [--permission <permission>] [--interactive] [--dryrun] [--noupdate] <imagename>' . "\n\n";
print " --permission is used for statelite only\n";
print " -g is used for SLES only\n\n";
print " -m is used for urbuntu, debian and fedora12 only\n\n";
@ -68,152 +69,156 @@ sub print_usage
}
if (!GetOptions(
'a=s' => \$arch,
'p=s' => \$profile,
'o=s' => \$os,
'n=s' => \$drivers,
'i=s' => \$interface,
'r=s' => \$otherInterfaces,
'l=s' => \$rootlimit,
't=s' => \$tmplimit,
'k=s' => \$kernel,
'g=s' => \$krpmver,
'm=s' => \$mode,
'permission=s' => \$permission,
'kerneldir=s' => \$kerneldir,
'interactive' => \$interactive,
'onlyinitrd' => \$onlyinitrd,
'dryrun' => \$dryrun,
'ignorekernelchk' => \$ignorekernelchk,
'noupdate' => \$noupdate,
'h|help' => \$help,
'v|version' => \$version,
)) {
&print_usage;
exit 1;
'a=s' => \$arch,
'p=s' => \$profile,
'o=s' => \$os,
'n=s' => \$drivers,
'i=s' => \$interface,
'r=s' => \$otherInterfaces,
'l=s' => \$rootlimit,
't=s' => \$tmplimit,
'k=s' => \$kernel,
'g=s' => \$krpmver,
'm=s' => \$mode,
'permission=s' => \$permission,
'kerneldir=s' => \$kerneldir,
'interactive' => \$interactive,
'onlyinitrd' => \$onlyinitrd,
'dryrun' => \$dryrun,
'ignorekernelchk' => \$ignorekernelchk,
'noupdate' => \$noupdate,
'h|help' => \$help,
'v|version' => \$version,
)) {
&print_usage;
exit 1;
}
if($help){
if ($help) {
&print_usage;
exit 0;
}
if ($version){
if ($version) {
my $version = xCAT::Utils->Version();
xCAT::MsgUtils->message("N", $version);
exit 0;
}
if (@ARGV > 0) {
$imagename=$ARGV[0];
$imagename = $ARGV[0];
}
if ((!$imagename) && (!$profile) && (!$os) && (!$arch)) {
my $tmpimgs=`lsdef -t osimage -w provmethod=~'/statelite|netboot/' |cut -d' ' -f1`;
my $tmpimgs = `lsdef -t osimage -w provmethod=~'/statelite|netboot/' |cut -d' ' -f1`;
if ($? == 0) {
if (($tmpimgs) && ($tmpimgs !~ /^Could/)) { #Could is returned when the osimage table is empty
my @images=split('\n', $tmpimgs);
print "Do you want to re-generate an existing image from the osimage table? ";
print "[y/n] ";
my $conf = <stdin>;
chomp($conf);
if($conf ne "" && $conf !~/N|n|[Nn][Oo]/) {
$match = 0;
while(1){
print "Available images: \n";
foreach(sort @images){
print " $_\n";
}
# default is the first image
print "Which image do you want to re-generate? [";
print $images[0];
print "] ";
my $img = <stdin>;
chomp($img);
if($img eq ""){
$imagename = $images[0];
last;
}
foreach(@images){
if($img eq $_){
$imagename=$img;
$match = 1;
}
}
if ($match) {
last;
} else {
print "$img is not found in the osimage table.\n";
}
}
}
}
if (($tmpimgs) && ($tmpimgs !~ /^Could/)) { #Could is returned when the osimage table is empty
my @images = split('\n', $tmpimgs);
print "Do you want to re-generate an existing image from the osimage table? ";
print "[y/n] ";
my $conf = <stdin>;
chomp($conf);
if ($conf ne "" && $conf !~ /N|n|[Nn][Oo]/) {
$match = 0;
while (1) {
print "Available images: \n";
foreach (sort @images) {
print " $_\n";
}
# default is the first image
print "Which image do you want to re-generate? [";
print $images[0];
print "] ";
my $img = <stdin>;
chomp($img);
if ($img eq "") {
$imagename = $images[0];
last;
}
foreach (@images) {
if ($img eq $_) {
$imagename = $img;
$match = 1;
}
}
if ($match) {
last;
} else {
print "$img is not found in the osimage table.\n";
}
}
}
}
}
}
# get the install directory
my @entries = xCAT::TableUtils->get_site_attribute("installdir");
my @entries = xCAT::TableUtils->get_site_attribute("installdir");
my $installdir = $entries[0];
chomp($installdir);
# lots of error checking to make sure it exists.
if($installdir eq ''){
if ($installdir eq '') {
print "Could not get install directory from site table. Assuming your OSes are stored in '/install'\n";
$installdir = "/install";
}
unless(-d $installdir){
unless (-d $installdir) {
print "The directory where your OS distributions resides: $installdir does not exist. Please check site table\n";
exit 1;
exit 1;
}
if ((!$imagename) && (!$os)){
if ((!$imagename) && (!$os)) {
my @dircontents = `ls $installdir`;
chomp(@dircontents);
foreach (@dircontents) {
# SL matches Scientific Linux, sl matches sles amd sled
if($_ =~ /(rhel|fedora|SL|centos|sl|suse)/){
push @oses,$_;
}
}
if($#oses eq -1){
print "There are no OS repositories in $installdir. Please run copycds for the OS first.\n";
exit 1;
# SL matches Scientific Linux, sl matches sles amd sled
if ($_ =~ /(rhel|fedora|SL|centos|sl|suse)/) {
push @oses, $_;
}
}
if ($#oses eq -1) {
print "There are no OS repositories in $installdir. Please run copycds for the OS first.\n";
exit 1;
}
# now they have the OSes, make sure they select one that is available
$match = 0;
while(1){
print "Available OSes: \n";
foreach(@oses){
print " $_\n";
}
# default is the first OS cause in many cases, they'll only have 1.
print "Which OS do you want to build a image for? [";
print $oses[0] ;
print "] ";
$os = <stdin>;
chomp($os);
if($os eq ""){
$os = $oses[0];
last;
}
foreach(@oses){
if($os eq $_){
$match = 1;
}
}
if($match){
last;
}else{
print "$os is not found in '$installdir'\n";
}
while (1) {
print "Available OSes: \n";
foreach (@oses) {
print " $_\n";
}
# default is the first OS cause in many cases, they'll only have 1.
print "Which OS do you want to build a image for? [";
print $oses[0];
print "] ";
$os = <stdin>;
chomp($os);
if ($os eq "") {
$os = $oses[0];
last;
}
foreach (@oses) {
if ($os eq $_) {
$match = 1;
}
}
if ($match) {
last;
} else {
print "$os is not found in '$installdir'\n";
}
}
chomp($os);
}
if ($os) { print " OS: $os\n"; }
@ -222,10 +227,10 @@ if ($os) { print " OS: $os\n"; }
### Get the Profile ####
my $osfamily = $os;
$osfamily =~ s/\d+//g;
$osfamily =~ s/\.//g;
if($osfamily =~ /rh/){
$osfamily = "rh";
$osfamily =~ s/\d+//g;
$osfamily =~ s/\.//g;
if ($osfamily =~ /rh/) {
$osfamily = "rh";
}
# OS version on s390x can contain 'sp', e.g. sles11sp1
@ -236,86 +241,87 @@ if ($osfamily =~ /sles/ && $osfamily =~ /sp/) {
#print "OSfamily: $osfamily\n";
$profDir = "$::XCATROOT/share/xcat/netboot/$osfamily";
unless(-d $profDir){
unless (-d $profDir) {
print "Unable to find genimage script in $profDir\n";
exit 1;
}
if ((!$imagename) && (!$profile)){
if ((!$imagename) && (!$profile)) {
my $profDir2 = "$installdir/custom/netboot/$osfamily";
my @proList = `ls $profDir/*.pkglist`;
my @proList = `ls $profDir/*.pkglist`;
if (-d $profDir2) {
@proList = (@proList, `ls $profDir2/*.pkglist`);
@proList = (@proList, `ls $profDir2/*.pkglist`);
}
my %seen = ();
foreach (@proList) {
my $f = basename($_);
$f =~ s/([^\.]*).*/$1/;
chomp($f);
$seen{$f}++;
}
my $f = basename($_);
$f =~ s/([^\.]*).*/$1/;
chomp($f);
$seen{$f}++;
}
@profiles = sort keys %seen;
if($#profiles eq -1){
print "There are no profiles in $::XCATROOT/share/xcat/netboot/$osfamily.\n";
exit 1;
if ($#profiles eq -1) {
print "There are no profiles in $::XCATROOT/share/xcat/netboot/$osfamily.\n";
exit 1;
}
$match = 0;
while(1){
print "Available Profiles for $os: \n";
foreach(@profiles){
print " $_\n";
}
# default is the first OS cause in many cases, they'll only have 1.
print "Which profile do you want to use for $os? [";
print "$profiles[0] ";
print "] ";
$profile = <stdin>;
chomp($profile);
if($profile eq ""){
$profile = $profiles[0];
last;
}
foreach(@profiles){
if($profile eq $_){
$match = 1;
}
}
if($match eq 1){
last;
}
while (1) {
print "Available Profiles for $os: \n";
foreach (@profiles) {
print " $_\n";
}
# default is the first OS cause in many cases, they'll only have 1.
print "Which profile do you want to use for $os? [";
print "$profiles[0] ";
print "] ";
$profile = <stdin>;
chomp($profile);
if ($profile eq "") {
$profile = $profiles[0];
last;
}
foreach (@profiles) {
if ($profile eq $_) {
$match = 1;
}
}
if ($match eq 1) {
last;
}
}
}
if ($profile) { print " Profile: $profile\n"; }
if ($profile) { print " Profile: $profile\n"; }
# get the interface
if ((!$imagename) && (!$interface)){
while(1){
print "OPTIONAL: Which specific network interface will the image boot from? [<blank>]";
$interface = <stdin>;
chomp($interface);
if($interface eq ""){
last;
}else{
print "You want your stateless machines to boot off of ";
print "$interface";
print "? ";
print "[Y/n] ";
my $conf = <stdin>;
chomp($conf);
if($conf eq ""){
last;
}
if($conf =~ /Y|y|[Yy][Ee][Ss]/){
last;
}
}
if ((!$imagename) && (!$interface)) {
while (1) {
print "OPTIONAL: Which specific network interface will the image boot from? [<blank>]";
$interface = <stdin>;
chomp($interface);
if ($interface eq "") {
last;
} else {
print "You want your stateless machines to boot off of ";
print "$interface";
print "? ";
print "[Y/n] ";
my $conf = <stdin>;
chomp($conf);
if ($conf eq "") {
last;
}
if ($conf =~ /Y|y|[Yy][Ee][Ss]/) {
last;
}
}
}
if ($interface) { print " Interface: $interface\n"; }
else { print " No interface specified. The interface will be determined at network boot time.\n"; }
else { print " No interface specified. The interface will be determined at network boot time.\n"; }
}
print "Generating image: \n";
my @arg;
@ -349,7 +355,7 @@ if ($kernel) {
push @arg, "$kernel";
}
if($otherInterfaces){
if ($otherInterfaces) {
push @arg, "-r";
push @arg, "$otherInterfaces";
}
@ -364,7 +370,7 @@ if ($rootlimit) {
push @arg, "$rootlimit";
}
if($tmplimit) {
if ($tmplimit) {
push @arg, "-t";
push @arg, "$tmplimit";
}
@ -384,8 +390,8 @@ if ($kerneldir) {
push @arg, "$kerneldir";
}
my $tempfile="/tmp/xcat_genimage.$$";
push @arg, "--tempfile"; #this is the file that contains the output
my $tempfile = "/tmp/xcat_genimage.$$";
push @arg, "--tempfile"; #this is the file that contains the output
push @arg, "$tempfile";
if ($interactive) {
@ -410,45 +416,47 @@ if ($noupdate) {
}
my $cmdref;
push (@{$cmdref->{arg}}, @arg);
$cmdref->{command}->[0] = "genimage";
push(@{ $cmdref->{arg} }, @arg);
$cmdref->{command}->[0] = "genimage";
if (!$interactive) {
xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response);
exit $xCAT::Client::EXITCODE;
} else {
if ($dryrun) { exit 0; }
#when in interactive mode, first call genimage.pm get info from DB,
#when in interactive mode, first call genimage.pm get info from DB,
xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response);
#then call the specific genimage under /opt/xcat/share...
if (-f $tempfile) {
my $cmdname;
#read the command name
open(FILE1, "<$tempfile");
my @output = <FILE1>;
if (@output >0) {
$cmdname=$output[0];
} else {
close FILE1;
return 1;
}
close FILE1;
my $cmdname;
# run the specific genimage command
#print "cmdname=$cmdname\n";
system("$cmdname");
#read the command name
open(FILE1, "<$tempfile");
my @output = <FILE1>;
if (@output > 0) {
$cmdname = $output[0];
} else {
close FILE1;
return 1;
}
close FILE1;
#then call genimage.pm to save the DB
my @arg1;
push @arg1, $tempfile;
my $request;
push (@{$request->{arg}}, @arg1);
$request->{command}->[0] = "saveimgdata";
xCAT::Client::submit_request($request, \&xCAT::Client::handle_response);
exit $xCAT::Client::EXITCODE;
# run the specific genimage command
#print "cmdname=$cmdname\n";
system("$cmdname");
#then call genimage.pm to save the DB
my @arg1;
push @arg1, $tempfile;
my $request;
push(@{ $request->{arg} }, @arg1);
$request->{command}->[0] = "saveimgdata";
xCAT::Client::submit_request($request, \&xCAT::Client::handle_response);
exit $xCAT::Client::EXITCODE;
} else {
exit 1;
exit 1;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -5,16 +5,16 @@
# Run asu64 or iflash64 utility out of band to multiple nodes, either sequentially or in parallel
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr';
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr';
}
my $iam = $0;
use strict;
close(STDIN);
open(STDIN,"<","/dev/null");
open(STDIN, "<", "/dev/null");
use lib "$::XCATROOT/lib/perl";
use IO::Socket::SSL;
use XML::Simple;
$XML::Simple::PREFERRED_PARSER='XML::Parser';
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
use Data::Dumper;
use IO::Handle;
use IO::Select;
@ -22,13 +22,14 @@ use xCAT::Utils;
use Getopt::Long;
use POSIX qw(:signal_h :errno_h :sys_wait_h);
use Thread qw(yield);
if ($iam =~ /pasu/) {
$::utilcmd = '/opt/lenovo/toolscenter/asu/asu64';
if (! -x $::utilcmd) {
$::utilcmd = '/opt/ibm/toolscenter/asu/asu64';
}
$::utilcmd = '/opt/lenovo/toolscenter/asu/asu64';
if (!-x $::utilcmd) {
$::utilcmd = '/opt/ibm/toolscenter/asu/asu64';
}
} elsif ($iam =~ /piflash/) {
$::utilcmd = '/opt/xcat/sbin/iflash64 --unattended';
$::utilcmd = '/opt/xcat/sbin/iflash64 --unattended';
}
my $interface;
my $username;
@ -39,64 +40,67 @@ my $help;
Getopt::Long::Configure("require_order");
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("no_pass_through");
if (!GetOptions(
"i|interface=s" => \$interface,
"p|passwd=s" => \$passwd,
'l|loginname=s' => \$username,
'f|fanout=i' => \$fanout,
'b|batch=s' => \$batchfile,
'r|retry' => \$::RETRY,
'd|donotfilter' => \$::DONOTFILTER,
"V|verbose" => \$::VERBOSE,
'h|help' => \$help,
) || $help || ($batchfile && scalar(@ARGV)!=1) || (!$batchfile && scalar(@ARGV)<2) ) {
print "Usage: $iam [-V] [-d] [-i <hostname-suffix>] [-l <user>] [-p <passwd>] [-f <fanout>] <noderange> <command>\n";
print " $iam [-V] [-d] [-i <hostname-suffix>] [-l <user>] [-p <passwd>] [-f <fanout>] -b <batchfile> <noderange>\n";
exit;
"i|interface=s" => \$interface,
"p|passwd=s" => \$passwd,
'l|loginname=s' => \$username,
'f|fanout=i' => \$fanout,
'b|batch=s' => \$batchfile,
'r|retry' => \$::RETRY,
'd|donotfilter' => \$::DONOTFILTER,
"V|verbose" => \$::VERBOSE,
'h|help' => \$help,
) || $help || ($batchfile && scalar(@ARGV) != 1) || (!$batchfile && scalar(@ARGV) < 2)) {
print "Usage: $iam [-V] [-d] [-i <hostname-suffix>] [-l <user>] [-p <passwd>] [-f <fanout>] <noderange> <command>\n";
print " $iam [-V] [-d] [-i <hostname-suffix>] [-l <user>] [-p <passwd>] [-f <fanout>] -b <batchfile> <noderange>\n";
exit;
}
my %nodehdl;
my $xcathost='localhost:3001';
my $pasumaxp = 64;
my $xcathost = 'localhost:3001';
my $pasumaxp = 64;
if ($ENV{XCATHOST}) {
$xcathost=$ENV{XCATHOST};
$xcathost = $ENV{XCATHOST};
}
if ($ENV{XCATPSHFANOUT}) {
$pasumaxp=$ENV{XCATPSHFANOUT};
if ($ENV{XCATPSHFANOUT}) {
$pasumaxp = $ENV{XCATPSHFANOUT};
}
if ($fanout) { # see if they overroad the fanout from the command line
$pasumaxp=$fanout;
if ($fanout) { # see if they overroad the fanout from the command line
$pasumaxp = $fanout;
}
my $noderange = shift @ARGV;
my @nodes=();
my @nodes = ();
#print "fanout=$fanout, username=$username, noderange=$noderange\n";
my $nodeattrs;
# do not need to do this call, because getting the ipmi atts will also give us a list of nodes
#@nodes = expandnoderange($noderange);
# this is reference to a hash, each key is the nodename and the value is a reference to a hash of attr values
$nodeattrs = getipmiattrs($noderange);
#print Dumper($nodeattrs);
#foreach my $k (keys(%$nodeattrs)) {
# print "$k:\n";
# my $subhash = $nodeattrs->{$k};
# foreach my $k2 (keys(%$subhash)) { print " $k2=", $subhash->{$k2}, "\n"; }
#}
#exit;
@nodes = keys(%$nodeattrs);
# do not need to do this call, because getting the ipmi atts will also give us a list of nodes
#@nodes = expandnoderange($noderange);
# this is reference to a hash, each key is the nodename and the value is a reference to a hash of attr values
$nodeattrs = getipmiattrs($noderange);
#print Dumper($nodeattrs);
#foreach my $k (keys(%$nodeattrs)) {
# print "$k:\n";
# my $subhash = $nodeattrs->{$k};
# foreach my $k2 (keys(%$subhash)) { print " $k2=", $subhash->{$k2}, "\n"; }
#}
#exit;
@nodes = keys(%$nodeattrs);
my $children = 0;
my $inputs = new IO::Select;
my %pids; # pid => node
my %exitcodes; # Keep a list of children with known exit codes
my $inputs = new IO::Select;
my %pids; # pid => node
my %exitcodes; # Keep a list of children with known exit codes
my %foundcodes;
my @retries; # the nodes that fail with connection error
if ($interface) {
foreach (@nodes) {
s/$/-$interface/;
}
foreach (@nodes) {
s/$/-$interface/;
}
}
# Fork the processes for running utility for each node
@ -105,60 +109,61 @@ if ($interface) {
# logic in just in case.
@retries = @nodes;
while (scalar(@retries)) {
@nodes = @retries;
@retries = ();
foreach (@nodes) {
my $node=$_;
my $ipmiattrs = $nodeattrs->{$node};
my $bmc = $ipmiattrs->{bmcaddr};
if (!defined($bmc)) {
print "$node: the ipmi.bmc attribute is not defined, skipping.\n";
next;
@nodes = @retries;
@retries = ();
foreach (@nodes) {
my $node = $_;
my $ipmiattrs = $nodeattrs->{$node};
my $bmc = $ipmiattrs->{bmcaddr};
if (!defined($bmc)) {
print "$node: the ipmi.bmc attribute is not defined, skipping.\n";
next;
}
# if we have already forked the max # of simultaneous processes, wait till 1 finishes
while ($children > $pasumaxp) { processoutput($inputs); }
# fork anothe process
my $child;
$children++;
# precedence on the username and password is: cli option, ipmi table, passwd table
my ($user, $pw);
if (defined($username)) { $user = $username; } # cli option
elsif (defined($ipmiattrs->{bmcuser})) { $user = $ipmiattrs->{bmcuser}; }
if (defined($passwd)) { $pw = $passwd; } # cli option
elsif (defined($ipmiattrs->{bmcpass})) { $pw = $ipmiattrs->{bmcpass}; }
if ($::VERBOSE) { print "For node $node using bmc=$bmc, user=$user, pw=$pw\n"; }
utilnode(\$child, $node, $bmc, $user, $pw, $batchfile, @ARGV); # child is the fd of the child process
$inputs->add($child);
$nodehdl{$child} = $node;
}
# if we have already forked the max # of simultaneous processes, wait till 1 finishes
while ($children > $pasumaxp) { processoutput($inputs); }
# fork anothe process
my $child;
$children++;
# precedence on the username and password is: cli option, ipmi table, passwd table
my ($user, $pw);
if (defined($username)) { $user = $username; } # cli option
elsif (defined($ipmiattrs->{bmcuser})) { $user = $ipmiattrs->{bmcuser}; }
if (defined($passwd)) { $pw = $passwd; } # cli option
elsif (defined($ipmiattrs->{bmcpass})) { $pw = $ipmiattrs->{bmcpass}; }
if ($::VERBOSE) { print "For node $node using bmc=$bmc, user=$user, pw=$pw\n"; }
utilnode(\$child,$node,$bmc,$user,$pw,$batchfile,@ARGV); # child is the fd of the child process
$inputs->add($child);
$nodehdl{$child} = $node;
}
# quiesce everything
while ($inputs->count) {
processoutput($inputs);
}
while (processoutput($inputs)) {};
while (wait != -1) {
yield;
}
# quiesce everything
while ($inputs->count) {
processoutput($inputs);
}
while (processoutput($inputs)) { }
while (wait != -1) {
yield;
}
}
my $exitcode=0;
my $exitcode = 0;
foreach (values %pids) {
my $possible_codes = join ",",keys %foundcodes;
my $possible_codes = join ",", keys %foundcodes;
unless (defined $exitcodes{$_}) {
print stderr "$_: *** $iam missed exit code, probably one of the following: $possible_codes\n";
}
}
foreach (keys %exitcodes) {
if ($exitcodes{$_}) {
print stderr "$_: *** $::utilcmd exited with error code ".$exitcodes{$_}.".\n";
print stderr "$_: *** $::utilcmd exited with error code " . $exitcodes{$_} . ".\n";
$exitcode++;
}
}
if ($exitcode) { #Exit code reflects number of failed nodes
$exitcode=$exitcode%256; #keep from overflowing valid values
if ($exitcode) { #Exit code reflects number of failed nodes
$exitcode = $exitcode % 256; #keep from overflowing valid values
unless ($exitcode) { #if number of failed nodes happened to be evenly divisible by 256, make it non-zero again
$exitcode++;
}
@ -166,177 +171,183 @@ if ($exitcode) { #Exit code reflects number of failed nodes
exit($exitcode);
# Process output on the select stmt from the forked cmds
sub processoutput { #This way, one arbiter handles output, no interrupting
my $inputs = shift; # the select object that contains all the file descriptors
my @readyins = $inputs->can_read(1); # child fds with some output available
my $rc = @readyins;
my $readyh;
foreach $readyh (@readyins) {
my $cursel = new IO::Select; # need to do non-blocking reads on this fd
$cursel->add($readyh);
while ($cursel->can_read(0)) {
my $line = <$readyh>;
unless ($line) {
$inputs->remove($readyh);
close($readyh);
$exitcodes{$nodehdl{$readyh}} = $? >> 8;
$children--;
next;
}
chomp($line);
if ($::RETRY && ($line =~ /Connection link error/i) ) {
if ($::VERBOSE) { print "Need to retry $nodehdl{$readyh}\n"; }
push @retries, $nodehdl{$readyh};
} elsif ($::DONOTFILTER || ($line!~/IBM Advanced Settings Utility version/i &&
$line!~/Lenovo Advanced Settings Utility version/i &&
$line!~/Licensed Materials - Property of IBM/i &&
$line!~/Licensed Materials - Property of Lenovo/i &&
$line!~/\(C\) Copyright IBM Corp. \d+-\d+ All Rights Reserved/i &&
$line!~/\(C\) Copyright Lenovo Corp. \d+-\d+ All Rights Reserved/i &&
$line!~/Connected to IMM at IP address/i )) {
print $nodehdl{$readyh}.": ".$line."\n";
}
sub processoutput { #This way, one arbiter handles output, no interrupting
my $inputs = shift; # the select object that contains all the file descriptors
my @readyins = $inputs->can_read(1); # child fds with some output available
my $rc = @readyins;
my $readyh;
foreach $readyh (@readyins) {
my $cursel = new IO::Select; # need to do non-blocking reads on this fd
$cursel->add($readyh);
while ($cursel->can_read(0)) {
my $line = <$readyh>;
unless ($line) {
$inputs->remove($readyh);
close($readyh);
$exitcodes{ $nodehdl{$readyh} } = $? >> 8;
$children--;
next;
}
chomp($line);
if ($::RETRY && ($line =~ /Connection link error/i)) {
if ($::VERBOSE) { print "Need to retry $nodehdl{$readyh}\n"; }
push @retries, $nodehdl{$readyh};
} elsif ($::DONOTFILTER || ($line !~ /IBM Advanced Settings Utility version/i &&
$line !~ /Lenovo Advanced Settings Utility version/i &&
$line !~ /Licensed Materials - Property of IBM/i &&
$line !~ /Licensed Materials - Property of Lenovo/i &&
$line !~ /\(C\) Copyright IBM Corp. \d+-\d+ All Rights Reserved/i &&
$line !~ /\(C\) Copyright Lenovo Corp. \d+-\d+ All Rights Reserved/i &&
$line !~ /Connected to IMM at IP address/i)) {
print $nodehdl{$readyh} . ": " . $line . "\n";
}
}
}
}
no strict 'subs';
IO::Handle::flush(stdout);
use strict 'subs';
yield; #Explicitly give all children a chance to refill any buffers
return $rc;
no strict 'subs';
IO::Handle::flush(stdout);
use strict 'subs';
yield; #Explicitly give all children a chance to refill any buffers
return $rc;
}
sub utilnode {
my $out = shift; # this is a reference to the child file descriptor
my $node = shift;
my $bmc = shift;
my $username = shift;
my $passwd = shift;
my $batchfile = shift;
my $args;
$bmc =~ s/,.*//;
if ($batchfile) {
$args = "batch $batchfile";
} else {
foreach my $a (@_) { $args .= ' ' . xCAT::Utils->quote($a); }
}
my $cmd = "$::utilcmd $args --host '$bmc' --user '$username' --password '$passwd' 2>&1 |";
if ($::VERBOSE) { print "forking $cmd\n"; }
my $pid = open($$out, $cmd);
$pids{$pid} = $node;
my $out = shift; # this is a reference to the child file descriptor
my $node = shift;
my $bmc = shift;
my $username = shift;
my $passwd = shift;
my $batchfile = shift;
my $args;
$bmc =~ s/,.*//;
if ($batchfile) {
$args = "batch $batchfile";
} else {
foreach my $a (@_) { $args .= ' ' . xCAT::Utils->quote($a); }
}
my $cmd = "$::utilcmd $args --host '$bmc' --user '$username' --password '$passwd' 2>&1 |";
if ($::VERBOSE) { print "forking $cmd\n"; }
my $pid = open($$out, $cmd);
$pids{$pid} = $node;
}
# Contact xcatd to expand the noderange into a list of nodes
sub expandnoderange {
my $noderange = shift @_;
my @nodes;
my @user = getpwuid($>);
my $homedir=$user[7];
my %sslargs;
if (defined($ENV{'XCATSSLVER'})) {
$sslargs{SSL_version} = $ENV{'XCATSSLVER'};
}
my $client = IO::Socket::SSL->new(
PeerAddr=>$xcathost,
SSL_key_file=>$homedir."/.xcat/client-cred.pem",
SSL_cert_file=>$homedir."/.xcat/client-cred.pem",
SSL_ca_file => $homedir."/.xcat/ca.pem",
SSL_use_cert => 1,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_verifycn_scheme => "none",
%sslargs,
);
die "Connection failure: $!\n" unless ($client);
#todo: get the bmc attr for each node, not the node name itself
my %cmdref = (command => 'noderange', noderange => $noderange);
$SIG{ALRM} = sub { die "No response getting noderange" };
alarm(15);
my $msg = XMLout(\%cmdref,RootName=>'xcatrequest', NoAttr=>1, KeyAttr => []);
if ($ENV{XCATXMLTRACE}) { print $msg; }
print $client $msg;
alarm(15);
my $response="";
while (<$client>) {
alarm(0);
$response .= $_;
if ($response =~ m/<\/xcatresponse>/) {
if ($ENV{XCATXMLTRACE}) { print $response; }
my $rsp=XMLin($response, ForceArray => ['node']);
$response='';
if ($rsp->{warning}) {
printf "Warning: ".$rsp->{warning}."\n";
}
if ($rsp->{error}) {
die ("ERROR: ".$rsp->{error}."\n");
} elsif ($rsp->{node}) {
@nodes=@{$rsp->{node}};
}
if ($rsp->{serverdone}) {
last;
}
my $noderange = shift @_;
my @nodes;
my @user = getpwuid($>);
my $homedir = $user[7];
my %sslargs;
if (defined($ENV{'XCATSSLVER'})) {
$sslargs{SSL_version} = $ENV{'XCATSSLVER'};
}
}
close($client);
if ($::VERBOSE) { print 'Nodes:', join(',',@nodes), "\n"; }
return @nodes;
my $client = IO::Socket::SSL->new(
PeerAddr => $xcathost,
SSL_key_file => $homedir . "/.xcat/client-cred.pem",
SSL_cert_file => $homedir . "/.xcat/client-cred.pem",
SSL_ca_file => $homedir . "/.xcat/ca.pem",
SSL_use_cert => 1,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_verifycn_scheme => "none",
%sslargs,
);
die "Connection failure: $!\n" unless ($client);
#todo: get the bmc attr for each node, not the node name itself
my %cmdref = (command => 'noderange', noderange => $noderange);
$SIG{ALRM} = sub { die "No response getting noderange" };
alarm(15);
my $msg = XMLout(\%cmdref, RootName => 'xcatrequest', NoAttr => 1, KeyAttr => []);
if ($ENV{XCATXMLTRACE}) { print $msg; }
print $client $msg;
alarm(15);
my $response = "";
while (<$client>) {
alarm(0);
$response .= $_;
if ($response =~ m/<\/xcatresponse>/) {
if ($ENV{XCATXMLTRACE}) { print $response; }
my $rsp = XMLin($response, ForceArray => ['node']);
$response = '';
if ($rsp->{warning}) {
printf "Warning: " . $rsp->{warning} . "\n";
}
if ($rsp->{error}) {
die("ERROR: " . $rsp->{error} . "\n");
} elsif ($rsp->{node}) {
@nodes = @{ $rsp->{node} };
}
if ($rsp->{serverdone}) {
last;
}
}
}
close($client);
if ($::VERBOSE) { print 'Nodes:', join(',', @nodes), "\n"; }
return @nodes;
}
# Contact xcatd to get from the ipmi table for this list of nodes: bmc, username, password
sub getipmiattrs {
my $noderange = shift @_;
my $nodeattrs = {}; # this will be a reference to a hash
my @user = getpwuid($>);
my $homedir=$user[7];
my %sslargs;
if (defined($ENV{'XCATSSLVER'})) {
$sslargs{SSL_version} = $ENV{'XCATSSLVER'};
}
my $client = IO::Socket::SSL->new(
PeerAddr=>$xcathost,
SSL_key_file=>$homedir."/.xcat/client-cred.pem",
SSL_cert_file=>$homedir."/.xcat/client-cred.pem",
SSL_ca_file => $homedir."/.xcat/ca.pem",
SSL_use_cert => 1,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_verifycn_scheme => "none",
%sslargs,
);
die "Connection failure: $!\n" unless ($client);
my %cmdref = (command => 'getipmicons', noderange => $noderange);
$SIG{ALRM} = sub { die "No response getting ipmi attributes" };
alarm(15);
my $msg = XMLout(\%cmdref,RootName=>'xcatrequest', NoAttr=>1, KeyAttr => []);
if ($ENV{XCATXMLTRACE}) { print $msg; }
print $client $msg;
alarm(15);
my $response="";
while (<$client>) {
alarm(0);
$response .= $_;
if ($response =~ m/<\/xcatresponse>/) {
if ($ENV{XCATXMLTRACE}) { print $response; }
my $rsp=XMLin($response, ForceArray => ['node']);
$response='';
if ($rsp->{warning}) {
printf "Warning: ".$rsp->{warning}."\n";
}
if ($rsp->{error}) {
die ("ERROR: ".$rsp->{error}."\n");
} elsif ($rsp->{node}) {
#print Dumper($rsp->{node});
foreach (keys %{$rsp->{node}}) {
$nodeattrs->{$_} = $rsp->{node}->{$_}; # this is reference to a hash, each key is the nodename and the value is a reference to a hash of attr values
}
}
if ($rsp->{serverdone}) {
last;
}
my $noderange = shift @_;
my $nodeattrs = {}; # this will be a reference to a hash
my @user = getpwuid($>);
my $homedir = $user[7];
my %sslargs;
if (defined($ENV{'XCATSSLVER'})) {
$sslargs{SSL_version} = $ENV{'XCATSSLVER'};
}
}
close($client);
#if ($::VERBOSE) { print 'Nodes:', join(',',$nodeattrs), "\n"; }
return $nodeattrs;
my $client = IO::Socket::SSL->new(
PeerAddr => $xcathost,
SSL_key_file => $homedir . "/.xcat/client-cred.pem",
SSL_cert_file => $homedir . "/.xcat/client-cred.pem",
SSL_ca_file => $homedir . "/.xcat/ca.pem",
SSL_use_cert => 1,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_verifycn_scheme => "none",
%sslargs,
);
die "Connection failure: $!\n" unless ($client);
my %cmdref = (command => 'getipmicons', noderange => $noderange);
$SIG{ALRM} = sub { die "No response getting ipmi attributes" };
alarm(15);
my $msg = XMLout(\%cmdref, RootName => 'xcatrequest', NoAttr => 1, KeyAttr => []);
if ($ENV{XCATXMLTRACE}) { print $msg; }
print $client $msg;
alarm(15);
my $response = "";
while (<$client>) {
alarm(0);
$response .= $_;
if ($response =~ m/<\/xcatresponse>/) {
if ($ENV{XCATXMLTRACE}) { print $response; }
my $rsp = XMLin($response, ForceArray => ['node']);
$response = '';
if ($rsp->{warning}) {
printf "Warning: " . $rsp->{warning} . "\n";
}
if ($rsp->{error}) {
die("ERROR: " . $rsp->{error} . "\n");
} elsif ($rsp->{node}) {
#print Dumper($rsp->{node});
foreach (keys %{ $rsp->{node} }) {
$nodeattrs->{$_} = $rsp->{node}->{$_}; # this is reference to a hash, each key is the nodename and the value is a reference to a hash of attr values
}
}
if ($rsp->{serverdone}) {
last;
}
}
}
close($client);
#if ($::VERBOSE) { print 'Nodes:', join(',',$nodeattrs), "\n"; }
return $nodeattrs;
}

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#Note, this pping still frontends fping. I think it would be possible to write a perl equivalent, but
#I've not had the time. Net::Ping shows perl code I could see being adapted for a somewhat
#asynchronous ICMP ping (the tcp syn is interesting, but far too limited, and that is currently the only async
#asynchronous ICMP ping (the tcp syn is interesting, but far too limited, and that is currently the only async
#method Net::Ping provides.
BEGIN
{
@ -16,36 +16,38 @@ use xCAT::TableUtils;
use POSIX qw(:signal_h :errno_h :sys_wait_h);
use IO::Socket::SSL;
use XML::Simple;
$XML::Simple::PREFERRED_PARSER='XML::Parser';
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
#use Data::Dumper;
use IO::Handle;
use IO::Select;
use Getopt::Long;
my $USAGE="Usage: pping [-i|--interface interfaces][-f|--use_fping] noderange
my $USAGE = "Usage: pping [-i|--interface interfaces][-f|--use_fping] noderange
pping -h|--help
pping -v|--version\n";
pping -v|--version\n";
my $interface;
# Parse the options
require Getopt::Long;
Getopt::Long::Configure ("bundling");
if(!GetOptions(
'f|use_fping' => \$::USE_FPING,
'h|help' => \$::HELP,
'v|version' => \$::VERSION,
'X|noexpand' => \$::NOEXPAND,
'i|interface=s' => \$interface))
{
print "$USAGE";
exit 1;
}
Getopt::Long::Configure("bundling");
if (!GetOptions(
'f|use_fping' => \$::USE_FPING,
'h|help' => \$::HELP,
'v|version' => \$::VERSION,
'X|noexpand' => \$::NOEXPAND,
'i|interface=s' => \$interface))
{
print "$USAGE";
exit 1;
}
if ($::HELP) { print "$USAGE"; exit 0}
if ($::VERSION) {print xCAT::Utils->Version() . "\n"; exit 0}
my $xcathost='localhost:3001';
if ($::HELP) { print "$USAGE"; exit 0 }
if ($::VERSION) { print xCAT::Utils->Version() . "\n"; exit 0 }
my $xcathost = 'localhost:3001';
if ($ENV{XCATHOST}) {
$xcathost=$ENV{XCATHOST};
$xcathost = $ENV{XCATHOST};
}
unless (@ARGV) {
@ -53,60 +55,61 @@ unless (@ARGV) {
exit(1);
}
my $noderange = $ARGV[0];
my @nodes=();
my $cmd="id -u";
my $userid = xCAT::Utils->runcmd("$cmd", -1);
my @nodes = ();
my $cmd = "id -u";
my $userid = xCAT::Utils->runcmd("$cmd", -1);
if ($::NOEXPAND) { # this is when ppping is calling us and has already expanded the noderange
@nodes = split(/,/, $noderange);
if ($::NOEXPAND) { # this is when ppping is calling us and has already expanded the noderange
@nodes = split(/,/, $noderange);
}
else { # the normal case of the user running the cmd - expand the noderange using xcatd
else { # the normal case of the user running the cmd - expand the noderange using xcatd
my %sslargs;
if (defined($ENV{'XCATSSLVER'})) {
$sslargs{SSL_version} = $ENV{'XCATSSLVER'};
}
my $client = IO::Socket::SSL->new(
PeerAddr=>$xcathost,
SSL_key_file=> xCAT::Utils->getHomeDir()."/.xcat/client-cred.pem",
SSL_cert_file=> xCAT::Utils->getHomeDir()."/.xcat/client-cred.pem",
SSL_ca_file => xCAT::Utils->getHomeDir()."/.xcat/ca.pem",
SSL_use_cert => 1,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_verifycn_scheme => "none",
%sslargs,
);
die "Connection failure: $!\n" unless ($client);
my %cmdref = (command => 'noderange', noderange => $noderange);
$SIG{ALRM} = sub { die "No response getting noderange" };
alarm(15);
print $client XMLout(\%cmdref,RootName=>'xcatrequest', NoAttr=>1, KeyAttr => []);
alarm(15);
my $response="";
while (<$client>) {
alarm(0);
$response .= $_;
if ($response =~ m/<\/xcatresponse>/) {
my $rsp=XMLin($response, ForceArray => ['node']);
$response='';
if ($rsp->{warning}) {
printf "Warning: ".$rsp->{warning}."\n";
}
if ($rsp->{error}) {
die ("ERROR: ".$rsp->{error}."\n");
} elsif ($rsp->{node}) {
@nodes=@{$rsp->{node}};
}
if ($rsp->{serverdone}) {
last;
}
}
}
close($client);
} # end of else that expands the noderange using xcatd
my $client = IO::Socket::SSL->new(
PeerAddr => $xcathost,
SSL_key_file => xCAT::Utils->getHomeDir() . "/.xcat/client-cred.pem",
SSL_cert_file => xCAT::Utils->getHomeDir() . "/.xcat/client-cred.pem",
SSL_ca_file => xCAT::Utils->getHomeDir() . "/.xcat/ca.pem",
SSL_use_cert => 1,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_verifycn_scheme => "none",
%sslargs,
);
die "Connection failure: $!\n" unless ($client);
my %cmdref = (command => 'noderange', noderange => $noderange);
$SIG{ALRM} = sub { die "No response getting noderange" };
alarm(15);
print $client XMLout(\%cmdref, RootName => 'xcatrequest', NoAttr => 1, KeyAttr => []);
alarm(15);
my $response = "";
while (<$client>) {
alarm(0);
$response .= $_;
if ($response =~ m/<\/xcatresponse>/) {
my $rsp = XMLin($response, ForceArray => ['node']);
$response = '';
if ($rsp->{warning}) {
printf "Warning: " . $rsp->{warning} . "\n";
}
if ($rsp->{error}) {
die("ERROR: " . $rsp->{error} . "\n");
} elsif ($rsp->{node}) {
@nodes = @{ $rsp->{node} };
}
if ($rsp->{serverdone}) {
last;
}
}
}
close($client);
} # end of else that expands the noderange using xcatd
unless (scalar(@nodes)) {
exit 1;
exit 1;
}
# I think this was only needed when we forked ping ourselves
@ -115,61 +118,62 @@ unless (scalar(@nodes)) {
#$SIG{CHLD} = sub { while (waitpid(-1,WNOHANG) > 0) { $children--; } };
my $usenmap = (-x '/usr/bin/nmap' or -x '/usr/local/bin/nmap');
if ($::USE_FPING) { # Use fping instead of nmap
$usenmap = 0;
if ($::USE_FPING) { # Use fping instead of nmap
$usenmap = 0;
}
my @interfaces;
if ($interface) { @interfaces = split(/,/, $interface); }
else { $interfaces[0] = ''; }
else { $interfaces[0] = ''; }
# Do the pings to the nodes for each interface in sequence. We could consider doing all the interfaces
# in parallel, but then the output would get all mixed up and be confusing for the user.
foreach my $interf (@interfaces) {
my $noderef;
if ($interf) {
# make a copy of the node list and add the interface on
$noderef = [ @nodes ];
foreach (@$noderef) {
s/-hf\d$//;
s/$/-$interf/;
}
}
else {
$noderef = \@nodes; # use the original node list
}
if ($usenmap) { nmap_pping($noderef); }
else { fping_pping($noderef); }
my $noderef;
if ($interf) {
# make a copy of the node list and add the interface on
$noderef = [@nodes];
foreach (@$noderef) {
s/-hf\d$//;
s/$/-$interf/;
}
}
else {
$noderef = \@nodes; # use the original node list
}
if ($usenmap) { nmap_pping($noderef); }
else { fping_pping($noderef); }
}
sub fping_pping {
my $nodes = shift;
my $master = xCAT::TableUtils->get_site_Master();
my $masterip = xCAT::NetworkUtils->getipaddr($master);
if ($masterip =~ /:/) #IPv6, needs fping6 support
my $nodes = shift;
my $master = xCAT::TableUtils->get_site_Master();
my $masterip = xCAT::NetworkUtils->getipaddr($master);
if ($masterip =~ /:/) #IPv6, needs fping6 support
{
if (!-x '/usr/bin/fping6')
{
if (!-x '/usr/bin/fping6')
{
print "fping6 is not availabe for IPv6 ping.\n";
exit 1;
}
open (FPING, "fping6 ".join(' ',@$nodes). " 2>&1 |") or die("Cannot open fping pipe: $!");
print "fping6 is not availabe for IPv6 ping.\n";
exit 1;
}
else
{
open (FPING, "fping ".join(' ',@$nodes). " 2>&1 |") or die("Cannot open fping pipe: $!");
open(FPING, "fping6 " . join(' ', @$nodes) . " 2>&1 |") or die("Cannot open fping pipe: $!");
}
else
{
open(FPING, "fping " . join(' ', @$nodes) . " 2>&1 |") or die("Cannot open fping pipe: $!");
}
while (<FPING>) {
if ($_ =~ /is unreachable/) {
s/ is unreachable/: noping/;
} elsif ($_ =~ /is alive/) {
s/ is alive/: ping/;
} elsif ($_ =~ /address not found/) {
s/ address not found/: noping/;
}
while (<FPING>) {
if ($_ =~ /is unreachable/) {
s/ is unreachable/: noping/;
} elsif ($_ =~ /is alive/) {
s/ is alive/: ping/;
} elsif ($_ =~ /address not found/) {
s/ address not found/: noping/;
}
print $_;
}
print $_;
}
}
sub nmap_pping {
@ -179,45 +183,46 @@ sub nmap_pping {
my $more_options;
my $tcmd;
foreach (@$nodes) {
$deadnodes{$_}=1;
$deadnodes{$_} = 1;
}
if ( $userid != 0 ) {
$tcmd ="tabdump site|grep nmapoptions|awk -F, '{print $2}'|sed -e 's/\"//g'|awk -F, '{print $1}'";
$more_options = xCAT::Utils->runcmd($tcmd, -1);
if ($userid != 0) {
$tcmd = "tabdump site|grep nmapoptions|awk -F, '{print $2}'|sed -e 's/\"//g'|awk -F, '{print $1}'";
$more_options = xCAT::Utils->runcmd($tcmd, -1);
} else {
# get additional options from site table
@nmap_options = xCAT::TableUtils->get_site_attribute("nmapoptions");
$more_options = $nmap_options[0];
}
open (FPING, "nmap -PE --system-dns --send-ip -sP $more_options ".join(' ',@$nodes). " 2> /dev/null|") or die("Cannot open nmap pipe: $!");
}
open(FPING, "nmap -PE --system-dns --send-ip -sP $more_options " . join(' ', @$nodes) . " 2> /dev/null|") or die("Cannot open nmap pipe: $!");
my $node;
while (<FPING>) {
if (/Host (.*) \(.*\) appears to be up/) {
$node=$1;
unless ($deadnodes{$node}) {
foreach (keys %deadnodes) {
if ($node =~ /^$_\./) {
$node = $_;
last;
}
}
}
delete $deadnodes{$node};
print "$node: ping\n" if ($node);
} elsif (/Nmap scan report for ([^ ]*) /) {
$node=$1;
} elsif (/Host is up./) {
unless ($deadnodes{$node}) {
foreach (keys %deadnodes) {
if ($node =~ /^$_\./) {
$node = $_;
last;
}
}
}
delete $deadnodes{$node};
print "$node: ping\n" if ($node);
}
if (/Host (.*) \(.*\) appears to be up/) {
$node = $1;
unless ($deadnodes{$node}) {
foreach (keys %deadnodes) {
if ($node =~ /^$_\./) {
$node = $_;
last;
}
}
}
delete $deadnodes{$node};
print "$node: ping\n" if ($node);
} elsif (/Nmap scan report for ([^ ]*) /) {
$node = $1;
} elsif (/Host is up./) {
unless ($deadnodes{$node}) {
foreach (keys %deadnodes) {
if ($node =~ /^$_\./) {
$node = $_;
last;
}
}
}
delete $deadnodes{$node};
print "$node: ping\n" if ($node);
}
}
foreach (sort keys %deadnodes) {
print "$_: noping\n";

View File

@ -2,7 +2,7 @@
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#Note, this ppping still frontends fping. I think it would be possible to write a perl equivalent, but
#I've not had the time. Net::Ping shows perl code I could see being adapted for a somewhat
#asynchronous ICMP ping (the tcp syn is interesting, but far too limited, and that is currently the only async
#asynchronous ICMP ping (the tcp syn is interesting, but far too limited, and that is currently the only async
#method Net::Ping provides.
# This script starts with a noderange from the user, expands it using the
@ -11,8 +11,8 @@
# obtained from the user. It then prints out the result and exits.
BEGIN
{
# XCATROOT must be set for this script to work
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
# XCATROOT must be set for this script to work
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use strict;
use lib "$::XCATROOT/lib/perl";
@ -22,60 +22,61 @@ use POSIX qw(:signal_h :errno_h :sys_wait_h);
use IO::Socket::SSL;
use XML::Simple;
if ($^O =~ /^linux/i) {
$XML::Simple::PREFERRED_PARSER='XML::Parser';
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
}
#use Data::Dumper;
use IO::Handle;
use IO::Select;
use Getopt::Long;
my $interface;
my $USAGE="Usage: ppping [-i|--interface interfaces] [-d|--debug] [-V|--verbose] [-q|--quiet] [-s|--serial] noderange
my $USAGE = "Usage: ppping [-i|--interface interfaces] [-d|--debug] [-V|--verbose] [-q|--quiet] [-s|--serial] noderange
ppping -h|--help
ppping -v|--version\n";
ppping -v|--version\n";
# Parse the options
require Getopt::Long;
Getopt::Long::Configure ("bundling");
if(!GetOptions(
'h|help' => \$::HELP,
'v|version' => \$::VERSION,
's|serial' => \$::SERIAL,
'd|debug' => \$::DEBUG,
'V|verbose' => \$::VERBOSE,
'H|hierarchical' => \$::HIERARCHY,
'q|quiet' => \$::QUIET,
'i|interface=s' => \$interface))
Getopt::Long::Configure("bundling");
if (!GetOptions(
'h|help' => \$::HELP,
'v|version' => \$::VERSION,
's|serial' => \$::SERIAL,
'd|debug' => \$::DEBUG,
'V|verbose' => \$::VERBOSE,
'H|hierarchical' => \$::HIERARCHY,
'q|quiet' => \$::QUIET,
'i|interface=s' => \$interface))
{
print "$USAGE";
exit 1;
print "$USAGE";
exit 1;
}
if ($::HELP) { print "$USAGE"; exit 0}
if ($::VERSION) {print xCAT::Utils->Version() . "\n"; exit 0}
if ($::HELP) { print "$USAGE"; exit 0 }
if ($::VERSION) { print xCAT::Utils->Version() . "\n"; exit 0 }
# A method to prefix and print debug information only if it is wanted.
sub debug {
my $debug_text = shift;
if($::DEBUG){
print("---$debug_text");
}
my $debug_text = shift;
if ($::DEBUG) {
print("---$debug_text");
}
}
my $xcathost='localhost:3001';
my $xcathost = 'localhost:3001';
if ($ENV{XCATHOST}) {
$xcathost=$ENV{XCATHOST};
$xcathost = $ENV{XCATHOST};
}
unless (@ARGV) {
print "$USAGE";
exit 1;
print "$USAGE";
exit 1;
}
## Connect to xcatd to expand a noderange
my $noderange = $ARGV[0];
my @user = getpwuid($>);
my $homedir=$user[7];
my @user = getpwuid($>);
my $homedir = $user[7];
my %sslargs;
if (defined($ENV{'XCATSSLVER'})) {
@ -83,86 +84,89 @@ if (defined($ENV{'XCATSSLVER'})) {
}
my $client = IO::Socket::SSL->new(
PeerAddr=>$xcathost,
SSL_key_file=>$homedir."/.xcat/client-cred.pem",
SSL_cert_file=>$homedir."/.xcat/client-cred.pem",
SSL_ca_file => $homedir."/.xcat/ca.pem",
SSL_use_cert => 1,
%sslargs,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_verifycn_scheme => "none",
);
PeerAddr => $xcathost,
SSL_key_file => $homedir . "/.xcat/client-cred.pem",
SSL_cert_file => $homedir . "/.xcat/client-cred.pem",
SSL_ca_file => $homedir . "/.xcat/ca.pem",
SSL_use_cert => 1,
%sslargs,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_verifycn_scheme => "none",
);
die "Connection failure: $!\n" unless ($client);
my %cmdref = (command => 'noderange', noderange => $noderange);
# Request nodes from xcatd
debug("[start] - request nodes from xcatd\n");
$SIG{ALRM} = sub { die "No response getting noderange" };
alarm(15);
print $client XMLout(\%cmdref,RootName=>'xcatrequest', NoAttr=>1, KeyAttr => []);
print $client XMLout(\%cmdref, RootName => 'xcatrequest', NoAttr => 1, KeyAttr => []);
alarm(15);
debug("[stop] - request nodes from xcatd\n");
## Recieve nodes from xcatd and place them in @nodes
my $response="";
my @nodes=();
my $response = "";
my @nodes = ();
debug("[start] - recieve nodes from xcatd\n");
while (<$client>) {
alarm(0);
$response .= $_;
if ($response =~ m/<\/xcatresponse>/) {
my $rsp=XMLin($response, ForceArray => ['node']);
$response='';
if ($rsp->{warning}) {
printf "Warning: ".$rsp->{warning}."\n";
alarm(0);
$response .= $_;
if ($response =~ m/<\/xcatresponse>/) {
my $rsp = XMLin($response, ForceArray => ['node']);
$response = '';
if ($rsp->{warning}) {
printf "Warning: " . $rsp->{warning} . "\n";
}
if ($rsp->{error}) {
die("ERROR: " . $rsp->{error} . "\n");
} elsif ($rsp->{node}) {
@nodes = @{ $rsp->{node} };
}
if ($rsp->{serverdone}) {
last;
}
}
if ($rsp->{error}) {
die ("ERROR: ".$rsp->{error}."\n");
} elsif ($rsp->{node}) {
@nodes=@{$rsp->{node}};
}
if ($rsp->{serverdone}) {
last;
}
}
}
close($client);
debug("[stop] - recieve nodes from xcatd\n");
debug("\@nodes LENGTH:" . scalar @nodes . "\n");
unless (scalar(@nodes)) {
exit 1;
exit 1;
}
my $children = 0;
my $inputs = new IO::Select;
$SIG{CHLD} = sub { while (waitpid(-1,WNOHANG) > 0) { $children--; } };
my $inputs = new IO::Select;
$SIG{CHLD} = sub { while (waitpid(-1, WNOHANG) > 0) { $children--; } };
## Use pping to determine which nodes are reachable
my @reachable_nodes=();
my @unreachable_nodes=();
my @reachable_nodes = ();
my @unreachable_nodes = ();
debug("[start] - find unreachable nodes\n");
my $cmd = "$::XCATROOT/bin/pping ".join(',',@nodes). " --noexpand 2>&1";
my $cmd = "$::XCATROOT/bin/pping " . join(',', @nodes) . " --noexpand 2>&1";
debug("Running '$cmd'\n");
open (PPING, "$cmd |") or die("Cannot open ppinginternal pipe: $!");
open(PPING, "$cmd |") or die("Cannot open ppinginternal pipe: $!");
while (<PPING>) {
if ($_ =~ / ping/) {
my @a_tmp=split(':', $_);
push(@reachable_nodes, $a_tmp[0]);
}
elsif ($_ =~ /noping/) {
my @a_tmp=split(':', $_);
push(@unreachable_nodes, $a_tmp[0]);
}
else { print $_; } # probably an error msg, so just echo it
if ($_ =~ / ping/) {
my @a_tmp = split(':', $_);
push(@reachable_nodes, $a_tmp[0]);
}
elsif ($_ =~ /noping/) {
my @a_tmp = split(':', $_);
push(@unreachable_nodes, $a_tmp[0]);
}
else { print $_; } # probably an error msg, so just echo it
}
close(PPING);
# this next line seems to always have a non-zero $?, even if pping succeeded...
#if ($?) { die "Error in the pping command used to first test the nodes (exit code=" . ($?>>8) . ").\n"; }
debug("[stop] - find unreachable nodes\n");
## Dispose of the unreachable nodes now
foreach(@unreachable_nodes) {
print "$_: noping\n";
foreach (@unreachable_nodes) {
print "$_: noping\n";
}
## If there are nodes in @reachable nodes, use xdsh to make each reachable
@ -172,57 +176,60 @@ debug("REACHABLE_NODES:@reachable_nodes\n");
if (@reachable_nodes == 0) { exit 1; }
my $allnodes=join(',', @nodes);
my $allnodes = join(',', @nodes);
# Note: even if verbose is not set, we still do not want to set the quiet flag because we want
# to count the pings that come back, unless they request fully quiet mode.
my $quiet = "";
if($::QUIET) { $quiet = "-q "; }
if ($::QUIET) { $quiet = "-q "; }
# bypass mode for xdsh is not used any more, because it doesn't give any advantage
my $bypass = "";
my @interfaces;
if ($interface) { @interfaces = split(/,/, $interface); }
else { $interfaces[0] = ''; }
else { $interfaces[0] = ''; }
# Possible todo: this loop runs xdsh pping2 for each interface. An optimization could be to send all
# the interfaces to pping2 at once. But this would mix up all the ping responses and making it
# harder to tell what is going on.
foreach my $interf (@interfaces) {
my $i_string = $interf ? "-i $interf " : '';
my $i_string = $interf ? "-i $interf " : '';
## If the serial option was set, pping2 one reachable node at a time.
if ($::SERIAL) {
debug("SERIAL:$::SERIAL\n");
debug("[start] - xdsh to each reachable node\n");
foreach(@reachable_nodes) {
my $command = "$::XCATROOT/bin/xdsh $_ $bypass -s -e $::XCATROOT/sbin/pping2 \"$i_string$quiet$allnodes\" 2>&1";
debug("Running '$command'\n");
open (PPING2, "$command |") or die("Cannot open xdsh internal pipe: $!");
# Print out the result
my %numpings;
while (<PPING2>) {
output($_, \%numpings, $interf);
}
close(PPING2);
## If the serial option was set, pping2 one reachable node at a time.
if ($::SERIAL) {
debug("SERIAL:$::SERIAL\n");
debug("[start] - xdsh to each reachable node\n");
foreach (@reachable_nodes) {
my $command = "$::XCATROOT/bin/xdsh $_ $bypass -s -e $::XCATROOT/sbin/pping2 \"$i_string$quiet$allnodes\" 2>&1";
debug("Running '$command'\n");
open(PPING2, "$command |") or die("Cannot open xdsh internal pipe: $!");
# Print out the result
my %numpings;
while (<PPING2>) {
output($_, \%numpings, $interf);
}
close(PPING2);
}
debug("[stop] - xdsh to each reachable node\n");
}
debug("[stop] - xdsh to each reachable node\n");
}
## If the serial option was not set, pping2 all the reachable nodes simultaneously.
else {
debug("SERIAL not set.\n");
my $node_string=join(',', @reachable_nodes);
my $command = "$::XCATROOT/bin/xdsh $node_string $bypass -s -e $::XCATROOT/sbin/pping2 \"$i_string$quiet$allnodes\" 2>&1";
debug("Running '$command'\n");
open (PPING2, "$command |") or die("Cannot open xdsh internal pipe: $!");
# Print out the result
my %numpings;
while (<PPING2>) {
output($_, \%numpings, $interf);
## If the serial option was not set, pping2 all the reachable nodes simultaneously.
else {
debug("SERIAL not set.\n");
my $node_string = join(',', @reachable_nodes);
my $command = "$::XCATROOT/bin/xdsh $node_string $bypass -s -e $::XCATROOT/sbin/pping2 \"$i_string$quiet$allnodes\" 2>&1";
debug("Running '$command'\n");
open(PPING2, "$command |") or die("Cannot open xdsh internal pipe: $!");
# Print out the result
my %numpings;
while (<PPING2>) {
output($_, \%numpings, $interf);
}
close(PPING2);
}
close(PPING2);
}
}
debug("[stop] - deal with reachable nodes\n");
@ -230,30 +237,31 @@ exit 0;
# Process the output if the xdsh pping2 commands
sub output {
my $line = shift;
my $numpings = shift;
my $interface = shift;
if ($line =~ /^\s*$/) { return; } # xdsh had a habit of adding an extra blank line in streaming mode
# In verbose mode we just echo everything. In quiet mode, the only thing that will come back
# from pping2 are the nopings, so we echo everything in that case too.
if ($::VERBOSE || $::QUIET) { print "$line"; return; }
# This is the default case in which pping2 will return both pings and nopings.
# We want to count the pings and display the nopings.
my $node;
if ( ($node) = $line =~ /^(\S+):.+:\s+ping$/) {
if (!($numpings->{$node}==-1)) {
$numpings->{$node}++;
# If we got pings for all the nodes then print success
if ($numpings->{$node} >= scalar(@nodes)) {
my $istr = $interface ? " on interface $interface" : '';
print "$node: pinged all nodes successfully$istr\n";
$numpings->{$node} = -1;
}
}
}
else {
print "$line";
if ( ($node) = $line =~ /^(\S+?):/) { $numpings->{$node} = -1; } # something beside ping, stop counting
}
my $line = shift;
my $numpings = shift;
my $interface = shift;
if ($line =~ /^\s*$/) { return; } # xdsh had a habit of adding an extra blank line in streaming mode
# In verbose mode we just echo everything. In quiet mode, the only thing that will come back
# from pping2 are the nopings, so we echo everything in that case too.
if ($::VERBOSE || $::QUIET) { print "$line"; return; }
# This is the default case in which pping2 will return both pings and nopings.
# We want to count the pings and display the nopings.
my $node;
if (($node) = $line =~ /^(\S+):.+:\s+ping$/) {
if (!($numpings->{$node} == -1)) {
$numpings->{$node}++;
# If we got pings for all the nodes then print success
if ($numpings->{$node} >= scalar(@nodes)) {
my $istr = $interface ? " on interface $interface" : '';
print "$node: pinged all nodes successfully$istr\n";
$numpings->{$node} = -1;
}
}
}
else {
print "$line";
if (($node) = $line =~ /^(\S+?):/) { $numpings->{$node} = -1; } # something beside ping, stop counting
}
}

View File

@ -7,7 +7,8 @@ BEGIN
use lib "$::XCATROOT/lib/perl";
use IO::Socket::SSL;
use XML::Simple;
$XML::Simple::PREFERRED_PARSER='XML::Parser';
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
#use Data::Dumper;
use IO::Handle;
use IO::Select;
@ -23,25 +24,25 @@ Getopt::Long::Configure("no_gnu_compat");
Getopt::Long::Configure("bundling");
my %nodehdl;
my $xcathost='localhost:3001';
my $xcathost = 'localhost:3001';
if ($ENV{XCATHOST}) {
$xcathost=$ENV{XCATHOST};
$xcathost = $ENV{XCATHOST};
}
if (!(@ARGV)) {
&usage;
exit(1);
&usage;
exit(1);
}
if (!GetOptions(
'h|help' => \$help,
'v|version' => \$version,
'o|options=s' => \$opts,
'f|fanout=s' => \$fanout,
'i|interface=s' => \$interface))
'h|help' => \$help,
'v|version' => \$version,
'o|options=s' => \$opts,
'f|fanout=s' => \$fanout,
'i|interface=s' => \$interface))
{
&usage;
exit(1);
&usage;
exit(1);
}
if ($help) {
&usage;
@ -52,125 +53,132 @@ if ($version) {
print "$version \n";
exit(0);
}
my $pshmaxp = 64;
my $pshmaxp = 64;
# determine fanout
if ($ENV{XCATPSHFANOUT}) {
$pshmaxp=$ENV{XCATPSHFANOUT};
if ($ENV{XCATPSHFANOUT}) {
$pshmaxp = $ENV{XCATPSHFANOUT};
}
if ($fanout) { # see if they overroad the fanout from the command line
$pshmaxp=$fanout;
if ($fanout) { # see if they overroad the fanout from the command line
$pshmaxp = $fanout;
}
(my $noderange,my $destloc) = split(/:/,$ARGV[1]);
my @user = getpwuid($>);
my $homedir=$user[7];
(my $noderange, my $destloc) = split(/:/, $ARGV[1]);
my @user = getpwuid($>);
my $homedir = $user[7];
my %sslargs;
if (defined($ENV{'XCATSSLVER'})) {
$sslargs{SSL_version} = $ENV{'XCATSSLVER'};
}
my $client = IO::Socket::SSL->new(
PeerAddr=>$xcathost,
SSL_key_file=>$homedir."/.xcat/client-cred.pem",
SSL_cert_file=>$homedir."/.xcat/client-cred.pem",
SSL_ca_file => $homedir."/.xcat/ca.pem",
SSL_use_cert => 1,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_verifycn_scheme => "none",
%sslargs,
);
PeerAddr => $xcathost,
SSL_key_file => $homedir . "/.xcat/client-cred.pem",
SSL_cert_file => $homedir . "/.xcat/client-cred.pem",
SSL_ca_file => $homedir . "/.xcat/ca.pem",
SSL_use_cert => 1,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_verifycn_scheme => "none",
%sslargs,
);
die "Connection failure: $!\n" unless ($client);
my %cmdref = (command => 'noderange', noderange => $noderange);
$SIG{ALRM} = sub { die "No response getting noderange" };
alarm(15);
print $client XMLout(\%cmdref,RootName=>'xcatrequest', NoAttr=>1, KeyAttr => []);
print $client XMLout(\%cmdref, RootName => 'xcatrequest', NoAttr => 1, KeyAttr => []);
alarm(15);
my $response="";
my @nodes=();
my $response = "";
my @nodes = ();
while (<$client>) {
alarm(0);
$response .= $_;
if ($response =~ m/<\/xcatresponse>/) {
$rsp=XMLin($response, ForceArray => ['node']);
$response='';
if ($rsp->{warning}) {
printf "Warning: ".$rsp->{warning}."\n";
alarm(0);
$response .= $_;
if ($response =~ m/<\/xcatresponse>/) {
$rsp = XMLin($response, ForceArray => ['node']);
$response = '';
if ($rsp->{warning}) {
printf "Warning: " . $rsp->{warning} . "\n";
}
if ($rsp->{error}) {
die("ERROR: " . $rsp->{error} . "\n");
} elsif ($rsp->{node}) {
@nodes = @{ $rsp->{node} };
}
if ($rsp->{serverdone}) {
last;
}
}
if ($rsp->{error}) {
die ("ERROR: ".$rsp->{error}."\n");
} elsif ($rsp->{node}) {
@nodes=@{$rsp->{node}};
}
if ($rsp->{serverdone}) {
last;
}
}
}
close($client);
my $children = 0;
my $inputs = new IO::Select;
my $inputs = new IO::Select;
$SIG{CHLD} = \&reaper;
sub reaper {
while (($pid = waitpid(-1,WNOHANG)) > 0) {
$children--;
}
if ($children and $pid == -1) { #for whatever reason, rsync processes slip by frequently
$children = 0;
}
$SIG{CHLD} = \&reaper;
while (($pid = waitpid(-1, WNOHANG)) > 0) {
$children--;
}
if ($children and $pid == -1) { #for whatever reason, rsync processes slip by frequently
$children = 0;
}
$SIG{CHLD} = \&reaper;
}
if ($interface) {
foreach (@nodes) {
s/$/-$interface/;
}
foreach (@nodes) {
s/$/-$interface/;
}
}
foreach (@nodes) {
my $node=$_;
while ($children > $pshmaxp) { processoutput($inputs); }
my $child;
$children++;
scpnode(\$child,$node,@ARGV[0],$destloc,$opts);
$inputs->add($child);
$nodehdl{$child} = $node;
my $node = $_;
while ($children > $pshmaxp) { processoutput($inputs); }
my $child;
$children++;
scpnode(\$child, $node, @ARGV[0], $destloc, $opts);
$inputs->add($child);
$nodehdl{$child} = $node;
}
while ($inputs->count and $children) {
processoutput($inputs);
processoutput($inputs);
}
while (processoutput($inputs)) {};
while (processoutput($inputs)) { }
wait;
exit(0);
sub processoutput { #This way, one arbiter handles output, no interrupting
my $inputs = shift;
my @readyins = $inputs->can_read(1);
my $rc = @readyins;
my $readyh;
foreach $readyh (@readyins) {
my $line = <$readyh>;
unless ($line) {
$inputs->remove($readyh);
print $nodehdl{$readyh}.": done\n";
close($readyh);
next;
sub processoutput { #This way, one arbiter handles output, no interrupting
my $inputs = shift;
my @readyins = $inputs->can_read(1);
my $rc = @readyins;
my $readyh;
foreach $readyh (@readyins) {
my $line = <$readyh>;
unless ($line) {
$inputs->remove($readyh);
print $nodehdl{$readyh} . ": done\n";
close($readyh);
next;
}
chomp($line);
print $nodehdl{$readyh} . ": " . $line . "\n";
}
chomp($line);
print $nodehdl{$readyh}.": ".$line."\n";
}
#yield;
return $rc;
#yield;
return $rc;
}
sub scpnode {
my $out = shift;
my $node = shift;
my $in;
#my $args = join(" ",@_);
my $file = shift;
my $dest = shift;
my $opts = shift;
my $cmd="rsync -az$opts $file $node:$dest 2>&1 |";
open($$out,"rsync -az$opts $file $node:$dest 2>&1 |");
my $out = shift;
my $node = shift;
my $in;
#my $args = join(" ",@_);
my $file = shift;
my $dest = shift;
my $opts = shift;
my $cmd = "rsync -az$opts $file $node:$dest 2>&1 |";
open($$out, "rsync -az$opts $file $node:$dest 2>&1 |");
}
sub usage {
print "Usage: prsync filename [filename ...] noderange:destinationdirectory\n";
print " prsync [-f fanout] [-o rsync options] [filename filename ...] [directory directory ...]";

View File

@ -8,7 +8,8 @@ use lib "$::XCATROOT/lib/perl";
use xCAT::Utils;
use IO::Socket::SSL;
use XML::Simple;
$XML::Simple::PREFERRED_PARSER='XML::Parser';
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
#use Data::Dumper;
use IO::Handle;
use IO::Select;
@ -17,31 +18,31 @@ use Getopt::Long qw(:config pass_through require_order);
use POSIX qw(:signal_h :errno_h :sys_wait_h);
my $interface;
GetOptions(
"interface=s" => \$interface,
"f|fanout=s" => \$fanout,
"h|help" => \$usage,
"v|version" => \$::VERSION,
);
"interface=s" => \$interface,
"f|fanout=s" => \$fanout,
"h|help" => \$usage,
"v|version" => \$::VERSION,
);
my %nodehdl;
my $xcathost='localhost:3001';
if ($::VERSION) {print xCAT::Utils->Version() . "\n"; exit 0}
my $xcathost = 'localhost:3001';
if ($::VERSION) { print xCAT::Utils->Version() . "\n"; exit 0 }
if ($ENV{XCATHOST}) {
$xcathost=$ENV{XCATHOST};
$xcathost = $ENV{XCATHOST};
}
sub usage
{
print $_[0];
print "Usage: pscp [ -f fanout] [-i <SUFFIX>] [SCP OPTIONS...] FILE... <NODERANGE>:<DESTINATION>\n";
exit 1;
print $_[0];
print "Usage: pscp [ -f fanout] [-i <SUFFIX>] [SCP OPTIONS...] FILE... <NODERANGE>:<DESTINATION>\n";
exit 1;
}
my $pshmaxp = 64;
if ($ENV{XCATPSHFANOUT}) {
$pshmaxp=$ENV{XCATPSHFANOUT};
my $pshmaxp = 64;
if ($ENV{XCATPSHFANOUT}) {
$pshmaxp = $ENV{XCATPSHFANOUT};
}
if ($fanout) { # see if they overroad the fanout from the command line
$pshmaxp=$fanout;
if ($fanout) { # see if they overroad the fanout from the command line
$pshmaxp = $fanout;
}
@ -51,113 +52,118 @@ my $dest = shift;
my @scpargs;
while (@ARGV)
{
push @scpargs, $dest;
$dest = shift;
push @scpargs, $dest;
$dest = shift;
}
my $noderange, $destloc;
if ($dest =~ /:/) { ($noderange, $destloc) = split(/:/, $dest); }
else { usage("No node range specified\n\n"); }
else { usage("No node range specified\n\n"); }
my @user = getpwuid($>);
my $homedir=$user[7];
my @user = getpwuid($>);
my $homedir = $user[7];
my %sslargs;
if (defined($ENV{'XCATSSLVER'})) {
$sslargs{SSL_version} = $ENV{'XCATSSLVER'};
}
my $client = IO::Socket::SSL->new(
PeerAddr=>$xcathost,
SSL_key_file=>$homedir."/.xcat/client-cred.pem",
SSL_cert_file=>$homedir."/.xcat/client-cred.pem",
SSL_ca_file => $homedir."/.xcat/ca.pem",
SSL_use_cert => 1,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_verifycn_scheme => "none",
%sslargs,
);
PeerAddr => $xcathost,
SSL_key_file => $homedir . "/.xcat/client-cred.pem",
SSL_cert_file => $homedir . "/.xcat/client-cred.pem",
SSL_ca_file => $homedir . "/.xcat/ca.pem",
SSL_use_cert => 1,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_verifycn_scheme => "none",
%sslargs,
);
die "Connection failure: $!\n" unless ($client);
my %cmdref = (command => 'noderange', noderange => $noderange);
$SIG{ALRM} = sub { die "No response getting noderange" };
alarm(15);
print $client XMLout(\%cmdref,RootName=>'xcatrequest', NoAttr=>1, KeyAttr => []);
print $client XMLout(\%cmdref, RootName => 'xcatrequest', NoAttr => 1, KeyAttr => []);
alarm(15);
my $response="";
my @nodes=();
my $response = "";
my @nodes = ();
while (<$client>) {
alarm(0);
$response .= $_;
if ($response =~ m/<\/xcatresponse>/) {
$rsp=XMLin($response, ForceArray => ['node']);
$response='';
if ($rsp->{warning}) {
printf "Warning: ".$rsp->{warning}."\n";
alarm(0);
$response .= $_;
if ($response =~ m/<\/xcatresponse>/) {
$rsp = XMLin($response, ForceArray => ['node']);
$response = '';
if ($rsp->{warning}) {
printf "Warning: " . $rsp->{warning} . "\n";
}
if ($rsp->{error}) {
die("ERROR: " . $rsp->{error} . "\n");
} elsif ($rsp->{node}) {
@nodes = @{ $rsp->{node} };
}
if ($rsp->{serverdone}) {
last;
}
}
if ($rsp->{error}) {
die ("ERROR: ".$rsp->{error}."\n");
} elsif ($rsp->{node}) {
@nodes=@{$rsp->{node}};
}
if ($rsp->{serverdone}) {
last;
}
}
}
close($client);
my $children = 0;
my $inputs = new IO::Select;
$SIG{CHLD} = sub { while (waitpid(-1,WNOHANG) > 0) { $children--; } };
my $inputs = new IO::Select;
$SIG{CHLD} = sub { while (waitpid(-1, WNOHANG) > 0) { $children--; } };
if ($interface) {
foreach (@nodes) {
s/$/-$interface/;
}
foreach (@nodes) {
s/$/-$interface/;
}
}
foreach (@nodes) {
my $node=$_;
while ($children > $pshmaxp) { processoutput($inputs); }
$children++;
#scpnode(\$child,$node,@ARGV[0],$destloc);
scpnode($inputs,\%nodehdl,$node,\@scpargs,$destloc);
my $node = $_;
while ($children > $pshmaxp) { processoutput($inputs); }
$children++;
#scpnode(\$child,$node,@ARGV[0],$destloc);
scpnode($inputs, \%nodehdl, $node, \@scpargs, $destloc);
}
while ($inputs->count and $children) {
processoutput($inputs);
processoutput($inputs);
}
while (processoutput($inputs)) {};
while (processoutput($inputs)) { }
wait;
exit(0);
sub processoutput { #This way, one arbiter handles output, no interrupting
my $inputs = shift;
my @readyins = $inputs->can_read(1);
my $rc = @readyins;
my $readyh;
foreach $readyh (@readyins) {
my $line = <$readyh>;
unless ($line) {
$inputs->remove($readyh);
print $nodehdl{$readyh}.": done\n";
close($readyh);
next;
sub processoutput { #This way, one arbiter handles output, no interrupting
my $inputs = shift;
my @readyins = $inputs->can_read(1);
my $rc = @readyins;
my $readyh;
foreach $readyh (@readyins) {
my $line = <$readyh>;
unless ($line) {
$inputs->remove($readyh);
print $nodehdl{$readyh} . ": done\n";
close($readyh);
next;
}
chomp($line);
print $nodehdl{$readyh} . ": " . $line . "\n";
}
chomp($line);
print $nodehdl{$readyh}.": ".$line."\n";
}
#yield;
return $rc;
#yield;
return $rc;
}
sub scpnode {
my $inputs = shift;
my $nodehdl = shift;
my $node = shift;
my $in;
#my $args = join(" ",@_);
#my $file = shift;
my $scpargsr = shift;
my @scpargs = @{$scpargsr};
my $dest = shift;
my $child;
open($child, "scp -o BatchMode=yes @scpargs $node:$dest 2>&1 |");
$inputs->add($child);
$nodehdl->{$child} = $node;
my $inputs = shift;
my $nodehdl = shift;
my $node = shift;
my $in;
#my $args = join(" ",@_);
#my $file = shift;
my $scpargsr = shift;
my @scpargs = @{$scpargsr};
my $dest = shift;
my $child;
open($child, "scp -o BatchMode=yes @scpargs $node:$dest 2>&1 |");
$inputs->add($child);
$nodehdl->{$child} = $node;
}
# vim: set et sw=2 ts=2 sts=2:

View File

@ -3,14 +3,15 @@
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr';
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr';
}
close(STDIN);
open(STDIN,"<","/dev/null");
open(STDIN, "<", "/dev/null");
use lib "$::XCATROOT/lib/perl";
use IO::Socket::SSL;
use XML::Simple;
$XML::Simple::PREFERRED_PARSER='XML::Parser';
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
#use Data::Dumper;
use xCAT::Utils;
use IO::Handle;
@ -21,198 +22,202 @@ use Thread qw(yield);
my $interface;
my $username;
my $help;
my $timeout=0;
my $timeout = 0;
Getopt::Long::Configure("require_order");
Getopt::Long::Configure("no_pass_through");
if (!GetOptions(
"i|interface=s" => \$interface,
'l|loginname=s' => \$username,
't|timeout=s' => \$timeout,
'f|fanout=s' => \$fanout,
"nonodecheck" => \$::NONODECHECK, #does not check the noderange, in this case, noderange need to be a list of nodes.
'h|help' => \$help,
"v|version" => \$::VERSION,
) || scalar(@ARGV)<2 ) {
if ($::VERSION) {print xCAT::Utils->Version() . "\n"; exit 0}
if ($help) {
print "Usage: psh [-i <interface>] [-l <user>] [-f <fanout>] [--nonodecheck] [-t <timeout value in seconds>] <noderange> <command>\n";
exit;
}
"i|interface=s" => \$interface,
'l|loginname=s' => \$username,
't|timeout=s' => \$timeout,
'f|fanout=s' => \$fanout,
"nonodecheck" => \$::NONODECHECK, #does not check the noderange, in this case, noderange need to be a list of nodes.
'h|help' => \$help,
"v|version" => \$::VERSION,
) || scalar(@ARGV) < 2) {
if ($::VERSION) { print xCAT::Utils->Version() . "\n"; exit 0 }
if ($help) {
print "Usage: psh [-i <interface>] [-l <user>] [-f <fanout>] [--nonodecheck] [-t <timeout value in seconds>] <noderange> <command>\n";
exit;
}
}
my %nodehdl;
my $xcathost='localhost:3001';
my $pshmaxp = 64;
my $xcathost = 'localhost:3001';
my $pshmaxp = 64;
if ($ENV{XCATHOST}) {
$xcathost=$ENV{XCATHOST};
$xcathost = $ENV{XCATHOST};
}
if ($ENV{XCATPSHFANOUT}) {
$pshmaxp=$ENV{XCATPSHFANOUT};
if ($ENV{XCATPSHFANOUT}) {
$pshmaxp = $ENV{XCATPSHFANOUT};
}
if ($fanout) { # see if they overroad the fanout from the command line
$pshmaxp=$fanout;
if ($fanout) { # see if they overroad the fanout from the command line
$pshmaxp = $fanout;
}
my $noderange = $ARGV[0];
my @nodes=();
my @nodes = ();
if ($::NONODECHECK) {
@nodes=split(/,/, $noderange);
@nodes = split(/,/, $noderange);
}
else {
my @user = getpwuid($>);
my $homedir=$user[7];
my %sslargs;
if (defined($ENV{'XCATSSLVER'})) {
$sslargs{SSL_version} = $ENV{'XCATSSLVER'};
}
my $client = IO::Socket::SSL->new(
PeerAddr=>$xcathost,
SSL_key_file=>$homedir."/.xcat/client-cred.pem",
SSL_cert_file=>$homedir."/.xcat/client-cred.pem",
SSL_ca_file => $homedir."/.xcat/ca.pem",
SSL_use_cert => 1,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_verifycn_scheme => "none",
%sslargs,
);
die "Connection failure: $!\n" unless ($client);
my %cmdref = (command => 'noderange', noderange => $noderange);
$SIG{ALRM} = sub { die "No response getting noderange" };
alarm(15);
print $client XMLout(\%cmdref,RootName=>'xcatrequest', NoAttr=>1, KeyAttr => []);
alarm(15);
my $response="";
while (<$client>) {
alarm(0);
$response .= $_;
if ($response =~ m/<\/xcatresponse>/) {
$rsp=XMLin($response, ForceArray => ['node']);
$response='';
if ($rsp->{warning}) {
printf "Warning: ".$rsp->{warning}."\n";
}
if ($rsp->{error}) {
die ("ERROR: ".$rsp->{error}."\n");
} elsif ($rsp->{node}) {
@nodes=@{$rsp->{node}};
}
if ($rsp->{serverdone}) {
last;
}
my @user = getpwuid($>);
my $homedir = $user[7];
my %sslargs;
if (defined($ENV{'XCATSSLVER'})) {
$sslargs{SSL_version} = $ENV{'XCATSSLVER'};
}
}
close($client);
my $client = IO::Socket::SSL->new(
PeerAddr => $xcathost,
SSL_key_file => $homedir . "/.xcat/client-cred.pem",
SSL_cert_file => $homedir . "/.xcat/client-cred.pem",
SSL_ca_file => $homedir . "/.xcat/ca.pem",
SSL_use_cert => 1,
SSL_verify_mode => SSL_VERIFY_PEER,
SSL_verifycn_scheme => "none",
%sslargs,
);
die "Connection failure: $!\n" unless ($client);
my %cmdref = (command => 'noderange', noderange => $noderange);
$SIG{ALRM} = sub { die "No response getting noderange" };
alarm(15);
print $client XMLout(\%cmdref, RootName => 'xcatrequest', NoAttr => 1, KeyAttr => []);
alarm(15);
my $response = "";
while (<$client>) {
alarm(0);
$response .= $_;
if ($response =~ m/<\/xcatresponse>/) {
$rsp = XMLin($response, ForceArray => ['node']);
$response = '';
if ($rsp->{warning}) {
printf "Warning: " . $rsp->{warning} . "\n";
}
if ($rsp->{error}) {
die("ERROR: " . $rsp->{error} . "\n");
} elsif ($rsp->{node}) {
@nodes = @{ $rsp->{node} };
}
if ($rsp->{serverdone}) {
last;
}
}
}
close($client);
}
my $children = 0;
my $inputs = new IO::Select;
my %pids; # pid => node
my %exitcodes; # Keep a list of children with known exit codes
my $inputs = new IO::Select;
my %pids; # pid => node
my %exitcodes; # Keep a list of children with known exit codes
my %foundcodes;
if ($interface) {
foreach (@nodes) {
s/$/-$interface/;
}
}
local $SIG{ALRM}= sub {
my @proclist = `ps -ef`;
my %ownedpids;
foreach (@proclist) {
m/\S+\s+(\S+)\s+(\S+)/;
$ownedpids{$2}=$1; #only recall one child per parent
}
foreach my $pid (keys %pids) {
my $node = $pids{$pid};
unless (defined $exitcodes{$node}) {
print stderr "$node: timeout exceeded\n";
if ($ownedpids{$pid}) {
kill 15,$ownedpids{$pid};
} else {
kill 15,$pid;
}
foreach (@nodes) {
s/$/-$interface/;
}
}
local $SIG{ALRM} = sub {
my @proclist = `ps -ef`;
my %ownedpids;
foreach (@proclist) {
m/\S+\s+(\S+)\s+(\S+)/;
$ownedpids{$2} = $1; #only recall one child per parent
}
foreach my $pid (keys %pids) {
my $node = $pids{$pid};
unless (defined $exitcodes{$node}) {
print stderr "$node: timeout exceeded\n";
if ($ownedpids{$pid}) {
kill 15, $ownedpids{$pid};
} else {
kill 15, $pid;
}
}
}
}
};
if ($timeout) { alarm($timeout); }
foreach (@nodes) {
my $node=$_;
while ($children >= $pshmaxp) { processoutput($inputs); }
$children++;
sshnode($inputs,\%nodehdl,$node,$username,@ARGV[1 .. $#ARGV]);
my $node = $_;
while ($children >= $pshmaxp) { processoutput($inputs); }
$children++;
sshnode($inputs, \%nodehdl, $node, $username, @ARGV[ 1 .. $#ARGV ]);
}
while ($inputs->count) {
processoutput($inputs);
processoutput($inputs);
}
while (processoutput($inputs)) {};
while (processoutput($inputs)) { }
while (wait != -1) {
yield;
yield;
}
my $exitcode=0;
my $exitcode = 0;
foreach (values %pids) {
my $possible_codes = join ",",keys %foundcodes;
my $possible_codes = join ",", keys %foundcodes;
unless (defined $exitcodes{$_}) {
print stderr "$_: *** psh missed exit code, probably one of the following: $possible_codes\n";
}
}
foreach (keys %exitcodes) {
if ($exitcodes{$_}) {
print stderr "$_: *** ssh exited with error code ".$exitcodes{$_}.".\n";
print stderr "$_: *** ssh exited with error code " . $exitcodes{$_} . ".\n";
$exitcode++;
}
}
if ($exitcode) { #Exit code reflects number of failed nodes
$exitcode=$exitcode%256; #keep from overflowing valid values
if ($exitcode) { #Exit code reflects number of failed nodes
$exitcode = $exitcode % 256; #keep from overflowing valid values
unless ($exitcode) { #if number of failed nodes happened to be evenly divisible by 256, make it non-zero again
$exitcode++;
}
}
exit($exitcode);
sub processoutput { #This way, one arbiter handles output, no interrupting
my $inputs = shift;
my @readyins = $inputs->can_read(1);
my $rc = @readyins;
my $readyh;
foreach $readyh (@readyins) {
my $cursel = new IO::Select;
$cursel->add($readyh);
while ($cursel->can_read(0)) {
my $line = <$readyh>;
unless ($line) {
$inputs->remove($readyh);
close($readyh);
$exitcodes{$nodehdl{$readyh}} = $? >> 8;
$children--;
next;
}
chomp($line);
print $nodehdl{$readyh}.": ".$line."\n";
sub processoutput { #This way, one arbiter handles output, no interrupting
my $inputs = shift;
my @readyins = $inputs->can_read(1);
my $rc = @readyins;
my $readyh;
foreach $readyh (@readyins) {
my $cursel = new IO::Select;
$cursel->add($readyh);
while ($cursel->can_read(0)) {
my $line = <$readyh>;
unless ($line) {
$inputs->remove($readyh);
close($readyh);
$exitcodes{ $nodehdl{$readyh} } = $? >> 8;
$children--;
next;
}
chomp($line);
print $nodehdl{$readyh} . ": " . $line . "\n";
}
}
}
IO::Handle::flush(stdout);
yield; #Explicitly give all children a chance to refill any buffers
return $rc;
IO::Handle::flush(stdout);
yield; #Explicitly give all children a chance to refill any buffers
return $rc;
}
sub sshnode {
my $inputs = shift;
my $nodehdl = shift;
my $node = shift;
my $username = shift;
my $out;
if (length($username)) { $username = "-l $username"; }
my $in;
my $args = join(" ",@_);
#print "ssh -o BatchMode=yes $username $node " . &quote($args) . " 2>&1 |\n";
my $pid = open($out,"ssh -o BatchMode=yes $username $node " . &quote($args) . " 2>&1 |");
$inputs->add($out);
$nodehdl->{$out} = $node;
$pids{$pid} = $node;
my $inputs = shift;
my $nodehdl = shift;
my $node = shift;
my $username = shift;
my $out;
if (length($username)) { $username = "-l $username"; }
my $in;
my $args = join(" ", @_);
#print "ssh -o BatchMode=yes $username $node " . &quote($args) . " 2>&1 |\n";
my $pid = open($out, "ssh -o BatchMode=yes $username $node " . &quote($args) . " 2>&1 |");
$inputs->add($out);
$nodehdl->{$out} = $node;
$pids{$pid} = $node;
}
sub quote
{
my $str = shift;
my $str = shift;
# if the value has imbedded double quotes, use single quotes. If it also has
# single quotes, escape the double quotes.

View File

@ -1,7 +1,7 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
# Used as a convience command combined of [nodech]-nodeset-rsetboot-rpower-[rcons/wcons]
# Used as a convience command combined of [nodech]-nodeset-rsetboot-rpower-[rcons/wcons]
# to make ease of node OS provision
# This is the client front-end to rinstall/winstall commands
@ -10,9 +10,9 @@
BEGIN
{
$::XCATROOT =
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
}
use lib "$::XCATROOT/lib/perl";
@ -28,60 +28,65 @@ use strict;
my $bname = basename($0);
my $cmdref;
$cmdref->{command}->[0] = $bname;
$cmdref->{cwd}->[0] = cwd();
$cmdref->{cwd}->[0] = cwd();
# allows our plugins to get the stdin of the cmd that invoked the plugin
my $data;
if ( (($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}) )
if ((($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}))
{
my $rin="";
my $rin = "";
my $rout;
vec($rin,fileno(STDIN),1)=1;
my $nfound=select($rout=$rin,"","",1);
vec($rin, fileno(STDIN), 1) = 1;
my $nfound = select($rout = $rin, "", "", 1);
if ($nfound)
{
while ( <STDIN> ) { $data.=$_; }
$cmdref->{stdin}->[0]=$data;
while (<STDIN>) { $data .= $_; }
$cmdref->{stdin}->[0] = $data;
}
}
else
{
if (-p STDIN) {
while ( <STDIN> ) { $data.=$_; }
$cmdref->{stdin}->[0]=$data;
while (<STDIN>) { $data .= $_; }
$cmdref->{stdin}->[0] = $data;
}
}
my $arg;
my @tmpargv = @ARGV;
# first
$arg=shift(@ARGV);
$arg = shift(@ARGV);
# first 1st non-hyphen arg is the noderange
while ($arg =~ /^-/) {
push (@{$cmdref->{arg}}, $arg);
$arg=shift(@ARGV);
push(@{ $cmdref->{arg} }, $arg);
$arg = shift(@ARGV);
}
$cmdref->{noderange}->[0]=$arg;
push (@{$cmdref->{arg}}, @ARGV);
$cmdref->{noderange}->[0] = $arg;
push(@{ $cmdref->{arg} }, @ARGV);
my $noderange=$cmdref->{noderange}->[0]; # save the noderange
my $noderange = $cmdref->{noderange}->[0]; # save the noderange
# ok call Client to run the plugin rinstall.pm
xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response);
xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response);
if ($xCAT::Client::EXITCODE == 0) # no errors
if ($xCAT::Client::EXITCODE == 0) # no errors
{
my $startconsole=$cmdref->{startconsole}->[0];
# if startconsole requested ( -c flag) for rinstall always for winstall
# This is set in the rinstall plugin
if ($startconsole == 1) {
if (basename($0) =~ /rinstall/) {
my $startconsole = $cmdref->{startconsole}->[0];
exec("rcons $noderange");
}
elsif (basename($0) =~ /winstall/) {
# winstall can commence a wcons command to the noderange for monitoring the provision cycle
# if startconsole requested ( -c flag) for rinstall always for winstall
# This is set in the rinstall plugin
if ($startconsole == 1) {
if (basename($0) =~ /rinstall/) {
exec("wcons $noderange");
exec("rcons $noderange");
}
elsif (basename($0) =~ /winstall/) {
# winstall can commence a wcons command to the noderange for monitoring the provision cycle
exec("wcons $noderange");
}
}
}
}
exit $xCAT::Client::EXITCODE;

View File

@ -22,26 +22,27 @@ sub updatenode_usage
my $bname = basename($0);
my $cmdref;
$cmdref->{command}->[0] = $bname;
$cmdref->{cwd}->[0] = cwd();
$cmdref->{cwd}->[0] = cwd();
my $data;
# allows our plugins to get the stdin of the cmd that invoked the plugin
if ( (($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}) )
if ((($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}))
{
my $rin="";
my $rin = "";
my $rout;
vec($rin,fileno(STDIN),1)=1;
my $nfound=select($rout=$rin,"","",1);
vec($rin, fileno(STDIN), 1) = 1;
my $nfound = select($rout = $rin, "", "", 1);
if ($nfound)
{
while ( <STDIN> ) { $data.=$_; }
$cmdref->{stdin}->[0]=$data;
while (<STDIN>) { $data .= $_; }
$cmdref->{stdin}->[0] = $data;
}
}
else
{
if (-p STDIN) {
while ( <STDIN> ) { $data.=$_; }
$cmdref->{stdin}->[0]=$data;
while (<STDIN>) { $data .= $_; }
$cmdref->{stdin}->[0] = $data;
}
}
@ -50,56 +51,58 @@ Getopt::Long::Configure("posix_default");
Getopt::Long::Configure("no_gnu_compat");
Getopt::Long::Configure("bundling");
my $tmp=" ".join(' ', @ARGV);
my $tmp = " " . join(' ', @ARGV);
if (!($tmp =~ / (--help|-h|-v|--version)/)) {
my $arg=shift(@ARGV);
# Set the noderange
if ($arg !~ /^-/) {
my @tempnr = ();
foreach my $nr (split(/,/, $arg)) {
if ($nr =~ /^\^(.*)$/) {
my $nrf = $1;
if ($nrf !~ /^\//) { #relative path
$nrf = Cwd::abs_path($nrf);
my $arg = shift(@ARGV);
# Set the noderange
if ($arg !~ /^-/) {
my @tempnr = ();
foreach my $nr (split(/,/, $arg)) {
if ($nr =~ /^\^(.*)$/) {
my $nrf = $1;
if ($nrf !~ /^\//) { #relative path
$nrf = Cwd::abs_path($nrf);
}
$nrf = "\^" . $nrf;
push @tempnr, $nrf;
} else {
push @tempnr, $nr;
}
}
$nrf = "\^" . $nrf;
push @tempnr, $nrf;
} else {
push @tempnr, $nr;
}
$arg = join(',', @tempnr);
$cmdref->{noderange}->[0] = $arg;
} else {
&updatenode_usage();
print "The noderange should be the first argument.\n";
exit 1;
}
$arg = join(',',@tempnr);
$cmdref->{noderange}->[0]=$arg;
} else {
&updatenode_usage();
print "The noderange should be the first argument.\n";
exit 1;
}
}
push (@{$cmdref->{arg}}, @ARGV);
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);
if (
!GetOptions(
'A|updateallsw' => \$ALLSW,
'c|cmdlineonly' => \$CMDLINE,
'd=s' => \$ALTSRC,
'h|help' => \$HELP,
'v|version' => \$VERSION,
'V|verbose' => \$VERBOSE,
'F|sync' => \$FILESYNC,
'g|genmypost' => \$GENMYPOST,
'f|snsync' => \$SNFILESYNC,
'l|user=s' => \$USER,
'S|sw' => \$SWMAINTENANCE,
's|sn' => \$SETSERVER,
'P|scripts:s' => \$RERUNPS,
'k|security' => \$SECURITY,
'o|os=s' => \$OS,
'fanout=i' => \$fanout,
't|timetout=i' => \$timeout,
'n|noverify' => \$NOVERIFY,
'A|updateallsw' => \$ALLSW,
'c|cmdlineonly' => \$CMDLINE,
'd=s' => \$ALTSRC,
'h|help' => \$HELP,
'v|version' => \$VERSION,
'V|verbose' => \$VERBOSE,
'F|sync' => \$FILESYNC,
'g|genmypost' => \$GENMYPOST,
'f|snsync' => \$SNFILESYNC,
'l|user=s' => \$USER,
'S|sw' => \$SWMAINTENANCE,
's|sn' => \$SETSERVER,
'P|scripts:s' => \$RERUNPS,
'k|security' => \$SECURITY,
'o|os=s' => \$OS,
'fanout=i' => \$fanout,
't|timetout=i' => \$timeout,
'n|noverify' => \$NOVERIFY,
)
) {
&updatenode_usage();
@ -131,29 +134,29 @@ if ($VERSION)
print "$version\n";
exit 0;
}
if (($FILESYNC) && ($SNFILESYNC)){ # only one
if (($FILESYNC) && ($SNFILESYNC)) { # only one
my $msg = "Choose either -f to sync the service nodes, or -F to sync the nodes not both.";
xCAT::MsgUtils->message("E", $msg);
exit 1;
}
if (($SECURITY) && (($SWMAINTENANCE) || defined($RERUNPS) || ($FILESYNC) || ($SNFILESYNC))){
}
if (($SECURITY) && (($SWMAINTENANCE) || defined($RERUNPS) || ($FILESYNC) || ($SNFILESYNC))) {
my $msg = "If you use the -k flag, you cannot specify the -S,-P,-f or -F flags.";
xCAT::MsgUtils->message("E", $msg);
exit 1;
}
if ($SNFILESYNC && ($SWMAINTENANCE || defined($RERUNPS) || $SECURITY || $FILESYNC)){
if ($SNFILESYNC && ($SWMAINTENANCE || defined($RERUNPS) || $SECURITY || $FILESYNC)) {
my $msg = "If you specify the -f flag you must not specify either the -S or -k or -P or -F flags";
xCAT::MsgUtils->message("E", $msg);
exit 1;
}
# determine who is running the command on the client and who we will run as
# determine who is running the command on the client and who we will run as
# on the node
my $current_userid = getpwuid($>);
$ENV{DSH_FROM_USERID} = $current_userid;
my $to_userid;
if ($USER) # entered -l
if ($USER) # entered -l
{
$to_userid = $USER;
}
@ -167,11 +170,11 @@ $ENV{DSH_TO_USERID} = $to_userid;
if ($SECURITY) {
my $msg;
if (!($ENV{'DSH_REMOTE_PASSWORD'}))
{ # if not already set
# prompt for the password for the userid on the node that will be setup
{ # if not already set
# prompt for the password for the userid on the node that will be setup
my $userpw;
$msg =
"The ssh keys will be updated for '$to_userid' on the node(s).\nPassword:";
"The ssh keys will be updated for '$to_userid' on the node(s).\nPassword:";
xCAT::MsgUtils->message("I", $msg);
system("stty -echo"); # turn off keyboard
chop($userpw = <STDIN>);
@ -193,9 +196,9 @@ if ($SECURITY) {
foreach (keys %ENV) {
if (/^DSH_/ || /^XCAT/) {
push @{$cmdref->{environment}}, "$_=$ENV{$_}";
push @{ $cmdref->{environment} }, "$_=$ENV{$_}";
}
}
xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response);
xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response);
exit $xCAT::Client::EXITCODE;

View File

@ -7,63 +7,67 @@ use IO::Socket::UNIX;
use Time::HiRes qw/sleep/;
use lib "$::XCATROOT/lib/perl";
use xCAT::Client;
#use Data::Dumper;
use strict;
unless ($ENV{DISPLAY}) {
print '$DISPLAY not set';
exit 1;
print '$DISPLAY not set';
exit 1;
}
my $mydir = dirname($0);
my $sb;
my $tilefact;
my $xrm="-xrm xterm.mainMenu.*.font:fixed -xrm xterm.vtMenu.*.font:fixed -xrm xterm.fontMenu.*.font:fixed -xrm xterm -xrm xterm.vt100.font6:grvga.737";
my $xrm = "-xrm xterm.mainMenu.*.font:fixed -xrm xterm.vtMenu.*.font:fixed -xrm xterm.fontMenu.*.font:fixed -xrm xterm -xrm xterm.vt100.font6:grvga.737";
my $font = "5x7";
my $sizegeometry;
GetOptions(
#'sb' => \$sb,
'tile|t:i' => \$tilefact,
'geometry|g:s' => \$sizegeometry,
#'font|f=s' => \$font
#'sb' => \$sb,
'tile|t:i' => \$tilefact,
'geometry|g:s' => \$sizegeometry,
#'font|f=s' => \$font
);
my $noderange = $ARGV[$#ARGV];
my %conserverref = (command => 'nodels', noderange => $noderange, arg => ['nodehm.conserver']);
my @nodes;
my %conservers;
sub getconserver {
my $rsp = shift;
foreach (@{$rsp->{node}}) {
my $node = $_->{name};
if (ref $node) { $node = $node->[0]; }
push @nodes,$node;
if ($_->{data}->[0]->{contents}) {
$conservers{$node}=$_->{data}->[0]->{contents};
if (ref $conservers{$node}) { $conservers{$node} = $conservers{$node}->[0] };
}
}
my $rsp = shift;
foreach (@{ $rsp->{node} }) {
my $node = $_->{name};
if (ref $node) { $node = $node->[0]; }
push @nodes, $node;
if ($_->{data}->[0]->{contents}) {
$conservers{$node} = $_->{data}->[0]->{contents};
if (ref $conservers{$node}) { $conservers{$node} = $conservers{$node}->[0] }
}
}
}
xCAT::Client::submit_request(\%conserverref,\&getconserver);
xCAT::Client::submit_request(\%conserverref, \&getconserver);
unless ($ARGV[$#ARGV]) {
print "Usage: wcons <options> <noderange>\n";
exit 1;
print "Usage: wcons <options> <noderange>\n";
exit 1;
}
pop @ARGV;
foreach (@nodes) {
if ($conservers{$_}) {
next;
}
if ($ENV{XCATHOST}) {
$conservers{$_} = $ENV{XCATHOST};
$conservers{$_} =~ s/:.*//;
next;
}
if ($conservers{$_}) {
next;
}
if ($ENV{XCATHOST}) {
$conservers{$_} = $ENV{XCATHOST};
$conservers{$_} =~ s/:.*//;
next;
}
}
my $firstnode = shift @nodes;
unless ($firstnode) {
exit 1;
exit 1;
}
my $currx;
my $curry;
@ -74,118 +78,120 @@ my $screenwidth;
my $screenheight;
my $window_width;
my $window_height;
my $panel_pad=0;
my $panel_pad = 0;
my $top_pad;
if (defined($tilefact)) {
my $rootinf = `xwininfo -root`;
foreach (split /\n/,$rootinf) {
if (/.*Width:\s+([0-9]*).*/) {
$screenwidth=$1;
} elsif (/.*Height:\s+([0-9]*).*/) {
$screenheight=$1;
}
}
$rootinf = `xwininfo -name "Top Panel" 2> /dev/null`;
foreach (split /\n/,$rootinf) {
if (/-geometry\s+([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+)/) {
if ($1 > 640 and $2 < 480 and $3 == 0 and $4 == 0) {
$panel_pad=$2;
}
}
}
if ($panel_pad == 0) {
$rootinf = `xwininfo -name "Top Expanded Edge Panel" 2> /dev/null`;
foreach (split /\n/,$rootinf) {
if (/-geometry\s+([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+)/) {
if ($1 > 640 and $2 < 480 and $3 == 0 and $4 == 0) {
$panel_pad=$2;
}
}
}
}
my $rootinf = `xwininfo -root`;
foreach (split /\n/, $rootinf) {
if (/.*Width:\s+([0-9]*).*/) {
$screenwidth = $1;
} elsif (/.*Height:\s+([0-9]*).*/) {
$screenheight = $1;
}
}
$rootinf = `xwininfo -name "Top Panel" 2> /dev/null`;
foreach (split /\n/, $rootinf) {
if (/-geometry\s+([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+)/) {
if ($1 > 640 and $2 < 480 and $3 == 0 and $4 == 0) {
$panel_pad = $2;
}
}
}
if ($panel_pad == 0) {
$rootinf = `xwininfo -name "Top Expanded Edge Panel" 2> /dev/null`;
foreach (split /\n/, $rootinf) {
if (/-geometry\s+([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+)/) {
if ($1 > 640 and $2 < 480 and $3 == 0 and $4 == 0) {
$panel_pad = $2;
}
}
}
}
$ENV{CONSCONTROLPATH} = "/tmp/wconscontrol.$firstnode.$$";
system("xterm $xrm -bg black -fg white -title $firstnode -n $firstnode -geometry $sizegeometry+0+0 ".join(" ",@ARGV)." -e /bin/bash -c \"/bin/true ".$ENV{DISPLAY}." $firstnode $firstnode & let SDATE=`date +%s`+5; $mydir/rcons $firstnode ".$conservers{$firstnode}."; if [ \\\$SDATE -gt \\`date +%s\\` ]; then echo Press enter to close; read SDATE; fi \" &");
$ENV{CONSCONTROLPATH} = "";
my $remainwait = 2;
if (-x "/opt/confluent/bin/confetty" or -x "/usr/bin/confetty" or -x "/usr/local/bin/confetty" ) {
$remainwait = 10;
}
while (not -S "/tmp/wconscontrol.$firstnode.$$" and $remainwait > 0) {
sleep(0.1);
$remainwait -= 0.1;
}
my $xinfo;
if (-S "/tmp/wconscontrol.$firstnode.$$") { # confluent mode
my $controlchannel = IO::Socket::UNIX->new(Type=>SOCK_STREAM(), Peer => "/tmp/wconscontrol.$firstnode.$$");
$ENV{CONSCONTROLPATH} = "/tmp/wconscontrol.$firstnode.$$";
system("xterm $xrm -bg black -fg white -title $firstnode -n $firstnode -geometry $sizegeometry+0+0 " . join(" ", @ARGV) . " -e /bin/bash -c \"/bin/true " . $ENV{DISPLAY} . " $firstnode $firstnode & let SDATE=`date +%s`+5; $mydir/rcons $firstnode " . $conservers{$firstnode} . "; if [ \\\$SDATE -gt \\`date +%s\\` ]; then echo Press enter to close; read SDATE; fi \" &");
$ENV{CONSCONTROLPATH} = "";
my $remainwait = 2;
if (-x "/opt/confluent/bin/confetty" or -x "/usr/bin/confetty" or -x "/usr/local/bin/confetty") {
$remainwait = 10;
}
while (not -S "/tmp/wconscontrol.$firstnode.$$" and $remainwait > 0) {
sleep(0.1);
$remainwait -= 0.1;
}
my $xinfo;
if (-S "/tmp/wconscontrol.$firstnode.$$") { # confluent mode
my $controlchannel = IO::Socket::UNIX->new(Type => SOCK_STREAM(), Peer => "/tmp/wconscontrol.$firstnode.$$");
print $controlchannel "GETWINID\n";
my $winid = <$controlchannel>;
$winid = <$controlchannel>;
$xinfo = `xwininfo -id $winid`;
} else {
$xinfo = `xwininfo -name $firstnode`;
}
$xinfo = `xwininfo -id $winid`;
} else {
$xinfo = `xwininfo -name $firstnode`;
}
my @xinfl = split(/\n/,$xinfo);
my $side_pad;
my $wmxo;
my $wmyo;
foreach (@xinfl) {
if (/.*Absolute upper-left X:\s*([0-9]*).*/) {
$side_pad = $1;
} elsif (/.*Absolute upper-left Y:\s*([0-9]*).*/) {
$top_pad = $1-$panel_pad;
} elsif (/.*Width:\s*([0-9]*).*/) {
$window_width = $1;
} elsif (/.*Height:\s*([0-9]*).*/) {
$window_height = $1;
} elsif (/.*-gemotery \d+x\d+\+(\d+)(\d+)/) {
$wmxo=$1;
$wmyo=$2;
}
}
$window_width += $side_pad*2; #add the side border, assuming symmetric left and right borders
$window_height += $side_pad+$top_pad; #Add the titlebar and bottom border, which is guessed to probably be equal to the sides, doesn't hold true in all cases, i.e. window maker, but it's the currently best approximation
$screenwidth-=$wmxo; #Subtract a factor that 1.3 did, not sure why precisely
$screenheight-=$wmyo;
$currx=$window_width;
$curry=$panel_pad; #+$top_pad;
my $maxcol = int($screenwidth/$window_width);
unless ($tilefact or $tilefact > $maxcol) {
$tilefact=$maxcol;
}
if ($tilefact==1) {
$curry+=$window_height;
$currx=0;
}
my @xinfl = split(/\n/, $xinfo);
my $side_pad;
my $wmxo;
my $wmyo;
foreach (@xinfl) {
if (/.*Absolute upper-left X:\s*([0-9]*).*/) {
$side_pad = $1;
} elsif (/.*Absolute upper-left Y:\s*([0-9]*).*/) {
$top_pad = $1 - $panel_pad;
} elsif (/.*Width:\s*([0-9]*).*/) {
$window_width = $1;
} elsif (/.*Height:\s*([0-9]*).*/) {
$window_height = $1;
} elsif (/.*-gemotery \d+x\d+\+(\d+)(\d+)/) {
$wmxo = $1;
$wmyo = $2;
}
}
$window_width += $side_pad * 2; #add the side border, assuming symmetric left and right borders
$window_height += $side_pad + $top_pad; #Add the titlebar and bottom border, which is guessed to probably be equal to the sides, doesn't hold true in all cases, i.e. window maker, but it's the currently best approximation
$screenwidth -= $wmxo; #Subtract a factor that 1.3 did, not sure why precisely
$screenheight -= $wmyo;
$currx = $window_width;
$curry = $panel_pad; #+$top_pad;
my $maxcol = int($screenwidth / $window_width);
unless ($tilefact or $tilefact > $maxcol) {
$tilefact = $maxcol;
}
if ($tilefact == 1) {
$curry += $window_height;
$currx = 0;
}
} else {
my $geo;
if ($sizegeometry) {
$geo = "-g $sizegeometry ";
}
system("xterm $xrm $geo-bg black -fg white -title $firstnode -n $firstnode ".join(" ",@ARGV)." -e /bin/bash -c \"$mydir/xtcd.pl ".$ENV{DISPLAY}." $firstnode $firstnode & let SDATE=`date +%s`+5; $mydir/rcons $firstnode ".$conservers{$firstnode}."; if [ \\\$SDATE -gt \\`date +%s\\` ]; then echo Press enter to close; read SDATE; fi\" &");
my $geo;
if ($sizegeometry) {
$geo = "-g $sizegeometry ";
}
system("xterm $xrm $geo-bg black -fg white -title $firstnode -n $firstnode " . join(" ", @ARGV) . " -e /bin/bash -c \"$mydir/xtcd.pl " . $ENV{DISPLAY} . " $firstnode $firstnode & let SDATE=`date +%s`+5; $mydir/rcons $firstnode " . $conservers{$firstnode} . "; if [ \\\$SDATE -gt \\`date +%s\\` ]; then echo Press enter to close; read SDATE; fi\" &");
}
my $geometry="";
my $geometry = "";
foreach (@nodes) {
if ($tilefact) {
my $corrected_x=$currx+$wmxo;
my $corrected_y=$curry+$wmyo;
$geometry="-geometry $sizegeometry+$corrected_x+$corrected_y";
$currx+=$window_width;
if ($currx >= ($tilefact * $window_width)) {
$currx=0;
$curry+=$window_height;
if (($curry+$window_height) > $screenheight) {
$curry = $panel_pad; #+$top_pad;
}
}
} elsif ($sizegeometry) {
$geometry = "-geometry $sizegeometry";
}
if ($tilefact) {
my $corrected_x = $currx + $wmxo;
my $corrected_y = $curry + $wmyo;
$geometry = "-geometry $sizegeometry+$corrected_x+$corrected_y";
$currx += $window_width;
if ($currx >= ($tilefact * $window_width)) {
$currx = 0;
$curry += $window_height;
if (($curry + $window_height) > $screenheight) {
$curry = $panel_pad; #+$top_pad;
}
}
} elsif ($sizegeometry) {
$geometry = "-geometry $sizegeometry";
}
system("xterm $xrm -bg black -fg white ".join(" ",@ARGV)." -title $_ -n $_ $geometry -e /bin/bash -c \"$mydir/xtcd.pl .".$ENV{DISPLAY}." $_ $_ & let SDATE=`date +%s`+5; $mydir/rcons $_ ".$conservers{$_}."; if [ \\\$SDATE -gt \\`date +%s\\` ]; then echo Press enter to close; read SDATE; fi\" &");
system("xterm $xrm -bg black -fg white " . join(" ", @ARGV) . " -title $_ -n $_ $geometry -e /bin/bash -c \"$mydir/xtcd.pl ." . $ENV{DISPLAY} . " $_ $_ & let SDATE=`date +%s`+5; $mydir/rcons $_ " . $conservers{$_} . "; if [ \\\$SDATE -gt \\`date +%s\\` ]; then echo Press enter to close; read SDATE; fi\" &");
}

View File

@ -4,6 +4,7 @@
BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; }
use lib "$::XCATROOT/lib/perl";
use Cwd;
#use IO::Socket::SSL;
#use IO::Socket::INET;
my %rvidhash;
@ -13,16 +14,17 @@ unless ($xcatroot) {
}
use File::Basename;
use xCAT::Client;
#use Data::Dumper;
sub process_response {
my $resp = shift;
foreach my $rst (\@{$resp->{node}}) {
foreach my $rst (\@{ $resp->{node} }) {
foreach my $rsp (@$rst) {
if ($rsp->{errorcode} and (not ref $rsp->{errorcode} or $rsp->{errorcode}->[0])) {
print $rsp->{name}->[0].": Error: ".$rsp->{error}->[0]."\n";
} else {
$rvidhash{$rsp->{name}->[0]}->{$rsp->{data}->[0]->{desc}->[0]} = $rsp->{data}->[0]->{contents}->[0];
}
if ($rsp->{errorcode} and (not ref $rsp->{errorcode} or $rsp->{errorcode}->[0])) {
print $rsp->{name}->[0] . ": Error: " . $rsp->{error}->[0] . "\n";
} else {
$rvidhash{ $rsp->{name}->[0] }->{ $rsp->{data}->[0]->{desc}->[0] } = $rsp->{data}->[0]->{contents}->[0];
}
}
}
}
@ -31,23 +33,23 @@ my $cmdref;
$cmdref->{command}->[0] = 'getrvidparms';
# Consider the 1st non-hyphen arg to be the noderange. All others (before and after) go on the arg list.
my $arg=shift(@ARGV);
my $arg = shift(@ARGV);
while ($arg =~ /^-/) {
push (@{$cmdref->{arg}}, $arg);
$arg=shift(@ARGV);
push(@{ $cmdref->{arg} }, $arg);
$arg = shift(@ARGV);
}
if ($arg ne "NO_NODE_RANGE") {
$cmdref->{noderange}->[0]=$arg;
$cmdref->{noderange}->[0] = $arg;
}
push (@{$cmdref->{arg}}, @ARGV);
push(@{ $cmdref->{arg} }, @ARGV);
xCAT::Client::submit_request($cmdref,\&process_response);
my %CLEANENV=%ENV;
xCAT::Client::submit_request($cmdref, \&process_response);
my %CLEANENV = %ENV;
foreach my $node (keys %rvidhash) {
%ENV=%CLEANENV;
foreach my $var (keys %{$rvidhash{$node}}) {
$ENV{"rvid_$var"}=$rvidhash{$node}->{$var};
%ENV = %CLEANENV;
foreach my $var (keys %{ $rvidhash{$node} }) {
$ENV{"rvid_$var"} = $rvidhash{$node}->{$var};
}
system("$xcatroot/share/xcat/rvid/rvid.".$ENV{"rvid_method"}." &");
system("$xcatroot/share/xcat/rvid/rvid." . $ENV{"rvid_method"} . " &");
}
exit $xCAT::Client::EXITCODE;

View File

@ -52,32 +52,34 @@ else
}
$cmdref->{cwd}->[0] = cwd();
# get info from files piped in as stdin
my $data;
if ( (($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}) )
if ((($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}))
{
my $rout;
my $rin="";
vec($rin,fileno(STDIN),1)=1;
my $nfound=select($rout=$rin,"","",1);
my $rin = "";
vec($rin, fileno(STDIN), 1) = 1;
my $nfound = select($rout = $rin, "", "", 1);
if ($nfound)
{
while ( <STDIN> ) { $data.=$_; }
$cmdref->{stdin}->[0]=$data;
while (<STDIN>) { $data .= $_; }
$cmdref->{stdin}->[0] = $data;
}
}
else
{
if (-p STDIN) {
while ( <STDIN> ) { $data.=$_; }
$cmdref->{stdin}->[0]=$data;
while (<STDIN>) { $data .= $_; }
$cmdref->{stdin}->[0] = $data;
}
}
# The noderange can be specified through a noderange file
# the noderange file can be a relative path,
# convert the relative path to a full path.
my @tmpargv = ();
my @tmpv = @ARGV;
my @tmpv = @ARGV;
foreach my $a (@tmpv)
{
if (!($a =~ /=/) && !($a =~ /^-/)) {
@ -85,17 +87,17 @@ foreach my $a (@tmpv)
foreach my $nr (split(/,/, $a)) {
if ($nr =~ /^\^(.*)$/) {
my $nrf = $1;
if ($nrf !~ /^\//) { #relative path
$nrf = Cwd::abs_path($nrf);
}
if ($nrf !~ /^\//) { #relative path
$nrf = Cwd::abs_path($nrf);
}
$nrf = "\^" . $nrf;
push @tempnr, $nrf;
} else {
push @tempnr, $nr;
}
}
$a = join(',',@tempnr);
}
$a = join(',', @tempnr);
}
push @tmpargv, $a;
}
@ARGV = @tmpargv;
@ -103,25 +105,27 @@ foreach my $a (@tmpv)
# add all the cmd line args to the hash - to pass to the plugin subroutine
foreach my $a (@ARGV)
{
push(@{$cmdref->{arg}}, $a);
push(@{ $cmdref->{arg} }, $a);
}
# For some commands we need to set the noderange value
# - don't want to depend on the order of args so need to pick
# the operand that doesn't have an "=" sign ( ie. attr=val format)
my @checkcmds = ("nimnodeset", "mkdsklsnode", "rmdsklsnode", "xcat2nim", "nimnodecust");
if (grep(/^$bname$/, @checkcmds) ) {
# strip off all options
# use getopt instead of getopts to let long options pass through
getopt('ismot');
# check the operands for a noderange
while (my $a = shift(@ARGV)) {
if (!($a =~ /=/) && !($a =~ /^-/)) {
$cmdref->{noderange}->[0]=$a;
last;
}
}
if (grep(/^$bname$/, @checkcmds)) {
# strip off all options
# use getopt instead of getopts to let long options pass through
getopt('ismot');
# check the operands for a noderange
while (my $a = shift(@ARGV)) {
if (!($a =~ /=/) && !($a =~ /^-/)) {
$cmdref->{noderange}->[0] = $a;
last;
}
}
}
xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response);
xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response);
exit $xCAT::Client::EXITCODE;

View File

@ -11,37 +11,40 @@
BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; }
use lib "$::XCATROOT/lib/perl";
use Cwd;
#use IO::Socket::SSL;
#use IO::Socket::INET;
use File::Basename;
#use Data::Dumper;
use xCAT::Client;
use strict;
my $bname = basename($0);
my $cmdref;
if ($bname =~ /xcatclient/) { $cmdref->{command}->[0]=shift @ARGV; } # xcatclient was invoked directly and the 1st arg is cmd name that is used to locate the plugin
else { $cmdref->{command}->[0] = $bname; } # the cmd was sym linked to xcatclient
if ($bname =~ /xcatclient/) { $cmdref->{command}->[0] = shift @ARGV; } # xcatclient was invoked directly and the 1st arg is cmd name that is used to locate the plugin
else { $cmdref->{command}->[0] = $bname; } # the cmd was sym linked to xcatclient
$cmdref->{cwd}->[0] = cwd();
my $data;
# allows our plugins to get the stdin of the cmd that invoked the plugin
if ( (($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}) )
if ((($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}))
{
my $rin="";
my $rin = "";
my $rout;
vec($rin,fileno(STDIN),1)=1;
my $nfound=select($rout=$rin,"","",1);
vec($rin, fileno(STDIN), 1) = 1;
my $nfound = select($rout = $rin, "", "", 1);
if ($nfound)
{
while ( <STDIN> ) { $data.=$_; }
$cmdref->{stdin}->[0]=$data;
while (<STDIN>) { $data .= $_; }
$cmdref->{stdin}->[0] = $data;
}
}
else
{
if (-p STDIN) {
while ( <STDIN> ) { $data.=$_; }
$cmdref->{stdin}->[0]=$data;
while (<STDIN>) { $data .= $_; }
$cmdref->{stdin}->[0] = $data;
}
}
@ -57,40 +60,41 @@ if (($bname =~ /lslite/) && $str =~ /-i/)
$arg = "NO_NODE_RANGE";
}
else
{ # Consider the 1st non-hyphen arg to be the noderange. All others (before and after) go on the arg list.
$arg=shift(@ARGV);
{ # Consider the 1st non-hyphen arg to be the noderange. All others (before and after) go on the arg list.
$arg = shift(@ARGV);
while ($arg =~ /^-/) {
push (@{$cmdref->{arg}}, $arg);
$arg=shift(@ARGV);
push(@{ $cmdref->{arg} }, $arg);
$arg = shift(@ARGV);
}
}
if ($arg ne "NO_NODE_RANGE") {
# The noderange can be specified through a noderange file,
# the noderange file can be a relative path,
# convert the relative path to a full path.
# an ideal way is converting the relative path in xCAT::Noderange::noderange,
# but the existing xCAT::Noderange::noderange can not get the cwd(),
# needs to change all the callers to pass the cwd(),
# there are more than 100 callers.
my @tempnr = ();
foreach my $nr (split(/,/, $arg)) {
if ($nr =~ /^\^(.*)$/) {
my $nrf = $1;
if ($nrf !~ /^\//) { #relative path
$nrf = Cwd::abs_path($nrf);
}
$nrf = "\^" . $nrf;
push @tempnr, $nrf;
} else {
push @tempnr, $nr;
# The noderange can be specified through a noderange file,
# the noderange file can be a relative path,
# convert the relative path to a full path.
# an ideal way is converting the relative path in xCAT::Noderange::noderange,
# but the existing xCAT::Noderange::noderange can not get the cwd(),
# needs to change all the callers to pass the cwd(),
# there are more than 100 callers.
my @tempnr = ();
foreach my $nr (split(/,/, $arg)) {
if ($nr =~ /^\^(.*)$/) {
my $nrf = $1;
if ($nrf !~ /^\//) { #relative path
$nrf = Cwd::abs_path($nrf);
}
$nrf = "\^" . $nrf;
push @tempnr, $nrf;
} else {
push @tempnr, $nr;
}
}
}
$arg = join(',',@tempnr);
$cmdref->{noderange}->[0]=$arg;
$arg = join(',', @tempnr);
$cmdref->{noderange}->[0] = $arg;
}
if (@ARGV) {
push (@{$cmdref->{arg}}, @ARGV);
push(@{ $cmdref->{arg} }, @ARGV);
}
foreach (keys %ENV) {
if (/^XCAT_/) {
@ -98,5 +102,5 @@ foreach (keys %ENV) {
}
}
xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response);
xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response);
exit $xCAT::Client::EXITCODE;

View File

@ -15,34 +15,35 @@ use strict;
my $bname = basename($0);
my $cmdref;
if ($bname =~ /xcatclientnnr/) { $cmdref->{command}->[0]=shift @ARGV; } # xcatclientnnr was invoked directly and the 1st arg is cmd name that is used to locate the plugin
else { $cmdref->{command}->[0] = $bname; } # the cmd was sym linked to xcatclientnnr
if ($bname =~ /xcatclientnnr/) { $cmdref->{command}->[0] = shift @ARGV; } # xcatclientnnr was invoked directly and the 1st arg is cmd name that is used to locate the plugin
else { $cmdref->{command}->[0] = $bname; } # the cmd was sym linked to xcatclientnnr
$cmdref->{cwd}->[0] = cwd();
my $data;
# allows our plugins to get the stdin of the cmd that invoked the plugin
if ( (($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}) )
if ((($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}))
{
my $rout;
my $rin="";
vec($rin,fileno(STDIN),1)=1;
my $nfound=select($rout=$rin,"","",1);
my $rin = "";
vec($rin, fileno(STDIN), 1) = 1;
my $nfound = select($rout = $rin, "", "", 1);
if ($nfound)
{
while ( <STDIN> ) { $data.=$_; }
$cmdref->{stdin}->[0]=$data;
while (<STDIN>) { $data .= $_; }
$cmdref->{stdin}->[0] = $data;
}
}
else
{
if (-p STDIN) {
while ( <STDIN> ) { $data.=$_; }
$cmdref->{stdin}->[0]=$data;
while (<STDIN>) { $data .= $_; }
$cmdref->{stdin}->[0] = $data;
}
}
if (@ARGV) {
push (@{$cmdref->{arg}}, @ARGV);
push(@{ $cmdref->{arg} }, @ARGV);
}
foreach (keys %ENV) {
if (/^XCAT_/) {
@ -50,7 +51,7 @@ foreach (keys %ENV) {
}
}
xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response);
xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response);
exit $xCAT::Client::EXITCODE;

View File

@ -2,6 +2,7 @@
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; }
use lib "$::XCATROOT/lib/perl";
#use Data::Dumper;
use xCAT::Client;
use Getopt::Long;
@ -12,30 +13,31 @@ my $option;
my $printcount;
my $individual;
GetOptions("n"=>\$option,
"i"=>\$individual,
"c"=>\$printcount);
GetOptions("n" => \$option,
"i" => \$individual,
"c" => \$printcount);
while (<STDIN>) {
my $node;
my $output;
if (/:/) {
($node,$output) = split /:/,$_,2;
($node, $output) = split /:/, $_, 2;
} else {
$node= "UNKNOWN";
$node = "UNKNOWN";
$output = $_;
}
$output =~ s/^ //;
$output{$node}.=$output;
$output{$node} .= $output;
}
my %collated;
unless ($individual) {
foreach (keys %output) {
$collated{$output{$_}}->{$_}=1;
$collated{ $output{$_} }->{$_} = 1;
}
}
my $nodes;
sub fillerup {
my $response = shift;
if ($response->{data}->[0]) {
@ -53,20 +55,20 @@ if ($individual) {
exit(0);
}
foreach my $output (keys %collated) {
$nodes = join(',',sort (keys %{$collated{$output}}));
$nodes = join(',', sort (keys %{ $collated{$output} }));
my $cmdref = {
noderange => [$nodes],
command => ['rnoderange'],
command => ['rnoderange'],
};
unless ($option) {
xCAT::Client::submit_request($cmdref,\&fillerup);
xCAT::Client::submit_request($cmdref, \&fillerup);
}
print "====================================\n";
print "$nodes\n";
print "====================================\n";
if ($printcount) {
print "Node count = ".scalar( keys %{$collated{$output}})." \n";
print "====================================\n";
print "Node count = " . scalar(keys %{ $collated{$output} }) . " \n";
print "====================================\n";
}
print $output;
print "\n";

View File

@ -2,6 +2,7 @@
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; }
use lib "$::XCATROOT/lib/perl";
#use Data::Dumper;
use xCAT::Client;
my %columns;
@ -11,30 +12,31 @@ while (<STDIN>) {
my $node;
my $output;
if (/:/) {
($node,$output) = split /:/,$_,2;
($node, $output) = split /:/, $_, 2;
} else {
$node= "UNKNOWN";
$node = "UNKNOWN";
$output = $_;
}
my $colname;
if ($output =~ /:/) {
($colname,$output) = split /:/,$output,2;
if ($output =~ /:/) {
($colname, $output) = split /:/, $output, 2;
} else {
$colname = "UNKNOWN";
$colname = "UNKNOWN";
}
$colname =~ s/^ *//;
$colname =~ s/^ *//;
$output =~ s/^ //;
$output =~ s/\n//;
$output{$node}->{$colname}.=$output;
$columns{$colname}=1;
$output{$node}->{$colname} .= $output;
$columns{$colname} = 1;
}
my @columns;
foreach (keys %columns) { #create,preserv ordered list of columns
push @columns, $_;
foreach (keys %columns) { #create,preserv ordered list of columns
push @columns, $_;
}
print join(',',"node",@columns)."\n";
print join(',', "node", @columns) . "\n";
my $nodes;
sub fillerup {
my $response = shift;
if ($response->{data}->[0]) {
@ -42,9 +44,9 @@ sub fillerup {
}
}
foreach my $node (keys %output) {
my @output=($node);
my @output = ($node);
foreach (@columns) {
push @output,$output{$node}->{$_};
push @output, $output{$node}->{$_};
}
print join(",",@output)."\n";
print join(",", @output) . "\n";
}

View File

@ -3,9 +3,9 @@
BEGIN
{
$::XCATROOT =
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
}
use lib "$::XCATROOT/lib/perl";
use strict;
@ -73,7 +73,7 @@ if ($arg =~ /^-/) # no noderange
if ($::ROOTIMG != 1)
{ # if not running against rootimg then noderange required
xCAT::MsgUtils->message("I",
"Node range not specified, see $bname man page for syntax.\n");
"Node range not specified, see $bname man page for syntax.\n");
exit 1;
}
}
@ -84,7 +84,7 @@ else
if (!($cmdref->{noderange}->[0]))
{
xCAT::MsgUtils->message("I",
"Node range not specified, see man page for syntax.\n");
"Node range not specified, see man page for syntax.\n");
exit 1;
}
@ARGV = @SaveARGV; # noderange removed for parsing
@ -100,7 +100,7 @@ else
foreach my $sarg (@SaveARGV)
{
push(@{$cmdref->{arg}}, $sarg);
push(@{ $cmdref->{arg} }, $sarg);
}
# add environment variables, if they have not already been assigned with
@ -109,7 +109,7 @@ if (!($::NODE_RSH))
{
if ($ENV{'DSH_NODE_RSH'})
{
push(@{$cmdref->{env}}, "DSH_NODE_RSH=$ENV{'DSH_NODE_RSH'}");
push(@{ $cmdref->{env} }, "DSH_NODE_RSH=$ENV{'DSH_NODE_RSH'}");
}
}
@ -117,7 +117,7 @@ if (!($::NODE_RCP))
{
if ($ENV{'DSH_NODE_RCP'})
{
push(@{$cmdref->{env}}, "DSH_NODE_RCP=$ENV{'DSH_NODE_RCP'}");
push(@{ $cmdref->{env} }, "DSH_NODE_RCP=$ENV{'DSH_NODE_RCP'}");
}
}
@ -125,7 +125,7 @@ if (!($::NODE_OPTS))
{
if ($ENV{'DSH_NODE_OPTS'})
{
push(@{$cmdref->{env}}, "DSH_NODE_OPTS=$ENV{'DSH_NODE_OPTS'}");
push(@{ $cmdref->{env} }, "DSH_NODE_OPTS=$ENV{'DSH_NODE_OPTS'}");
}
}
@ -133,7 +133,7 @@ if (!($::FANOUT))
{
if ($ENV{'DSH_FANOUT'})
{
push(@{$cmdref->{env}}, "DSH_FANOUT=$ENV{'DSH_FANOUT'}");
push(@{ $cmdref->{env} }, "DSH_FANOUT=$ENV{'DSH_FANOUT'}");
}
}
@ -141,53 +141,53 @@ if (!($::TIMEOUT))
{
if ($ENV{'DSH_TIMEOUT'})
{
push(@{$cmdref->{env}}, "DSH_TIMEOUT=$ENV{'DSH_TIMEOUT'}");
push(@{ $cmdref->{env} }, "DSH_TIMEOUT=$ENV{'DSH_TIMEOUT'}");
}
}
if ($ENV{'DSH_REMOTE_PASSWORD'})
{
push(@{$cmdref->{env}}, "DSH_REMOTE_PASSWORD=$ENV{'DSH_REMOTE_PASSWORD'}");
push(@{ $cmdref->{env} }, "DSH_REMOTE_PASSWORD=$ENV{'DSH_REMOTE_PASSWORD'}");
}
if ($ENV{'DSH_FROM_USERID'})
{
push(@{$cmdref->{env}}, "DSH_FROM_USERID=$ENV{'DSH_FROM_USERID'}");
push(@{ $cmdref->{env} }, "DSH_FROM_USERID=$ENV{'DSH_FROM_USERID'}");
}
if ($ENV{'DSH_TO_USERID'})
{
push(@{$cmdref->{env}}, "DSH_TO_USERID=$ENV{'DSH_TO_USERID'}");
push(@{ $cmdref->{env} }, "DSH_TO_USERID=$ENV{'DSH_TO_USERID'}");
}
if ($ENV{'DEVICETYPE'})
{
push(@{$cmdref->{env}}, "DEVICETYPE=$ENV{'DEVICETYPE'}");
push(@{ $cmdref->{env} }, "DEVICETYPE=$ENV{'DEVICETYPE'}");
}
if ($ENV{'DSH_RSYNC_FILE'})
{
push(@{$cmdref->{env}}, "DSH_RSYNC_FILE=$ENV{'DSH_RSYNC_FILE'}");
push(@{ $cmdref->{env} }, "DSH_RSYNC_FILE=$ENV{'DSH_RSYNC_FILE'}");
}
if ($ENV{'RSYNCSN'})
{
push(@{$cmdref->{env}}, "RSYNCSN=$ENV{'RSYNCSN'}");
push(@{ $cmdref->{env} }, "RSYNCSN=$ENV{'RSYNCSN'}");
}
if ($ENV{'RSYNCSNONLY'})
{
push(@{$cmdref->{env}}, "RSYNCSNONLY=$ENV{'RSYNCSNONLY'}");
push(@{ $cmdref->{env} }, "RSYNCSNONLY=$ENV{'RSYNCSNONLY'}");
}
if ($ENV{'DCP_PULL'})
{
push(@{$cmdref->{env}}, "DCP_PULL=$ENV{'DCP_PULL'}");
push(@{ $cmdref->{env} }, "DCP_PULL=$ENV{'DCP_PULL'}");
}
if ($ENV{'DSHEXECUTE'})
{
push(@{$cmdref->{env}}, "DSHEXECUTE=$ENV{'DSHEXECUTE'}");
push(@{ $cmdref->{env} }, "DSHEXECUTE=$ENV{'DSHEXECUTE'}");
}
if ($ENV{'DSH_ENVIRONMENT'})
{
push(@{$cmdref->{env}}, "DSH_ENVIRONMENT=$ENV{'DSH_ENVIRONMENT'}");
push(@{ $cmdref->{env} }, "DSH_ENVIRONMENT=$ENV{'DSH_ENVIRONMENT'}");
}
xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response);
@ -208,10 +208,11 @@ exit $xCAT::Client::EXITCODE;
sub parse_args_xdsh
{
my $snodes = shift;
# test to see if any parameters were entered
my $arraysize=@ARGV;
if ($arraysize ==0) {
my $msg= "No parameters were supplied on the xdsh command. Run xdsh -h";
my $arraysize = @ARGV;
if ($arraysize == 0) {
my $msg = "No parameters were supplied on the xdsh command. Run xdsh -h";
xCAT::MsgUtils->message("E", $msg);
exit 1;
}
@ -247,8 +248,8 @@ sub parse_args_xdsh
'V|version' => \$options{'version'},
'devicetype=s' => \$options{'devicetype'},
'nodestatus|nodestatus' => \$options{'nodestatus'},
'sudo|sudo' => \$options{'sudo'},
'nodestatus|nodestatus' => \$options{'nodestatus'},
'sudo|sudo' => \$options{'sudo'},
'command-name|commandName=s' => \$options{'command-name'},
'command-description|commandDescription=s' =>
\$options{'command-description'},
@ -281,7 +282,7 @@ sub parse_args_xdsh
# get the directories on the servicenode to put the files in
my $defaultsyndir = "/var/xcat/syncfiles";
my @syndir = xCAT::TableUtils->get_site_attribute("SNsyncfiledir");
my @syndir = xCAT::TableUtils->get_site_attribute("SNsyncfiledir");
my $synfiledir;
if ($syndir[0])
{
@ -291,9 +292,10 @@ sub parse_args_xdsh
{
$synfiledir = "/var/xcat/syncfiles"; # default
}
# for append function
my $defaultnodesyndir = "/var/xcat/node/syncfiles";
my @syndir2 = xCAT::TableUtils->get_site_attribute("nodesyncfiledir");
my @syndir2 = xCAT::TableUtils->get_site_attribute("nodesyncfiledir");
my $synfiledir2;
if ($syndir2[0])
{
@ -307,12 +309,13 @@ sub parse_args_xdsh
{
my $answer;
my $msg =
"Do you wish to erase $synfiledir,$synfiledir2 and all subdirectories?\n Enter Y or N.";
"Do you wish to erase $synfiledir,$synfiledir2 and all subdirectories?\n Enter Y or N.";
xCAT::MsgUtils->message('I', "$msg");
`stty -echo`;
chop($answer = <STDIN>);
`stty echo`;
$answer =~ tr/a-z/A-Z/; # convert to upper
$answer =~ tr/a-z/A-Z/; # convert to upper
if ($answer ne "Y")
{
exit 0;
@ -321,7 +324,7 @@ sub parse_args_xdsh
my $cmd = "xdsh $snodes -v rm -rf $synfiledir/*;xdsh $snodes -v rm -rf $synfiledir2";
xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{ # error
{ # error
my $msg = "Error from $cmd: to cleanup servicenodes";
xCAT::MsgUtils->message("E", $msg);
exit 1;
@ -331,7 +334,7 @@ sub parse_args_xdsh
}
if ($options{'bypass'})
{
$ENV{XCATBYPASS} = "yes"; # bypass xcatd
$ENV{XCATBYPASS} = "yes"; # bypass xcatd
}
if ($options{'show-config'})
{
@ -339,24 +342,27 @@ sub parse_args_xdsh
exit 0;
}
my $executescript;
#check for full path to file
if ($options{execute})
{
{
# this can be a file + parameters
$executescript = join ' ', @ARGV;
if ($executescript !~ /^\//) {
#relative path
$executescript = xCAT::Utils->full_path($executescript);
#relative path
$executescript = xCAT::Utils->full_path($executescript);
}
$ENV{'DSHEXECUTE'} = $executescript; # execute script
$ENV{'DSHEXECUTE'} = $executescript; # execute script
}
# -E <env file> option if not already exported
if ($options{environment})
{
if (!($ENV{'DSH_ENVIRONMENT'})) { # env variable first
$ENV{'DSH_ENVIRONMENT'} = $options{environment}; # env file
}
{
if (!($ENV{'DSH_ENVIRONMENT'})) { # env variable first
$ENV{'DSH_ENVIRONMENT'} = $options{environment}; # env file
}
}
@ -384,12 +390,13 @@ sub parse_args_xdsh
$devicepath =~ s/::/\//g;
if (($options{'ssh-setup'}) && ($devicepath =~ /Mellanox/i)) {
my $msg =
"You do not use xdsh -K to setup the Mellanox switch ssh keys. Use rspconfig. See man page for rspconfig option sshcfg={enable|disable}.";
"You do not use xdsh -K to setup the Mellanox switch ssh keys. Use rspconfig. See man page for rspconfig option sshcfg={enable|disable}.";
xCAT::MsgUtils->message("E", $msg);
exit 2;
}
# only allow -K with -l if --devicetype defined
if ( (($options{'user'}) && ($options{'ssh-setup'}))
if ((($options{'user'}) && ($options{'ssh-setup'}))
&& (!($options{'devicetype'})))
{
my $msg =
@ -405,7 +412,7 @@ sub parse_args_xdsh
# prompt for the password for the userid on the node that will be setup
my $userpw;
$msg =
"The ssh keys will be updated for '$to_userid' on the node(s).\nPassword:";
"The ssh keys will be updated for '$to_userid' on the node(s).\nPassword:";
xCAT::MsgUtils->message("I", $msg);
system("stty -echo"); # turn off keyboard
chop($userpw = <STDIN>);
@ -433,49 +440,49 @@ sub parse_args_xdsh
my $sshdir = "$home/.ssh";
if (!-d $sshdir)
{
my $cmd = "/bin/mkdir -m 700 -p $sshdir";
my $outref = xCAT::Utils->runcmd("$cmd", 0);
if ($::RUNCMD_RC != 0)
{
xCAT::MsgUtils->message('E', "Could not create $sshdir directory.");
exit 1;
}
my $cmd = "/bin/mkdir -m 700 -p $sshdir";
my $outref = xCAT::Utils->runcmd("$cmd", 0);
if ($::RUNCMD_RC != 0)
{
xCAT::MsgUtils->message('E', "Could not create $sshdir directory.");
exit 1;
}
}
# add config file with strict host checking no, if not already there
my $configinfo = "StrictHostKeyChecking no";
my $configfile= "$home/.ssh/config";
if (-e $configfile)
{
my $cmd = "grep StrictHostKeyChecking $configfile";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0)
{ # not there
$cmd = "echo $configinfo >> $configfile";
my @output = xCAT::Utils->runcmd($cmd, 0);
# add config file with strict host checking no, if not already there
my $configinfo = "StrictHostKeyChecking no";
my $configfile = "$home/.ssh/config";
if (-e $configfile)
{
my $cmd = "grep StrictHostKeyChecking $configfile";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0)
{ # error
xCAT::MsgUtils->message("E", "Error on $cmd, @output");
return 1;
}
{ # not there
$cmd = "echo $configinfo >> $configfile";
my @output = xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{ # error
xCAT::MsgUtils->message("E", "Error on $cmd, @output");
return 1;
}
}
}
}
else # file does not exist
{
my $cmd = "echo $configinfo >> $configfile";
my @output = xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{ # error
xCAT::MsgUtils->message("E", "Error on $cmd, @output");
return 1;
}
else
{
chmod 0600, $configfile;
my $cmd = "echo $configinfo >> $configfile";
my @output = xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{ # error
xCAT::MsgUtils->message("E", "Error on $cmd, @output");
return 1;
}
else
{
chmod 0600, $configfile;
}
}
}
@ -484,15 +491,16 @@ sub parse_args_xdsh
#
if ($current_userid ne "root")
{
$::REMOTE_SHELL = "/usr/bin/ssh";
my $callback = \&xCAT::Client::handle_response;
# generates new keys for non-root id, if they do not already exist
my $rc=
xCAT::RemoteShellExp->remoteshellexp("k",$callback,$::REMOTE_SHELL);
if ($rc != 0) {
$msg = "remoteshellexp failed generating keys.";
xCAT::MsgUtils->message("E", $msg);
}
$::REMOTE_SHELL = "/usr/bin/ssh";
my $callback = \&xCAT::Client::handle_response;
# generates new keys for non-root id, if they do not already exist
my $rc =
xCAT::RemoteShellExp->remoteshellexp("k", $callback, $::REMOTE_SHELL);
if ($rc != 0) {
$msg = "remoteshellexp failed generating keys.";
xCAT::MsgUtils->message("E", $msg);
}
}
@ -547,10 +555,11 @@ sub parse_args_xdcp
{
my %options = ();
# test to see if any parameters were entered
my $arraysize=@ARGV;
if ($arraysize ==0) {
my $msg= "No parameters were supplied on the xdcp command. Run xdcp -h";
my $arraysize = @ARGV;
if ($arraysize == 0) {
my $msg = "No parameters were supplied on the xdcp command. Run xdcp -h";
xCAT::MsgUtils->message("E", $msg);
exit 1;
}
@ -560,28 +569,28 @@ sub parse_args_xdcp
if (
!GetOptions(
'f|fanout=i' => \$options{'fanout'},
'F|File=s' => \$options{'File'},
'h|help' => \$options{'help'},
'i|rootimg=s' => \$options{'rootimg'},
'l|user=s' => \$options{'user'},
'm|monitor' => \$options{'monitor'},
'o|node-options=s' => \$options{'node-options'},
'q|show-config' => \$options{'show-config'},
'p|preserve' => \$options{'preserve'},
'r|c|node-rcp=s' => \$options{'node-rcp'},
's' => \$options{'rsyncSN'},
't|timeout=i' => \$options{'timeout'},
'v|verify' => \$options{'verify'},
'B|bypass' => \$options{'bypass'},
'Q|silent' => \$options{'silent'},
'P|pull' => \$options{'pull'},
'R|recursive' => \$options{'recursive'},
'T|trace' => \$options{'trace'},
'V|version' => \$options{'version'},
'nodestatus|nodestatus' => \$options{'nodestatus'},
'sudo|sudo' => \$options{'sudo'},
'X:s' => \$options{'ignore_env'}
'f|fanout=i' => \$options{'fanout'},
'F|File=s' => \$options{'File'},
'h|help' => \$options{'help'},
'i|rootimg=s' => \$options{'rootimg'},
'l|user=s' => \$options{'user'},
'm|monitor' => \$options{'monitor'},
'o|node-options=s' => \$options{'node-options'},
'q|show-config' => \$options{'show-config'},
'p|preserve' => \$options{'preserve'},
'r|c|node-rcp=s' => \$options{'node-rcp'},
's' => \$options{'rsyncSN'},
't|timeout=i' => \$options{'timeout'},
'v|verify' => \$options{'verify'},
'B|bypass' => \$options{'bypass'},
'Q|silent' => \$options{'silent'},
'P|pull' => \$options{'pull'},
'R|recursive' => \$options{'recursive'},
'T|trace' => \$options{'trace'},
'V|version' => \$options{'version'},
'nodestatus|nodestatus' => \$options{'nodestatus'},
'sudo|sudo' => \$options{'sudo'},
'X:s' => \$options{'ignore_env'}
)
)
{
@ -645,7 +654,7 @@ sub parse_args_xdcp
if (($options{'rootimg'}) && (!($options{'File'})))
{
xCAT::MsgUtils->message("E",
"To use -i flag you must supply the -F flag\n.");
"To use -i flag you must supply the -F flag\n.");
exit 1;
}
if ($options{'node-rcp'}) # if set on command line, use it
@ -680,64 +689,64 @@ sub check_invalid_exports
if ($ENV{'DSH_CONTEXT'})
{
xCAT::MsgUtils->message("I",
"DSH_CONTEXT is set but is not supported. It will be ignored.\n");
"DSH_CONTEXT is set but is not supported. It will be ignored.\n");
}
if ($ENV{'DSH_LIST'}) # if file of nodes input
{
xCAT::MsgUtils->message("I",
"DSH_LIST is set but is not supported. It will be ignored.\n");
"DSH_LIST is set but is not supported. It will be ignored.\n");
}
if ($ENV{'DSH_NODE_LIST'})
{
xCAT::MsgUtils->message(
"I",
"DSH_NODE_LIST is set but is not supported. It will be ignored.\n"
);
"I",
"DSH_NODE_LIST is set but is not supported. It will be ignored.\n"
);
}
if ($ENV{'DSH_DEVICE_LIST'})
{
xCAT::MsgUtils->message(
"I",
"DSH_DEVICE_LIST is set but is not supported. It will be ignored.\n"
);
);
}
if ($ENV{'DSH_DEVICE_OPTS'})
{
xCAT::MsgUtils->message(
"I",
"DSH_DEVICE_OPTS is set but is not supported. It will be ignored.\n"
);
);
}
if ($ENV{'DSH_DEVICE_RCP'})
{
xCAT::MsgUtils->message(
"I",
"DSH_DEVICE_RCP is set but is not supported. It will be ignored.\n"
);
"I",
"DSH_DEVICE_RCP is set but is not supported. It will be ignored.\n"
);
}
if ($ENV{'DSH_DEVICE_RSH'})
{
xCAT::MsgUtils->message(
"I",
"DSH_DEVICE_RSH is set but is not supported. It will be ignored.\n"
);
"I",
"DSH_DEVICE_RSH is set but is not supported. It will be ignored.\n"
);
}
if ($ENV{'DSH_NODEGROUP_PATH'})
{
xCAT::MsgUtils->message(
"I",
"DSH_NODEGROUP_PATH is set but is not supported. It will be ignored.\n"
);
"DSH_NODEGROUP_PATH is set but is not supported. It will be ignored.\n"
);
}
if ($ENV{'RSYNC_RSH'})
{
xCAT::MsgUtils->message("I",
" RSYNC_RSH is set but is not supported. It will be ignored.\n");
" RSYNC_RSH is set but is not supported. It will be ignored.\n");
}
if ($ENV{'DSH_REPORT'})
{
xCAT::MsgUtils->message("I",
" DSH_REPORT is set but is not supported. It will be ignored.\n");
" DSH_REPORT is set but is not supported. It will be ignored.\n");
}
}

View File

@ -24,7 +24,7 @@ use Getopt::Std;
# -c : list distinct output only once #
# -h : usage #
# -x : omit extra header output for each node. #
# Can not be used with -c. #
# Can not be used with -c. #
# -q : quiet mode #
# #
# Ouputs: #
@ -110,8 +110,8 @@ while (<STDIN>)
#
$num_lines++;
if (!($quiet)) {
if ($::opt_x) { $num_lines % 100 == 0 && print STDOUT "."; }
else { $num_lines % 1000 == 0 && print STDOUT "."; }
if ($::opt_x) { $num_lines % 100 == 0 && print STDOUT "."; }
else { $num_lines % 1000 == 0 && print STDOUT "."; }
}
if (/: /)
{
@ -204,7 +204,7 @@ sub d_syntax
"-c : compresses the output by listing unique output only once.\n";
my $usage3 = "-h : help \n";
my $usage4 =
"-x : omit extra header output for each node. Can not be used with -c. \n";
"-x : omit extra header output for each node. Can not be used with -c. \n";
my $usage5 = "-q : quiet mode.\n";
my $usage = $usage1 .= $usage2 .= $usage3 .= $usage4 .= $usage5;
xCAT::MsgUtils->message("I", $usage);
@ -302,10 +302,10 @@ sub print_tree
xCAT::MsgUtils->message("I", "HOSTS:");
print
"-------------------------------------------------------------------------\n";
"-------------------------------------------------------------------------\n";
&display_wc;
print
"-------------------------------------------------------------------------------\n";
"-------------------------------------------------------------------------------\n";
print $str{$index};
}
}

View File

@ -1,6 +1,6 @@
#!/usr/bin/perl
eval 'exec perl -S $0 "$@"'
if 0;
eval 'exec perl -S $0 "$@"'
if 0;
#############################################################################
# podchecker -- command to invoke the podchecker function in Pod::Checker
#
@ -11,6 +11,7 @@
#############################################################################
use strict;
#use diagnostics;
=head1 NAME
@ -98,15 +99,15 @@ use Getopt::Long;
my %options;
## Parse options
GetOptions(\%options, qw(help man warnings+ nowarnings)) || pod2usage(2);
pod2usage(1) if ($options{help});
pod2usage(-verbose => 2) if ($options{man});
GetOptions(\%options, qw(help man warnings+ nowarnings)) || pod2usage(2);
pod2usage(1) if ($options{help});
pod2usage(-verbose => 2) if ($options{man});
if($options{nowarnings}) {
$options{warnings} = 0;
if ($options{nowarnings}) {
$options{warnings} = 0;
}
elsif(!defined $options{warnings}) {
$options{warnings} = 1; # default is warnings on
elsif (!defined $options{warnings}) {
$options{warnings} = 1; # default is warnings on
}
## Dont default to STDIN if connected to a terminal
@ -114,27 +115,29 @@ pod2usage(2) if ((@ARGV == 0) && (-t STDIN));
## Invoke podchecker()
my $status = 0;
@ARGV = qw(-) unless(@ARGV);
@ARGV = qw(-) unless (@ARGV);
for my $podfile (@ARGV) {
if($podfile eq '-') {
$podfile = '<&STDIN';
if ($podfile eq '-') {
$podfile = '<&STDIN';
}
elsif(-d $podfile) {
warn "podchecker: Warning: Ignoring directory '$podfile'\n";
next;
elsif (-d $podfile) {
warn "podchecker: Warning: Ignoring directory '$podfile'\n";
next;
}
my $errors =
podchecker($podfile, undef, '-warnings' => $options{warnings});
if($errors > 0) {
if ($errors > 0) {
# errors occurred
$status = 1;
printf STDERR ("%s has %d pod syntax %s.\n",
$podfile, $errors,
($errors == 1) ? 'error' : 'errors');
$podfile, $errors,
($errors == 1) ? 'error' : 'errors');
}
elsif($errors < 0) {
elsif ($errors < 0) {
# no pod found
$status = 2 unless($status);
$status = 2 unless ($status);
print STDERR "$podfile does not contain any pod commands.\n";
}
else {

View File

@ -7,9 +7,9 @@
BEGIN
{
$::XCATROOT =
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
}
use lib "$::XCATROOT/lib/perl";
use Getopt::Long;
@ -33,31 +33,31 @@ use strict;
my $rc = 0;
my $cmd;
&parse_args;
if ($::BINARY) { # not using xCAT to dump, using the database utility
my $DBname = xCAT::Utils->get_DBName;
if ($DBname eq "DB2") {
$rc=&DB2_bindump;
if ($rc == 0) {
xCAT::MsgUtils->message("I", "Backup Complete.");
} else {
xCAT::MsgUtils->message("I", "Backup Failed.");
}
exit $rc;
} else {
if ($DBname eq "PG") {
$rc=&PG_bindump;
if ($rc == 0) {
xCAT::MsgUtils->message("I", "Backup Complete.");
} else {
xCAT::MsgUtils->message("I", "Backup Failed.");
}
exit $rc;
} else {
xCAT::MsgUtils->message("E",
"Binary dump (-b) is not supported for $DBname");
exit 1;
}
}
if ($::BINARY) { # not using xCAT to dump, using the database utility
my $DBname = xCAT::Utils->get_DBName;
if ($DBname eq "DB2") {
$rc = &DB2_bindump;
if ($rc == 0) {
xCAT::MsgUtils->message("I", "Backup Complete.");
} else {
xCAT::MsgUtils->message("I", "Backup Failed.");
}
exit $rc;
} else {
if ($DBname eq "PG") {
$rc = &PG_bindump;
if ($rc == 0) {
xCAT::MsgUtils->message("I", "Backup Complete.");
} else {
xCAT::MsgUtils->message("I", "Backup Failed.");
}
exit $rc;
} else {
xCAT::MsgUtils->message("E",
"Binary dump (-b) is not supported for $DBname");
exit 1;
}
}
}
@ -66,50 +66,55 @@ my @output = xCAT::Utils->runcmd("tabdump", 0);
if ($::RUNCMD_RC != 0)
{ # error
xCAT::MsgUtils->message("E",
"Error running tabdump to get list of tables");
"Error running tabdump to get list of tables");
exit 1;
}
# Determine which table to skip
my @output2;
if ($ENV{'XCAT_SKIPTABLES'}) {
@output2=$ENV{'XCAT_SKIPTABLES'};
@output2 = $ENV{'XCAT_SKIPTABLES'};
} else {
# read tables to skip from site.skiptables attribute
@output2=xCAT::TableUtils->get_site_attribute('skiptables');
# read tables to skip from site.skiptables attribute
@output2 = xCAT::TableUtils->get_site_attribute('skiptables');
}
my @skiptbls;
if (@output2) {
@skiptbls = split (/\,/,$output2[0]);
@skiptbls = split(/\,/, $output2[0]);
}
foreach my $table (@output)
{
# if not -a request , skip eventlog and auditlog
if ( (!$::ALL) && (($table =~ /^eventlog/) || ($table =~ /^auditlog/))) {
if ($::DUMPVERBOSE) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
if ((!$::ALL) && (($table =~ /^eventlog/) || ($table =~ /^auditlog/))) {
if ($::DUMPVERBOSE) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
}
# skip teal tables
if ( $table =~ /^x_teal/ ) {
if ($::DUMPVERBOSE) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
# skip teal tables
if ($table =~ /^x_teal/) {
if ($::DUMPVERBOSE) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
}
# skip ISNM tables except isnm_config
if ( $table =~ /^isnm_perf/ ) {
if ($::DUMPVERBOSE) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
# skip ISNM tables except isnm_config
if ($table =~ /^isnm_perf/) {
if ($::DUMPVERBOSE) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
}
# skip any table in the site.skiptables attribute
if (grep(/^$table$/, @skiptbls)) {
if ($::DUMPVERBOSE) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
if (grep(/^$table$/, @skiptbls)) {
if ($::DUMPVERBOSE) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
}
$cmd = "tabdump -f $::PATH/$table.csv $table";
@ -118,9 +123,9 @@ foreach my $table (@output)
{ # error
xCAT::MsgUtils->message("E", "Error running $cmd, @errout");
} else {
if ($::DUMPVERBOSE) {
xCAT::MsgUtils->message("I", "Dumping $table");
}
if ($::DUMPVERBOSE) {
xCAT::MsgUtils->message("I", "Dumping $table");
}
}
}
@ -139,18 +144,18 @@ exit $rc;
sub parse_args
{
my $msg;
my $usagemsg =
" dumpxCATdb -h \n dumpxCATdb -v \n dumpxCATdb [-a] [-V] <-p> [path to backup directory] \n dumpxCATdb -b [-V] <-p> [path to backup directory]";
my $usagemsg =
" dumpxCATdb -h \n dumpxCATdb -v \n dumpxCATdb [-a] [-V] <-p> [path to backup directory] \n dumpxCATdb -b [-V] <-p> [path to backup directory]";
Getopt::Long::Configure("posix_default");
Getopt::Long::Configure("no_gnu_compat");
Getopt::Long::Configure("bundling");
if (
!GetOptions(
'a|all' => \$::ALL,
'b|bin' => \$::BINARY,
'a|all' => \$::ALL,
'b|bin' => \$::BINARY,
'p|path=s' => \$::PATH,
'h|help' => \$::HELP,
'V|verbose' => \$::DUMPVERBOSE,
'V|verbose' => \$::DUMPVERBOSE,
'v|version' => \$::VERSION
)
@ -176,16 +181,16 @@ sub parse_args
xCAT::MsgUtils->message("E", $msg);
exit 1;
}
if (!( -e $::PATH)) {
my $msg = " Creating $::PATH for database dump";
xCAT::MsgUtils->message("I", $msg);
my @output = xCAT::Utils->runcmd("mkdir -p $::PATH", 0);
if ($::RUNCMD_RC != 0)
{ # error
xCAT::MsgUtils->message("E",
"Error running mkdir -p $::PATH");
exit 1;
}
if (!(-e $::PATH)) {
my $msg = " Creating $::PATH for database dump";
xCAT::MsgUtils->message("I", $msg);
my @output = xCAT::Utils->runcmd("mkdir -p $::PATH", 0);
if ($::RUNCMD_RC != 0)
{ # error
xCAT::MsgUtils->message("E",
"Error running mkdir -p $::PATH");
exit 1;
}
}
}
@ -199,69 +204,71 @@ sub parse_args
=cut
#-----------------------------------------------------------------------------
sub DB2_bindump
sub DB2_bindump
{
my $msg;
my $rc=0;
my $rc = 0;
# check to see if they are setup to do an online dump
# Database has to have defined logretain RECOVERY and there
# must already been taken an offline backup.
my $cmd="db2 get database configuration for xcatdb > /tmp/db2output";
$rc = &rundb2cmd($cmd); # must su to xcatdb
# must already been taken an offline backup.
my $cmd = "db2 get database configuration for xcatdb > /tmp/db2output";
$rc = &rundb2cmd($cmd); # must su to xcatdb
if ($rc != 0)
{
xCAT::MsgUtils->message("E", " $cmd error.");
return 1;
xCAT::MsgUtils->message("E", " $cmd error.");
return 1;
}
# check to see if they setup log recover
$cmd = " egrep -i \"Log retain for recovery enabled\" /tmp/db2output";
my @output=xCAT::Utils->runcmd($cmd, -1);
my @output = xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("E", "Log retain for recovery enabled (LOGRETAIN) = RECOVERY must be set to perform ONLINE Backups and one ONLINE backup must have been taken. See xCAT DB2 documentation. The section - Backup/Restore the database with DB2 Commands.");
return 1;
} else { # check to see if LOGRETAIN is ON
if (!grep(/ = RECOVERY/, @output)) {
xCAT::MsgUtils->message("E", "Log retain for recovery enabled (LOGRETAIN) = RECOVERY must be set to perform ONLINE Backups and one ONLINE backup must have been taken. See xCAT DB2 documentation. The section - Backup/Restore the database with DB2 Commands.");
return 1;
}
xCAT::MsgUtils->message("E", "Log retain for recovery enabled (LOGRETAIN) = RECOVERY must be set to perform ONLINE Backups and one ONLINE backup must have been taken. See xCAT DB2 documentation. The section - Backup/Restore the database with DB2 Commands.");
return 1;
} else { # check to see if LOGRETAIN is ON
if (!grep(/ = RECOVERY/, @output)) {
xCAT::MsgUtils->message("E", "Log retain for recovery enabled (LOGRETAIN) = RECOVERY must be set to perform ONLINE Backups and one ONLINE backup must have been taken. See xCAT DB2 documentation. The section - Backup/Restore the database with DB2 Commands.");
return 1;
}
}
# check to see if they have one backup
$cmd = " ls $::PATH";
@output=xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("E", "One ONLINE backup must have been taken and exist in $::PATH. See xCAT DB2 documentation. The section - Backup/Restore the database with DB2 Commands.");
return 1;
} else { # check to see if LOGRETAIN is ON
if (!grep(/XCATDB/, @output)) {
xCAT::MsgUtils->message("E", "One ONLINE backup must have been taken and exist in $::PATH. See xCAT DB2 documentation. The section - Backup/Restore the database with DB2 Commands.");
return 1;
}
}
# finally all checks ok, can take an ONLINE backup
# get password from cfgloc
my $cmd="cat /etc/xcat/cfgloc";
my $info=xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("E", "Cannot read /etc/xcat/cfgloc.");
return 1;
}
chomp($info);
my ($db,$inst,$pw) = split(/\|/, $info);
my $cmd=" db2 backup db xcatdb user xcatdb using $pw ONLINE to $::PATH";
$rc = &rundb2cmd($cmd); # must su to xcatdb
# check to see if they have one backup
$cmd = " ls $::PATH";
@output = xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("E", "One ONLINE backup must have been taken and exist in $::PATH. See xCAT DB2 documentation. The section - Backup/Restore the database with DB2 Commands.");
return 1;
} else { # check to see if LOGRETAIN is ON
if (!grep(/XCATDB/, @output)) {
xCAT::MsgUtils->message("E", "One ONLINE backup must have been taken and exist in $::PATH. See xCAT DB2 documentation. The section - Backup/Restore the database with DB2 Commands.");
return 1;
}
}
# finally all checks ok, can take an ONLINE backup
# get password from cfgloc
my $cmd = "cat /etc/xcat/cfgloc";
my $info = xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("E", "Cannot read /etc/xcat/cfgloc.");
return 1;
}
chomp($info);
my ($db, $inst, $pw) = split(/\|/, $info);
my $cmd = " db2 backup db xcatdb user xcatdb using $pw ONLINE to $::PATH";
$rc = &rundb2cmd($cmd); # must su to xcatdb
if ($rc != 0)
{
xCAT::MsgUtils->message("E", " $cmd error.");
return 1;
xCAT::MsgUtils->message("E", " $cmd error.");
return 1;
}
return 0;
}
#-----------------------------------------------------------------------------
=head3 PG_bindump
@ -271,53 +278,57 @@ sub DB2_bindump
=cut
#-----------------------------------------------------------------------------
sub PG_bindump
sub PG_bindump
{
my $msg;
my $rc=0;
my $pgcmddir = "/usr/bin";
my $rc = 0;
my $pgcmddir = "/usr/bin";
# get path to Postgresql commands if running 9.X version
my $cmd = "rpm -qa | grep postgresql";
my @output=xCAT::Utils->runcmd($cmd, 0);
my @output = xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{
my $message =
"\nPostgreSQL is not installed. If on AIX, it should be first obtained from the xcat dependency tarballs and installed before running this command.\n If on Linux, install from the OS CDs.";
xCAT::MsgUtils->message("E", " $cmd failed. $message");
exit(1);
my $message =
"\nPostgreSQL is not installed. If on AIX, it should be first obtained from the xcat dependency tarballs and installed before running this command.\n If on Linux, install from the OS CDs.";
xCAT::MsgUtils->message("E", " $cmd failed. $message");
exit(1);
}
# check if 9.X release, setup different
if (grep(/postgresql9/, @output)) { # postgresql 9.x
# figure out which 9.x release and build path
# for example 9.x release /usr/pgsql-9.x/bin
my @parseout= split(/\-/, $output[0]);
my @ptflevel= split ("postgresql9",$parseout[0]);
my $postgres9=@ptflevel[1]; # set it to the PTF level
$pgcmddir = "/usr/pgsql-9.$postgres9/bin"; # pg cmds location
if (grep(/postgresql9/, @output)) { # postgresql 9.x
# figure out which 9.x release and build path
# for example 9.x release /usr/pgsql-9.x/bin
my @parseout = split(/\-/, $output[0]);
my @ptflevel = split("postgresql9", $parseout[0]);
my $postgres9 = @ptflevel[1]; # set it to the PTF level
$pgcmddir = "/usr/pgsql-9.$postgres9/bin"; # pg cmds location
}
# Get database, admin from cfgloc file
my $cmd="cat /etc/xcat/cfgloc";
my $info=xCAT::Utils->runcmd($cmd, -1);
my $cmd = "cat /etc/xcat/cfgloc";
my $info = xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("E", "Cannot read /etc/xcat/cfgloc.");
return 1;
xCAT::MsgUtils->message("E", "Cannot read /etc/xcat/cfgloc.");
return 1;
}
chomp($info);
my ($db,$admin,$pw) = split(/\|/, $info);
my ($info1,$info2) = split(/=/,$db);
my ($dbname,$host) = split(/;/,$info2);
chomp($info);
my ($db, $admin, $pw) = split(/\|/, $info);
my ($info1, $info2) = split(/=/, $db);
my ($dbname, $host) = split(/;/, $info2);
# create backup file name
my $backupfile="$::PATH/pgbackup.$$";
my $cmd="$pgcmddir/pg_dump $dbname -f $backupfile -U postgres -F custom";
my $info=xCAT::Utils->runcmd($cmd, -1);
my $backupfile = "$::PATH/pgbackup.$$";
my $cmd = "$pgcmddir/pg_dump $dbname -f $backupfile -U postgres -F custom";
my $info = xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("E", "$cmd failed");
return 1;
xCAT::MsgUtils->message("E", "$cmd failed");
return 1;
}
return 0;
}
#-----------------------------------------------------------------------------
=head3 rundb2cmd
@ -327,6 +338,7 @@ sub PG_bindump
Input: command
=cut
#-----------------------------------------------------------------------------
sub rundb2cmd
{

View File

@ -7,9 +7,9 @@
BEGIN
{
$::XCATROOT =
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
}
use lib "$::XCATROOT/lib/perl";
use Getopt::Long;
@ -34,32 +34,33 @@ use strict;
my $rc = 0;
&parse_args;
if ($::BINARY) { # not using xCAT to dump, using the database utility
my $DBname = xCAT::Utils->get_DBName;
if ($DBname eq "DB2") {
$rc=&DB2_binrestore;
if ($rc == 0) {
xCAT::MsgUtils->message("I", "Restore Complete. You can now restart the daemons.");
} else {
xCAT::MsgUtils->message("E", "Restore Failed.");
}
exit $rc;
} else {
if ($DBname eq "PG") {
$rc=&PG_binrestore;
if ($rc == 0) {
xCAT::MsgUtils->message("I", "Restore Complete.");
} else {
xCAT::MsgUtils->message("I", "Restore Failed.");
}
exit $rc;
} else {
xCAT::MsgUtils->message("E",
"Binary dump (-b) is not supported for $DBname");
exit 1;
}
}
if ($::BINARY) { # not using xCAT to dump, using the database utility
my $DBname = xCAT::Utils->get_DBName;
if ($DBname eq "DB2") {
$rc = &DB2_binrestore;
if ($rc == 0) {
xCAT::MsgUtils->message("I", "Restore Complete. You can now restart the daemons.");
} else {
xCAT::MsgUtils->message("E", "Restore Failed.");
}
exit $rc;
} else {
if ($DBname eq "PG") {
$rc = &PG_binrestore;
if ($rc == 0) {
xCAT::MsgUtils->message("I", "Restore Complete.");
} else {
xCAT::MsgUtils->message("I", "Restore Failed.");
}
exit $rc;
} else {
xCAT::MsgUtils->message("E",
"Binary dump (-b) is not supported for $DBname");
exit 1;
}
}
}
# read all the *.csv files from the input directory and restore the database
opendir DIRPATH, $::PATH;
if ($? != 0)
@ -68,11 +69,12 @@ if ($? != 0)
xCAT::MsgUtils->message("E", $msg);
exit 1;
}
# read tables to skip during restore from site.skiptables attribute
my @output2=xCAT::TableUtils->get_site_attribute('skiptables');
my @output2 = xCAT::TableUtils->get_site_attribute('skiptables');
my @skiptbls;
if (@output2) {
@skiptbls = split (/\,/,$output2[0]);
@skiptbls = split(/\,/, $output2[0]);
}
my @files = readdir(DIRPATH);
@ -83,38 +85,40 @@ foreach my $table (@files)
my $tablename = $::PATH;
$tablename .= "/";
$tablename .= $table;
if ( (!$::ALL) && (($table =~ /^eventlog/) || ($table =~ /^auditlog/))) {
if ($::VERBOSEREST) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
if ((!$::ALL) && (($table =~ /^eventlog/) || ($table =~ /^auditlog/))) {
if ($::VERBOSEREST) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
}
# skip teal tables
if ( $table =~ /^x_teal/ ) {
if ($::VERBOSEREST) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
if ($table =~ /^x_teal/) {
if ($::VERBOSEREST) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
}
# skip ISNM tables except isnm_config
if ( $table =~ /^isnm_perf/ ) {
if ($::DUMPVERBOSE) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
if ($table =~ /^isnm_perf/) {
if ($::DUMPVERBOSE) {
xCAT::MsgUtils->message("I", "Skipping $table\n");
}
next;
}
# skip and table in the site.skiptables attribute
if (@skiptbls) {
my ($tmptable,$suffix) = split(/\./,$table);
chomp $tmptable;
if (grep(/^$tmptable$/, @skiptbls)) {
if ($::VERBOSEREST) {
xCAT::MsgUtils->message("I", "Skipping $tmptable\n");
my ($tmptable, $suffix) = split(/\./, $table);
chomp $tmptable;
if (grep(/^$tmptable$/, @skiptbls)) {
if ($::VERBOSEREST) {
xCAT::MsgUtils->message("I", "Skipping $tmptable\n");
}
next;
}
next;
}
}
my $cmd = "tabrestore $tablename";
@ -123,9 +127,9 @@ foreach my $table (@files)
{ # error
xCAT::MsgUtils->message("E", "Error running $cmd, @errout\n");
} else {
if ($::VERBOSEREST) {
xCAT::MsgUtils->message("I", "Restoring $table.\n");
}
if ($::VERBOSEREST) {
xCAT::MsgUtils->message("I", "Restoring $table.\n");
}
}
}
}
@ -145,20 +149,20 @@ exit $rc;
sub parse_args
{
my $msg;
my $usagemsg =
" restorexCATdb -h \n restorexCATdb -v \n restorexCATdb [-a] [-V] <-p> [path to restore .csv files]\n restorexCATdb -b [-V] <-t> [timestamp on restore backup file] <-p> [path to restore backup file]";
my $usagemsg =
" restorexCATdb -h \n restorexCATdb -v \n restorexCATdb [-a] [-V] <-p> [path to restore .csv files]\n restorexCATdb -b [-V] <-t> [timestamp on restore backup file] <-p> [path to restore backup file]";
Getopt::Long::Configure("posix_default");
Getopt::Long::Configure("no_gnu_compat");
Getopt::Long::Configure("bundling");
if (
!GetOptions(
'a|all' => \$::ALL,
'b|binary' => \$::BINARY,
'p|path=s' => \$::PATH,
't|timestamp=s' => \$::TIMESTAMP,
'h|help' => \$::HELP,
'V|verbose' => \$::VERBOSEREST,
'v|version' => \$::VERSION
'a|all' => \$::ALL,
'b|binary' => \$::BINARY,
'p|path=s' => \$::PATH,
't|timestamp=s' => \$::TIMESTAMP,
'h|help' => \$::HELP,
'V|verbose' => \$::VERBOSEREST,
'v|version' => \$::VERSION
)
)
@ -192,6 +196,7 @@ sub parse_args
}
}
#-----------------------------------------------------------------------------
=head3 DB2_binrestore
@ -204,50 +209,54 @@ sub parse_args
sub DB2_binrestore
{
my $msg;
my $rc=0;
if (!($::TIMESTAMP)){
xCAT::MsgUtils->message("E", "To restore from a binary backup, the timestamp of the backup must be provided with the -t option.");
return 1;
my $rc = 0;
if (!($::TIMESTAMP)) {
xCAT::MsgUtils->message("E", "To restore from a binary backup, the timestamp of the backup must be provided with the -t option.");
return 1;
}
# check to see if xcatd running. Cannot restore if it is
my $cmd = "ps -ef | grep xcatd";
my @output=xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC == 0) { # found something
if (grep(/xcatd: SSL listener/, @output)) { # xcatd running
xCAT::MsgUtils->message("E", "xcatd is still accessing the database. All applications accessing the DB2 database must be stopped before you can restore.");
return 1;
my @output = xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC == 0) { # found something
if (grep(/xcatd: SSL listener/, @output)) { # xcatd running
xCAT::MsgUtils->message("E", "xcatd is still accessing the database. All applications accessing the DB2 database must be stopped before you can restore.");
return 1;
}
}
}
# get password from cfgloc
my $cmd="cat /etc/xcat/cfgloc";
my $info=xCAT::Utils->runcmd($cmd, -1);
my $cmd = "cat /etc/xcat/cfgloc";
my $info = xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("E", "Cannot read /etc/xcat/cfgloc.");
return 1;
xCAT::MsgUtils->message("E", "Cannot read /etc/xcat/cfgloc.");
return 1;
}
chomp($info);
my ($db,$inst,$pw) = split(/\|/, $info);
my ($db, $inst, $pw) = split(/\|/, $info);
# Hopefully nothing else is accessing the database, so try restore
$cmd="db2 restore db xcatdb user xcatdb using $pw from $::PATH taken at $::TIMESTAMP";
$rc = &rundb2cmd($cmd); # must su to xcatdb
$cmd = "db2 restore db xcatdb user xcatdb using $pw from $::PATH taken at $::TIMESTAMP";
$rc = &rundb2cmd($cmd); # must su to xcatdb
if ($rc != 0)
{
xCAT::MsgUtils->message("E", " $cmd error.");
return 1;
xCAT::MsgUtils->message("E", " $cmd error.");
return 1;
}
# Now roll forward any tranactions since the backup
$cmd="db2 rollforward database xcatdb to end of logs and complete";
$rc = &rundb2cmd($cmd); # must su to xcatdb
$cmd = "db2 rollforward database xcatdb to end of logs and complete";
$rc = &rundb2cmd($cmd); # must su to xcatdb
if ($rc != 0)
{
xCAT::MsgUtils->message("E", " $cmd error.");
return 1;
xCAT::MsgUtils->message("E", " $cmd error.");
return 1;
}
return 0;
}
#-----------------------------------------------------------------------------
=head3 PG_binrestore
@ -257,52 +266,56 @@ sub DB2_binrestore
=cut
#-----------------------------------------------------------------------------
sub PG_binrestore
sub PG_binrestore
{
my $msg;
my $rc=0;
my $pgcmddir = "/usr/bin";
my $rc = 0;
my $pgcmddir = "/usr/bin";
# get path to Postgresql commands if running 9.X version
my $cmd = "rpm -qa | grep postgresql";
my @output=xCAT::Utils->runcmd($cmd, 0);
my @output = xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{
my $message =
"\nPostgreSQL is not installed. If on AIX, it should be first obtained from the xcat dependency tarballs and installed before running this command.\n If on Linux, install from the OS CDs.";
xCAT::MsgUtils->message("E", " $cmd failed. $message");
exit(1);
my $message =
"\nPostgreSQL is not installed. If on AIX, it should be first obtained from the xcat dependency tarballs and installed before running this command.\n If on Linux, install from the OS CDs.";
xCAT::MsgUtils->message("E", " $cmd failed. $message");
exit(1);
}
# check if 9.X release, setup different
if (grep(/postgresql9/, @output)) { # postgresql 9.x
# figure out which 9.x release and build path
# for example 9.x release /usr/pgsql-9.x/bin
my @parseout= split(/\-/, $output[0]);
my @ptflevel= split ("postgresql9",$parseout[0]);
my $postgres9=@ptflevel[1]; # set it to the PTF level
$pgcmddir = "/usr/pgsql-9.$postgres9/bin"; # pg cmds location
if (grep(/postgresql9/, @output)) { # postgresql 9.x
# figure out which 9.x release and build path
# for example 9.x release /usr/pgsql-9.x/bin
my @parseout = split(/\-/, $output[0]);
my @ptflevel = split("postgresql9", $parseout[0]);
my $postgres9 = @ptflevel[1]; # set it to the PTF level
$pgcmddir = "/usr/pgsql-9.$postgres9/bin"; # pg cmds location
}
# Get database, admin from cfgloc file
my $cmd="cat /etc/xcat/cfgloc";
my $info=xCAT::Utils->runcmd($cmd, -1);
my $cmd = "cat /etc/xcat/cfgloc";
my $info = xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("E", "Cannot read /etc/xcat/cfgloc.");
return 1;
xCAT::MsgUtils->message("E", "Cannot read /etc/xcat/cfgloc.");
return 1;
}
chomp($info);
my ($db,$admin,$pw) = split(/\|/, $info);
my ($info1,$info2) = split(/=/,$db);
my ($dbname,$host) = split(/;/,$info2);
chomp($info);
my ($db, $admin, $pw) = split(/\|/, $info);
my ($info1, $info2) = split(/=/, $db);
my ($dbname, $host) = split(/;/, $info2);
# restore from backup file
my $cmd="$pgcmddir/pg_restore $::PATH -U postgres -d $dbname -c ";
my $info=xCAT::Utils->runcmd($cmd, -1);
my $cmd = "$pgcmddir/pg_restore $::PATH -U postgres -d $dbname -c ";
my $info = xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("E", "$cmd failed");
return 1;
xCAT::MsgUtils->message("E", "$cmd failed");
return 1;
}
return 0;
}
#-----------------------------------------------------------------------------
=head3 rundb2cmd
@ -312,6 +325,7 @@ sub PG_binrestore
Input: command
=cut
#-----------------------------------------------------------------------------
sub rundb2cmd
{

View File

@ -12,11 +12,11 @@ use xCAT::Utils;
use Getopt::Long;
sub usage {
print "Usage: tabrestore <tablename>.csv\n";
print " tabrestore -a <tablename>.csv\n";
print " tabrestore [-?|-h|--help]\n";
print " tabrestore [-v|--version]\n";
exit $_[0];
print "Usage: tabrestore <tablename>.csv\n";
print " tabrestore -a <tablename>.csv\n";
print " tabrestore [-?|-h|--help]\n";
print " tabrestore [-v|--version]\n";
exit $_[0];
}
#my $bname = basename($0);
@ -26,48 +26,48 @@ $cmdref->{command}->[0] = "tabrestore";
# Get the options
my $HELP;
if (
!GetOptions(
'h|?|help' => \$HELP,
'v|version' => \$VERSION,
'a|addrows' => \$ADDROWS,
)
)
!GetOptions(
'h|?|help' => \$HELP,
'v|version' => \$VERSION,
'a|addrows' => \$ADDROWS,
)
)
{ usage(1); }
my $arg=shift(@ARGV);
my $arg = shift(@ARGV);
while ($arg =~ /^-/) {
push (@{$cmdref->{arg}}, $arg);
$arg=shift(@ARGV);
push(@{ $cmdref->{arg} }, $arg);
$arg = shift(@ARGV);
}
if ($VERSION)
{
my $version = xCAT::Utils->Version();
print "$version\n";
exit 0;
my $version = xCAT::Utils->Version();
print "$version\n";
exit 0;
}
if ($HELP)
{
usage;
usage;
}
if ($ADDROWS)
{
$cmdref->{addrows}->[0] = "yes";
$cmdref->{addrows}->[0] = "yes";
}
unless ($arg) { usage(2); } # no filename specified
unless ($arg) { usage(2); } # no filename specified
# Open the specified table file and put its contents in the data key
my $filename = $arg;
my $tabname = basename($filename);
my $tabname = basename($filename);
$tabname =~ s/\..*//;
$cmdref->{table}->[0] = $tabname;
my $fh;
unless (open($fh,$filename)) { print "Error: Unable to open $arg for reading.\n"; exit 3; }
unless (open($fh, $filename)) { print "Error: Unable to open $arg for reading.\n"; exit 3; }
while (<$fh>) {
push @{$cmdref->{data}},$_;
push @{ $cmdref->{data} }, $_;
}
xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response);
xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response);
exit $xCAT::Client::EXITCODE;

View File

@ -6,20 +6,20 @@ while (<STDIN>) {
my $node;
my $output;
if (/:/) {
($node,$output) = split /:/,$_,2;
($node, $output) = split /:/, $_, 2;
} else {
$node= "UNKNOWN";
$node = "UNKNOWN";
$output = $_;
}
$output =~ s/^ //;
$output{$node}.=$output;
$output{$node} .= $output;
}
my %collated;
foreach (keys %output) {
$collated{$output{$_}}->{$_}=1;
$collated{ $output{$_} }->{$_} = 1;
}
foreach (keys %collated) {
my $nodes = join(',',sort (keys %{$collated{$_}}));
my $nodes = join(',', sort (keys %{ $collated{$_} }));
print "====================================\n";
print "$nodes\n";
print "====================================\n";

View File

@ -6,9 +6,9 @@
BEGIN
{
$::XCATROOT =
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
}
use lib "$::XCATROOT/lib/perl";
use Getopt::Long;
@ -79,7 +79,7 @@ sub parse_args
my $msg;
my $usagemsg;
$usagemsg =
"groupfiles4dsh -h \ngroupfiles4dsh -v \ngroupfiles4dsh [-p] [path to group files directory]";
"groupfiles4dsh -h \ngroupfiles4dsh -v \ngroupfiles4dsh [-p] [path to group files directory]";
Getopt::Long::Configure("posix_default");
Getopt::Long::Configure("no_gnu_compat");
Getopt::Long::Configure("bundling");

View File

@ -8,17 +8,19 @@
# done relative to that.
use strict;
#use lib '.';
use Pod::Man;
use Pod::Html;
my $poddir = 'pods';
my $mandir = 'share/man';
my $htmldir = 'share/doc';
my $poddir = 'pods';
my $mandir = 'share/man';
my $htmldir = 'share/doc';
my $cachedir = "$ENV{'HOME'}/tmp";
if (system("mkdir -p $cachedir")) { die "Error: could not create $cachedir.\n"; }
my @pods = getPodList($poddir);
#foreach (@pods) { print "$_\n"; } exit;
# Build the cmd overview page.
@ -30,12 +32,12 @@ push @pods, "$poddir/man1/xcat.1.pod";
print "Converting PODs to man pages...\n";
foreach my $podfile (@pods) {
my $manfile = $podfile;
$manfile =~ s/^$poddir/$mandir/; # change the beginning of the path
$manfile =~ s/\.pod$//; # change the ending
$manfile =~ s/^$poddir/$mandir/; # change the beginning of the path
$manfile =~ s/\.pod$//; # change the ending
my $mdir = $manfile;
$mdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $mdir")) { die "Error: could not create $mdir.\n"; }
my ($section) = $podfile =~ /\.(\d+)\.pod$/;
$mdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $mdir")) { die "Error: could not create $mdir.\n"; }
my ($section) = $podfile =~ /\.(\d+)\.pod$/;
convertpod2man($podfile, $manfile, $section);
}
@ -44,15 +46,17 @@ my @dummyPods = createDummyPods($poddir, \@pods);
# Build the html page for each pod.
#mkdir($htmldir) or die "Error: could not create $htmldir.\n";
print "Converting PODs to HTML pages...\n";
# have to clear the cache, because old entries can cause a problem
unlink("$cachedir/pod2htmd.tmp", "$cachedir/pod2htmi.tmp");
foreach my $podfile (@pods) {
my $htmlfile = $podfile;
$htmlfile =~ s/^$poddir/$htmldir/; # change the beginning of the path
$htmlfile =~ s/\.pod$/\.html/; # change the ending
$htmlfile =~ s/^$poddir/$htmldir/; # change the beginning of the path
$htmlfile =~ s/\.pod$/\.html/; # change the ending
my $hdir = $htmlfile;
$hdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $hdir")) { die "Error: could not create $hdir.\n"; }
$hdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $hdir")) { die "Error: could not create $hdir.\n"; }
#print "$podfile, $htmlfile, $poddir, $htmldir\n";
convertpod2html($podfile, $htmlfile, $poddir, $htmldir);
}
@ -69,75 +73,80 @@ exit;
# if that pod does not exist, create an empty one that will satisfy pod2html
# keep track of all dummy pods created, so they can be removed later
sub createDummyPods {
my ($poddir, $pods) = @_;
my $cmd = "grep -r -E 'L<.+\\([57]\\)\\|.+\\.[57]>' " . $poddir;
#print "Running cmd: ", $cmd, "\n";
my @lines = `$cmd`;
if ($?) { print "Did not find any section 5 man page, creating dummy pods...\n"; print join('', @lines); }
#my @lines;
#system($cmd);
my @dummyPods;
foreach my $l (@lines) {
#print "$l\n";
my @matches = $l =~ /L<([^\(]+)\(([57])\)\|\1\.[57]>/g; # get all the matches in the line
# The above line should create the array with every other entry being the man page name
# and every other entry is the section # (5 or 7)
my $cmd;
while ($cmd=shift @matches) {
#foreach my $m (@matches) {
my $section = shift @matches;
my $filename = "$poddir/man$section/$cmd.$section.pod";
#print "$filename\n";
if (!(grep /^$filename$/, @$pods) && !(grep /^$filename$/, @dummyPods)) { push @dummyPods, $filename; }
}
}
# Also add xcattest.1.pod and buildkit.1.pod, because the xcat.1.pod summary page refers to it
push @dummyPods, "$poddir/man1/xcattest.1.pod";
push @dummyPods, "$poddir/man1/buildkit.1.pod";
# Create these empty files
print "Creating empty linked-to files: ", join(', ', @dummyPods), "\n";
mkdir "$poddir/man7";
foreach my $d (@dummyPods) {
if (!open(TMP, ">>$d")) { warn "Could not create dummy pod file $d ($!)\n"; }
else { close TMP; }
}
return @dummyPods;
my ($poddir, $pods) = @_;
my $cmd = "grep -r -E 'L<.+\\([57]\\)\\|.+\\.[57]>' " . $poddir;
#print "Running cmd: ", $cmd, "\n";
my @lines = `$cmd`;
if ($?) { print "Did not find any section 5 man page, creating dummy pods...\n"; print join('', @lines); }
#my @lines;
#system($cmd);
my @dummyPods;
foreach my $l (@lines) {
#print "$l\n";
my @matches = $l =~ /L<([^\(]+)\(([57])\)\|\1\.[57]>/g; # get all the matches in the line
# The above line should create the array with every other entry being the man page name
# and every other entry is the section # (5 or 7)
my $cmd;
while ($cmd = shift @matches) {
#foreach my $m (@matches) {
my $section = shift @matches;
my $filename = "$poddir/man$section/$cmd.$section.pod";
#print "$filename\n";
if (!(grep /^$filename$/, @$pods) && !(grep /^$filename$/, @dummyPods)) { push @dummyPods, $filename; }
}
}
# Also add xcattest.1.pod and buildkit.1.pod, because the xcat.1.pod summary page refers to it
push @dummyPods, "$poddir/man1/xcattest.1.pod";
push @dummyPods, "$poddir/man1/buildkit.1.pod";
# Create these empty files
print "Creating empty linked-to files: ", join(', ', @dummyPods), "\n";
mkdir "$poddir/man7";
foreach my $d (@dummyPods) {
if (!open(TMP, ">>$d")) { warn "Could not create dummy pod file $d ($!)\n"; }
else { close TMP; }
}
return @dummyPods;
}
# Recursively get the list of pod man page files.
sub getPodList {
my $poddir = shift;
my @files;
my $poddir = shift;
my @files;
# 1st get toplevel dir listing
opendir(DIR, $poddir) or die "Error: could not read $poddir.\n";
my @topdir = grep !/^\./, readdir(DIR); # /
close(DIR);
# 1st get toplevel dir listing
opendir(DIR, $poddir) or die "Error: could not read $poddir.\n";
my @topdir = grep !/^\./, readdir(DIR); # /
close(DIR);
# Now go thru each subdir (these are man1, man3, etc.)
foreach my $mandir (@topdir) {
opendir(DIR, "$poddir/$mandir") or die "Error: could not read $poddir/$mandir.\n";
my @dir = grep !/^\./, readdir(DIR); # /
close(DIR);
foreach my $file (@dir) {
push @files, "$poddir/$mandir/$file";
}
}
return sort @files;
# Now go thru each subdir (these are man1, man3, etc.)
foreach my $mandir (@topdir) {
opendir(DIR, "$poddir/$mandir") or die "Error: could not read $poddir/$mandir.\n";
my @dir = grep !/^\./, readdir(DIR); # /
close(DIR);
foreach my $file (@dir) {
push @files, "$poddir/$mandir/$file";
}
}
return sort @files;
}
# Create the xcat man page that gives a summary description of each xcat cmd.
sub writesummarypage {
my $file = shift; # relative path file name of the man page
# the rest of @_ contains the pod files that describe each cmd
my $file = shift; # relative path file name of the man page
# the rest of @_ contains the pod files that describe each cmd
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
print FILE <<'EOS1';
print FILE <<'EOS1';
=head1 NAME
B<xcat> - extreme Cluster Administration Tool.
@ -168,56 +177,58 @@ i.e. all the commands in section 1, then the commands in section 3, etc.
=over 12
EOS1
# extract the summary for each cmd from its man page
foreach my $manpage (@_) {
my ($cmd, $sectionnum) = $manpage =~ /([^\/]+)\.(\d+)\.pod$/;
# Suck in the whole file, then we will parse it.
open(MANPAGE, "$manpage") or die "Error: could not open $manpage for reading.\n";
my @contents = <MANPAGE>;
my $wholemanpage = join('', @contents);
close(MANPAGE);
# This regex matches: optional space, =head1, space, title, space, cmd, space, description, newline
my ($description) = $wholemanpage =~ /^\s*=head1\s+\S+\s+\S+\s+(.+?)\n/si;
if (!defined($description)) { print "Warning: $manpage does not have a description for $cmd. It will be ignored.\n"; next; }
$description =~ s/^-\s*//; # if the description has a leading hypen, strip it off
print FILE "\n=item L<$cmd($sectionnum)|$cmd.$sectionnum>\n\n".$description."\n";
}
# extract the summary for each cmd from its man page
foreach my $manpage (@_) {
my ($cmd, $sectionnum) = $manpage =~ /([^\/]+)\.(\d+)\.pod$/;
# Artificially add the xcattest and buildkit cmds,
# because the xCAT-test and xCAT-buildkit rpms will add these
print FILE "\n=item L<xcattest(1)|xcattest.1>\n\nRun automated xCAT test cases.\n";
print FILE "\n=item L<buildkit(1)|buildkit.1>\n\nBuild product software kits to be installed in an xCAT cluster.\n";
# Suck in the whole file, then we will parse it.
open(MANPAGE, "$manpage") or die "Error: could not open $manpage for reading.\n";
my @contents = <MANPAGE>;
my $wholemanpage = join('', @contents);
close(MANPAGE);
print FILE <<"EOS3";
# This regex matches: optional space, =head1, space, title, space, cmd, space, description, newline
my ($description) = $wholemanpage =~ /^\s*=head1\s+\S+\s+\S+\s+(.+?)\n/si;
if (!defined($description)) { print "Warning: $manpage does not have a description for $cmd. It will be ignored.\n"; next; }
$description =~ s/^-\s*//; # if the description has a leading hypen, strip it off
print FILE "\n=item L<$cmd($sectionnum)|$cmd.$sectionnum>\n\n" . $description . "\n";
}
# Artificially add the xcattest and buildkit cmds,
# because the xCAT-test and xCAT-buildkit rpms will add these
print FILE "\n=item L<xcattest(1)|xcattest.1>\n\nRun automated xCAT test cases.\n";
print FILE "\n=item L<buildkit(1)|buildkit.1>\n\nBuild product software kits to be installed in an xCAT cluster.\n";
print FILE <<"EOS3";
=back
EOS3
close FILE;
close FILE;
}
# Create the html page for one pod.
sub convertpod2html {
my ($podfile, $htmlfile, $poddir, $htmldir) = @_;
my ($podfile, $htmlfile, $poddir, $htmldir) = @_;
#TODO: use --css=<stylesheet> and --title=<pagetitle> to make the pages look better
pod2html($podfile,
"--outfile=$htmlfile",
"--podpath=man1:man3:man5:man7:man8",
"--podroot=$poddir",
"--htmldir=$htmldir",
"--recurse",
"--cachedir=$cachedir",
);
#TODO: use --css=<stylesheet> and --title=<pagetitle> to make the pages look better
pod2html($podfile,
"--outfile=$htmlfile",
"--podpath=man1:man3:man5:man7:man8",
"--podroot=$poddir",
"--htmldir=$htmldir",
"--recurse",
"--cachedir=$cachedir",
);
}
# Create the man page for one pod.
sub convertpod2man {
my ($podfile, $manfile, $section) = @_;
my ($podfile, $manfile, $section) = @_;
my $parser = Pod::Man->new(section => $section);
my $parser = Pod::Man->new(section => $section);
$parser->parse_from_file($podfile, $manfile);
}

View File

@ -8,16 +8,18 @@
# done relative to that.
use strict;
#use lib '.';
use Pod::Man;
use Pod::Html;
my $poddir = 'pods';
my $mandir = 'share/man';
my $htmldir = 'share/doc';
my $poddir = 'pods';
my $mandir = 'share/man';
my $htmldir = 'share/doc';
my $cachedir = '/tmp';
my @pods = getPodList($poddir);
#foreach (@pods) { print "$_\n"; } exit;
# Build the cmd overview page.
@ -28,12 +30,12 @@ my @pods = getPodList($poddir);
print "Converting PODs to man pages...\n";
foreach my $podfile (@pods) {
my $manfile = $podfile;
$manfile =~ s/^$poddir/$mandir/; # change the beginning of the path
$manfile =~ s/\.pod$//; # change the ending
$manfile =~ s/^$poddir/$mandir/; # change the beginning of the path
$manfile =~ s/\.pod$//; # change the ending
my $mdir = $manfile;
$mdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $mdir")) { die "Error: could not create $mdir.\n"; }
my ($section) = $podfile =~ /\.(\d+)\.pod$/;
$mdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $mdir")) { die "Error: could not create $mdir.\n"; }
my ($section) = $podfile =~ /\.(\d+)\.pod$/;
convertpod2man($podfile, $manfile, $section);
}
@ -42,15 +44,17 @@ my @dummyPods = createDummyPods($poddir, \@pods);
# Build the html page for each pod.
#mkdir($htmldir) or die "Error: could not create $htmldir.\n";
print "Converting PODs to HTML pages...\n";
# have to clear the cache, because old entries can cause a problem
unlink("$cachedir/pod2htmd.tmp", "$cachedir/pod2htmi.tmp");
foreach my $podfile (@pods) {
my $htmlfile = $podfile;
$htmlfile =~ s/^$poddir/$htmldir/; # change the beginning of the path
$htmlfile =~ s/\.pod$/\.html/; # change the ending
$htmlfile =~ s/^$poddir/$htmldir/; # change the beginning of the path
$htmlfile =~ s/\.pod$/\.html/; # change the ending
my $hdir = $htmlfile;
$hdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $hdir")) { die "Error: could not create $hdir.\n"; }
$hdir =~ s|/[^/]*$||; # get rid of the basename part
if (system("mkdir -p $hdir")) { die "Error: could not create $hdir.\n"; }
#print "$podfile, $htmlfile, $poddir, $htmldir\n";
convertpod2html($podfile, $htmlfile, $poddir, $htmldir);
}
@ -67,72 +71,77 @@ exit;
# if that pod does not exist, create an empty one that will satisfy pod2html
# keep track of all dummy pods created, so they can be removed later
sub createDummyPods {
my ($poddir, $pods) = @_;
my $cmd = "grep -r -E 'L<.+\\([57]\\)\\|.+\\.[57]>' " . $poddir;
#print "Running cmd: ", $cmd, "\n";
my @lines = `$cmd`;
if ($?) { print "Did not find any section 5 man page, creating dummy pods...\n"; print join('', @lines); }
#my @lines;
#system($cmd);
my @dummyPods;
foreach my $l (@lines) {
#print "$l\n";
my @matches = $l =~ /L<([^\(]+)\(([57])\)\|\1\.[57]>/g; # get all the matches in the line
# The above line should create the array with every other entry being the man page name
# and every other entry is the section # (5 or 7)
my $cmd;
while ($cmd=shift @matches) {
#foreach my $m (@matches) {
my $section = shift @matches;
my $filename = "$poddir/man$section/$cmd.$section.pod";
#print "$filename\n";
if (!(grep /^$filename$/, @$pods) && !(grep /^$filename$/, @dummyPods)) { push @dummyPods, $filename; }
}
}
# Create these empty files
print "Creating empty linked-to files: ", join(', ', @dummyPods), "\n";
mkdir "$poddir/man7";
foreach my $d (@dummyPods) {
if (!open(TMP, ">>$d")) { warn "Could not create dummy pod file $d ($!)\n"; }
else { close TMP; }
}
return @dummyPods;
my ($poddir, $pods) = @_;
my $cmd = "grep -r -E 'L<.+\\([57]\\)\\|.+\\.[57]>' " . $poddir;
#print "Running cmd: ", $cmd, "\n";
my @lines = `$cmd`;
if ($?) { print "Did not find any section 5 man page, creating dummy pods...\n"; print join('', @lines); }
#my @lines;
#system($cmd);
my @dummyPods;
foreach my $l (@lines) {
#print "$l\n";
my @matches = $l =~ /L<([^\(]+)\(([57])\)\|\1\.[57]>/g; # get all the matches in the line
# The above line should create the array with every other entry being the man page name
# and every other entry is the section # (5 or 7)
my $cmd;
while ($cmd = shift @matches) {
#foreach my $m (@matches) {
my $section = shift @matches;
my $filename = "$poddir/man$section/$cmd.$section.pod";
#print "$filename\n";
if (!(grep /^$filename$/, @$pods) && !(grep /^$filename$/, @dummyPods)) { push @dummyPods, $filename; }
}
}
# Create these empty files
print "Creating empty linked-to files: ", join(', ', @dummyPods), "\n";
mkdir "$poddir/man7";
foreach my $d (@dummyPods) {
if (!open(TMP, ">>$d")) { warn "Could not create dummy pod file $d ($!)\n"; }
else { close TMP; }
}
return @dummyPods;
}
# Recursively get the list of pod man page files.
sub getPodList {
my $poddir = shift;
my @files;
my $poddir = shift;
my @files;
# 1st get toplevel dir listing
opendir(DIR, $poddir) or die "Error: could not read $poddir.\n";
my @topdir = grep !/^\./, readdir(DIR); # /
close(DIR);
# 1st get toplevel dir listing
opendir(DIR, $poddir) or die "Error: could not read $poddir.\n";
my @topdir = grep !/^\./, readdir(DIR); # /
close(DIR);
# Now go thru each subdir (these are man1, man3, etc.)
foreach my $mandir (@topdir) {
opendir(DIR, "$poddir/$mandir") or die "Error: could not read $poddir/$mandir.\n";
my @dir = grep !/^\./, readdir(DIR); # /
close(DIR);
foreach my $file (@dir) {
push @files, "$poddir/$mandir/$file";
}
}
return sort @files;
# Now go thru each subdir (these are man1, man3, etc.)
foreach my $mandir (@topdir) {
opendir(DIR, "$poddir/$mandir") or die "Error: could not read $poddir/$mandir.\n";
my @dir = grep !/^\./, readdir(DIR); # /
close(DIR);
foreach my $file (@dir) {
push @files, "$poddir/$mandir/$file";
}
}
return sort @files;
}
# Create the xcat man page that gives a summary description of each xcat cmd.
sub writesummarypage {
my $file = shift; # relative path file name of the man page
# the rest of @_ contains the pod files that describe each cmd
my $file = shift; # relative path file name of the man page
# the rest of @_ contains the pod files that describe each cmd
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
open(FILE, ">$file") or die "Error: could not open $file for writing.\n";
print FILE <<'EOS1';
print FILE <<'EOS1';
=head1 NAME
B<xcat> - extreme Cluster Administration Tool.
@ -158,56 +167,58 @@ i.e. all the commands in section 1, then the commands in section 3, etc.
=over 12
EOS1
# extract the summary for each cmd from its man page
foreach my $manpage (@_) {
my ($sectionnum) = $manpage =~ /\.(\d+)\.pod$/;
# Suck in the whole file, then we will parse it.
open(MANPAGE, "$manpage") or die "Error: could not open $manpage for reading.\n";
my @contents = <MANPAGE>;
my $wholemanpage = join('', @contents);
close(MANPAGE);
# This regex matches: optional space, =head1, space, title, space, cmd, space, description, newline
my ($cmd, $description) = $wholemanpage =~ /^\s*=head1\s+\S+\s+(\S+)\s+(.+?)\n/si;
if (!defined($cmd)) { print "Warning: $manpage is not in a recognized structure. It will be ignored.\n"; next; }
if (!defined($description)) { print "Warning: $manpage does not have a description for $cmd. It will be ignored.\n"; next; }
$cmd =~ s/^.<(.+)>$/$1/; # if the cmd name has pod formatting around it, strip it off
$description =~ s/^-\s*//; # if the description has a leading hypen, strip it off
print FILE "\n=item L<$cmd($sectionnum)|$cmd.$sectionnum>\n\n".$description."\n";
}
# extract the summary for each cmd from its man page
foreach my $manpage (@_) {
my ($sectionnum) = $manpage =~ /\.(\d+)\.pod$/;
# Artificially add the xcattest cmd, because the xCAT-test rpm will add this
print FILE "\n=item L<xcattest(1)|xcattest.1>\n\nRun automated xCAT test cases.\n";
# Suck in the whole file, then we will parse it.
open(MANPAGE, "$manpage") or die "Error: could not open $manpage for reading.\n";
my @contents = <MANPAGE>;
my $wholemanpage = join('', @contents);
close(MANPAGE);
print FILE <<"EOS3";
# This regex matches: optional space, =head1, space, title, space, cmd, space, description, newline
my ($cmd, $description) = $wholemanpage =~ /^\s*=head1\s+\S+\s+(\S+)\s+(.+?)\n/si;
if (!defined($cmd)) { print "Warning: $manpage is not in a recognized structure. It will be ignored.\n"; next; }
if (!defined($description)) { print "Warning: $manpage does not have a description for $cmd. It will be ignored.\n"; next; }
$cmd =~ s/^.<(.+)>$/$1/; # if the cmd name has pod formatting around it, strip it off
$description =~ s/^-\s*//; # if the description has a leading hypen, strip it off
print FILE "\n=item L<$cmd($sectionnum)|$cmd.$sectionnum>\n\n" . $description . "\n";
}
# Artificially add the xcattest cmd, because the xCAT-test rpm will add this
print FILE "\n=item L<xcattest(1)|xcattest.1>\n\nRun automated xCAT test cases.\n";
print FILE <<"EOS3";
=back
EOS3
close FILE;
close FILE;
}
# Create the html page for one pod.
sub convertpod2html {
my ($podfile, $htmlfile, $poddir, $htmldir) = @_;
my ($podfile, $htmlfile, $poddir, $htmldir) = @_;
#TODO: use --css=<stylesheet> and --title=<pagetitle> to make the pages look better
pod2html($podfile,
"--outfile=$htmlfile",
"--podpath=man1",
"--podroot=$poddir",
"--htmldir=$htmldir",
"--recurse",
"--cachedir=$cachedir",
);
#TODO: use --css=<stylesheet> and --title=<pagetitle> to make the pages look better
pod2html($podfile,
"--outfile=$htmlfile",
"--podpath=man1",
"--podroot=$poddir",
"--htmldir=$htmldir",
"--recurse",
"--cachedir=$cachedir",
);
}
# Create the man page for one pod.
sub convertpod2man {
my ($podfile, $manfile, $section) = @_;
my ($podfile, $manfile, $section) = @_;
my $parser = Pod::Man->new(section => $section);
my $parser = Pod::Man->new(section => $section);
$parser->parse_from_file($podfile, $manfile);
}

View File

@ -7,19 +7,19 @@ my $genesisrpm = shift @ARGV;
my %rpms;
my @files = `rpm -qlp $genesisrpm`;
my $total = scalar(@files);
my $i = 0;
my $i = 0;
foreach my $f (@files) {
$i++;
print "$i/$total\r";
chomp($f);
if ($f !~ m|/opt/xcat/share/xcat/netboot/genesis/x86_64/fs|) { next; }
$f =~ s|^/opt/xcat/share/xcat/netboot/genesis/x86_64/fs||;
if (!$f || !(-e $f)) { next; } # there are files dracut creates that are not part of an rpm
my $rpm = `rpm -q --whatprovides $f`;
if ($?) { next; } # there are files dracut creates that are not part of an rpm
#print '.'; # show progress
chomp($rpm);
$rpms{$rpm} = 1;
$i++;
print "$i/$total\r";
chomp($f);
if ($f !~ m|/opt/xcat/share/xcat/netboot/genesis/x86_64/fs|) { next; }
$f =~ s|^/opt/xcat/share/xcat/netboot/genesis/x86_64/fs||;
if (!$f || !(-e $f)) { next; } # there are files dracut creates that are not part of an rpm
my $rpm = `rpm -q --whatprovides $f`;
if ($?) { next; } # there are files dracut creates that are not part of an rpm
#print '.'; # show progress
chomp($rpm);
$rpms{$rpm} = 1;
}
print "\n";
foreach my $r (sort keys %rpms) { print "$r\n"; }

View File

@ -293,7 +293,7 @@ sub get_node_ip {
}
foreach my $node (keys %nodecheckrst) {
probe_utils->send_msg("$output", "d", "$node : $nodecheckrst{$node}{error}") if(exists($nodecheckrst{$node}{error}));
probe_utils->send_msg("$output", "d", "$node : $nodecheckrst{$node}{error}") if (exists($nodecheckrst{$node}{error}));
}
return %nodeip;
@ -379,7 +379,7 @@ sub dhcp_dynamic_range_check {
} else {
push @dynamic_range, "$2-$1";
}
}
}
@ -413,16 +413,16 @@ sub dhcp_dynamic_range_check {
probe_utils->send_msg("$output", "d", "Dynamic range for net $net is @{$subnet_hash{$net}}.") if ($verbose);
if (%node_ip) {
foreach my $node (keys %node_ip) {
foreach my $dr (@{$subnet_hash{$net}}) {
my @dr_ip = split(/-/, $dr);
foreach my $node (keys %node_ip) {
foreach my $dr (@{ $subnet_hash{$net} }) {
my @dr_ip = split(/-/, $dr);
if (compare_ip_value($dr_ip[0], $node_ip{$node}) and compare_ip_value($node_ip{$node}, $dr_ip[1])) {
probe_utils->send_msg("$output", "d", "$node ip $node_ip{$node} is conflicting with dynamic range.") if ($verbose);
$rst = 1;
}
}
}
if (compare_ip_value($dr_ip[0], $node_ip{$node}) and compare_ip_value($node_ip{$node}, $dr_ip[1])) {
probe_utils->send_msg("$output", "d", "$node ip $node_ip{$node} is conflicting with dynamic range.") if ($verbose);
$rst = 1;
}
}
}
}
} else {
probe_utils->send_msg("$output", "d", "Dynamic range for net $net did not be configured.") if ($verbose);
@ -1015,17 +1015,17 @@ sub do_monitor {
my $computerpid;
my $varlogpid;
my $rst = 0;
{ #important to hold a block
if(! -e "$varlogmsg"){
{ #important to hold a block
if (!-e "$varlogmsg") {
probe_utils->send_msg("$output", "w", "$varlogmsg doesn't exist");
}
if(! -e "$clusterlog"){
if (!-e "$clusterlog") {
probe_utils->send_msg("$output", "w", "$clusterlog doesn't exist");
}
if(! -e "$computelog"){
if (!-e "$computelog") {
probe_utils->send_msg("$output", "w", "$computelog doesn't exist");
}
if(! -e "$httplog"){
if (!-e "$httplog") {
probe_utils->send_msg("$output", "w", "$httplog doesn't exist");
}
@ -1092,7 +1092,7 @@ sub do_monitor {
probe_utils->send_msg("$output", "o", "All nodes need to monitor have finished discovery process");
}
last;
}
}
sleep 0.01;
}
&dump_history;

View File

@ -8,6 +8,7 @@ use probe_utils;
use File::Basename;
use Net::Ping;
use Getopt::Long qw(:config no_ignore_case);
#use Data::Dumper;
use warnings;
@ -74,7 +75,8 @@ unless (defined($CONSISTENCY_CHECK) || defined($DEFINITION_CHECK)) {
}
if (scalar(@ARGV) >= 1) {
# After processing all the expected flags and arguments,
# After processing all the expected flags and arguments,
# there is still left over stuff on the command line
probe_utils->send_msg("$output", "f", "Invalid flag or parameter: @ARGV");
probe_utils->send_msg("$output", "d", "$::USAGE");
@ -90,20 +92,22 @@ my %node_defined_image_uuid_hash;
my %node_defined_image_name_hash;
my %osimage_defined_provmethod_hash;
my $all_nodes_provmethod = `lsdef -i provmethod -c $noderange`;
my $all_nodes_provmethod = `lsdef -i provmethod -c $noderange`;
my $all_osimage_provmethod = `lsdef -t osimage -i provmethod,rootimgdir -c`;
chomp($all_nodes_provmethod);
my @all_nodes_provmethod_lines = split("[\n\r]", $all_nodes_provmethod);
my @all_nodes_provmethod_lines = split("[\n\r]", $all_nodes_provmethod);
my @all_osimage_provmethod_lines = split("[\n\r]", $all_osimage_provmethod);
if ($all_nodes_provmethod =~ /Usage:/) {
# lsdef command displayed a Usage message. Must be some noderange formatting problem.
# Issue a warning and exit.
probe_utils->send_msg("$output", "w", "Can not get a list of nodes from specified noderange.");
exit 1;
}
if (scalar(@all_nodes_provmethod_lines) <=0) {
if (scalar(@all_nodes_provmethod_lines) <= 0) {
# There were no nodes matching the noderange. Issue a warning and exit.
probe_utils->send_msg("$output", "w", "No nodes matching the noderange were found.");
exit 1;
@ -117,22 +121,25 @@ foreach (@all_osimage_provmethod_lines) {
# First, extract diskless nodes
foreach (@all_nodes_provmethod_lines) {
# Get osimage name for the node
my ($node_name, $junk, $node_osimage_name) = split "[:=]", $_;
chomp($node_osimage_name);
if (length($node_osimage_name) > 0) {
# Get provmethod and rootimgdir for the osimage
my $osimage_provmethod_type = $osimage_defined_provmethod_hash{$node_osimage_name . ": provmethod"};
my $rootimagedir= $osimage_defined_provmethod_hash{$node_osimage_name . ": rootimgdir"};
my $osimage_provmethod_type = $osimage_defined_provmethod_hash{ $node_osimage_name . ": provmethod" };
my $rootimagedir = $osimage_defined_provmethod_hash{ $node_osimage_name . ": rootimgdir" };
chomp($osimage_provmethod_type) if ($osimage_provmethod_type);
chomp($rootimagedir) if ($rootimagedir);
chomp($rootimagedir) if ($rootimagedir);
# Check if it is netboot, meaning diskless
if ($osimage_provmethod_type && $osimage_provmethod_type eq 'netboot') {
push(@diskless_nodes, $node_name);
probe_utils->send_msg("$output", "o", "$node_name is diskless") if ($VERBOSE);
if (length($rootimagedir) > 0) {
# For this diskless node, get UUID from rootimg directory xcatinfo file of the provmethod osimage
my $xcatinfo_file = $rootimagedir . "/rootimg/opt/xcat/xcatinfo";
if (-r $xcatinfo_file) {
@ -149,27 +156,29 @@ foreach (@all_nodes_provmethod_lines) {
}
else {
probe_utils->send_msg("$output", "w", "$node_name is not diskless. No image consistency verification will be performed.");
}
}
}
else {
probe_utils->send_msg("$output", "w", "$node_name has no provision method defined. No image consistency verification will be performed.");
}
}
if (scalar(@diskless_nodes) <=0) {
if (scalar(@diskless_nodes) <= 0) {
# There were no diskless nodes found. Issue a warning and exit.
probe_utils->send_msg("$output", "w", "No diskless compute nodes were found.");
exit 1;
}
if (scalar(@diskless_nodes) <=0) {
if (scalar(@diskless_nodes) <= 0) {
# There were no diskless nodes found. Issue a warning and exit.
probe_utils->send_msg("$output", "w", "No diskless compute nodes were found");
exit 1;
}
# Next, check if all diskless nodes are pingable
my $ping_hosts = join ",",@diskless_nodes;
my $ping_hosts = join ",", @diskless_nodes;
my $pping_output = `pping $ping_hosts`;
chomp($pping_output);
my @pping_lines = split("[\n\r]", $pping_output);
@ -186,13 +195,15 @@ foreach (@pping_lines) {
}
}
if (scalar(@pingable_nodes) <=0) {
if (scalar(@pingable_nodes) <= 0) {
# There were no pingable, diskless nodes found. Issue a warning and exit.
probe_utils->send_msg("$output", "w", "No diskless, pingable compute nodes were found");
exit 1;
}
if ((scalar(@pingable_nodes) == 1) && ($CONSISTENCY_CHECK)) {
# There was only one node in noderange and comparison check was requested.
# Nothing to compare the single node to.
probe_utils->send_msg("$output", "w", "Comparison check for a single diskless pingable node will not be performed. Minimum of 2 nodes are needed for that.");
@ -229,9 +240,9 @@ foreach (@xdsh_UUID_lines) {
# It is possible that some older version xCAT compute nodes will not have an IMAGEUUID line in
# the xcatinfo file, for those nodes insert $na as the running UUID value
foreach (@pingable_nodes) {
unless (exists($node_running_image_uuid_hash{$_})) {
unless (exists($node_running_image_uuid_hash{$_})) {
$node_running_image_uuid_hash{$_} = $na;
}
}
}
# Build a hash of key="hostname", value="running OS image name"
@ -277,6 +288,7 @@ if ($DEFINITION_CHECK) {
probe_utils->send_msg("$output", "f", "$msg");
}
if (scalar(@pingable_nodes) eq $success_nodes) {
# All pingable nodes were tested with success
probe_utils->send_msg("$output", "o", "OS image installed on each diskless compute node matches the image defined for it on management node");
}

View File

@ -41,6 +41,7 @@ Options:
";
#------------------------------------------
=head3
Description:
Check if all nodes are valid
@ -70,6 +71,7 @@ sub check_noderange {
$nodecheckrst{$currentnode}{"error"} = "Could not find node definition";
$rst = 1;
} elsif ($_ =~ /^\s*Object name: (\w+)/i) {
# 'rst' is used to check whether the node process finished, 1 is finished.
$monitor_nodes{$1}{"rst"} = 0;
$currentnode = $1;
@ -312,7 +314,8 @@ sub handle_cluster_msg {
probe_utils->send_msg("$output", "f", "Node $node has finished it's os provision process");
push(@{ $rawdata{$node}{"history"} }, "Node $node os provision failed");
} elsif (exists($rawdata{$node}) and ($status eq "installing")) {
# record 'installing' status, to check when receive 'booted' status
# record 'installing' status, to check when receive 'booted' status
$monitor_nodes{$node}{"status"} = "installing";
}
}

View File

@ -31,12 +31,12 @@ Options:
my $help;
my $test;
my $check;
my @nodes = ();
my @nodes = ();
my $verbose = '';
if (!GetOptions("help|h" => \$help,
"T" => \$test,
"c" => \$check,
"V" => \$verbose)) {
if (!GetOptions("help|h" => \$help,
"T" => \$test,
"c" => \$check,
"V" => \$verbose)) {
probe_utils->send_msg("$output", "f", "Option not support");
probe_utils->send_msg("$output", "d", $::USAGE);
exit 1;
@ -54,10 +54,10 @@ if ($help) {
exit 0;
}
if (! -d "$currdir/bin") {
mkpath("$currdir/bin/");
if (!-d "$currdir/bin") {
mkpath("$currdir/bin/");
}
if (! -e "$currdir/bin/switchprobe") {
if (!-e "$currdir/bin/switchprobe") {
link("$::XCATROOT/bin/xcatclient", "$currdir/bin/switchprobe");
}
@ -74,9 +74,9 @@ if ($test) {
if ($verbose) {
$verbose = "-V";
}
my $noderange = join(',',@nodes);
my $noderange = join(',', @nodes);
my $normal_file = "/tmp/result_normal";
my $error_file = "/tmp/result_error";
my $error_file = "/tmp/result_error";
if (-f $normal_file) {
unlink($normal_file);
}
@ -84,7 +84,7 @@ if (-f $error_file) {
unlink($error_file);
}
if ($check) {
`$currdir/bin/switchprobe $noderange -c $verbose >$normal_file 2>$error_file`;
`$currdir/bin/switchprobe $noderange -c $verbose >$normal_file 2>$error_file`;
}
else {
`$currdir/bin/switchprobe $noderange $verbose >$normal_file 2>$error_file`;
@ -95,6 +95,7 @@ if (-f $error_file) {
my $fd;
open($fd, "<", "$normal_file");
my @fails = ();
# There is 2 kinds of error message:
# 1. Error: The nodetype is not 'switch' for nodes: switch1
# Error: No switch configuration info find for switch-10-5-23-1
@ -107,7 +108,7 @@ foreach (<$fd>) {
} elsif (/^Error:\s*(.*)/) {
push @fails, $1;
} else {
push @fails, $_;
push @fails, $_;
}
}
elsif (/^(\S*):\s*PASS/) {
@ -117,7 +118,7 @@ foreach (<$fd>) {
probe_utils->send_msg("$output", "d", $_);
}
}
close ($fd);
close($fd);
if (-f $normal_file) {
unlink($normal_file);
}

View File

@ -75,7 +75,7 @@ if (!defined($installnic)) {
exit 1;
}
my $msg = "NIC $installnic exists on current server";
my $msg = "NIC $installnic exists on current server";
my $nics = `ip addr show $installnic >/dev/null 2>&1`;
if ($?) {
probe_utils->send_msg("$output", "f", "$msg");

View File

@ -61,7 +61,7 @@ sub loadsubcmds {
next;
} else {
my $desc = $2;
unless ($1 =~ /^ok$/) {
unless ($1 =~ /^ok$/) {
print "skip $_ for doing '$_ -T' failed, invalid flag\n" if ($verbose);
next;
}
@ -233,7 +233,7 @@ my $pluginname;
my $optnum = 0;
foreach my $attr (@tmpargv) {
if ($attr =~ /^-/) {
unless (grep(/^$attr$/, @supportopt)){
unless (grep(/^$attr$/, @supportopt)) {
print "Unsupported attribute: $attr\n";
print $::USAGE;
exit 1;

View File

@ -2,16 +2,17 @@
# IBM(c) 2010 EPL license http://www.eclipse.org/legal/epl-v10.html
use strict;
use locale;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use Getopt::Std;
use IPC::SysV qw(IPC_STAT S_IRWXU IPC_PRIVATE IPC_CREAT S_IRUSR S_IWUSR );
use IPC::Msg;
my $rc=`lssrc -l -s inetd |grep " ftpd"|grep active 2>&1`;
my $rc = `lssrc -l -s inetd |grep " ftpd"|grep active 2>&1`;
if ($? == 0) {
print "ftpd is active";
} else {

View File

@ -2,16 +2,17 @@
# IBM(c) 2010 EPL license http://www.eclipse.org/legal/epl-v10.html
use strict;
use locale;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use Getopt::Std;
use IPC::SysV qw(IPC_STAT S_IRWXU IPC_PRIVATE IPC_CREAT S_IRUSR S_IWUSR );
use IPC::Msg;
my $rc=`$::XCATROOT/bin/lsxcatd -a 2>&1`;
my $rc = `$::XCATROOT/bin/lsxcatd -a 2>&1`;
if ($?) {
print "$rc";
} else {

View File

@ -5,7 +5,7 @@
# Condition that is watching another Condition in a hierarchical cluster environment.
# The condition that is being watched is a batch event. This script will go th the
# node that has the watched condition, get the event batch file. And parse the file
# and then send email to a user with the detailed info of the events in the batch file.
# and then send email to a user with the detailed info of the events in the batch file.
# The batch file will be then deleted if -d flag is set.
# To use this script, create a Response that invokes this script with email address as the input.
@ -30,40 +30,40 @@ use POSIX qw(strftime);
use File::Basename;
use File::Path;
my $user=shift;
my $delete=shift;
my $user = shift;
my $delete = shift;
if (($delete) && ($delete eq '-d')) {
$delete=1;
$delete = 1;
} else {
$delete=0;
$delete = 0;
}
# Convert Severity and Type environment variables from integers to strings
my @COND_SEVERITY = qw(Informational Warning Critical);
my @TYPE = ('event', 'rearm event');
my $severity=$COND_SEVERITY[$ENV{ERRM_COND_SEVERITYID}];
my $type=$TYPE[$ENV{ERRM_TYPEID }];
my @TYPE = ('event', 'rearm event');
my $severity = $COND_SEVERITY[ $ENV{ERRM_COND_SEVERITYID} ];
my $type = $TYPE[ $ENV{ERRM_TYPEID} ];
# Parse the ERRM_VALUE attribute, which will contain the EventOccurred structured data variable from the Condition class
# The fields in this structured data variable are documented below where we parse them out.
my $event = $ENV{ERRM_VALUE};
$event =~ s/^\[(.*)\]$/$1/; # SD variables have square brackets around them
$event =~ s/^\[(.*)\]$/$1/; # SD variables have square brackets around them
# This parse the LastEvent
my ( # split the SD into the following fields:
$Saved, # batch file has been saved
$filename, # location of the batch file
$Size, # The size of the batch file
) = split(/,/, $event);
my ( # split the SD into the following fields:
$Saved, # batch file has been saved
$filename, # location of the batch file
$Size, # The size of the batch file
) = split(/,/, $event);
my $sn_condname=$ENV{ERRM_RSRC_NAME};
my $sn_name=$ENV{ERRM_NODE_NAME};
my $sn_condname = $ENV{ERRM_RSRC_NAME};
my $sn_name = $ENV{ERRM_NODE_NAME};
my (
$EventTime, # Time of event expressed in seconds since 1/1/1970
$EventTimeMicros, # Number of microseconds past EventTime
) = split(/,/, $ENV{ERRM_TIME});
my (
$EventTime, # Time of event expressed in seconds since 1/1/1970
$EventTimeMicros, # Number of microseconds past EventTime
) = split(/,/, $ENV{ERRM_TIME});
my $msg;
$msg .= "The following $type occurred:\n";
@ -71,69 +71,70 @@ $msg .= " Event Time: " . convertTime($EventTime) . "\n";
$msg .= " Condition name: $ENV{ERRM_COND_NAME}\n";
$msg .= " Severiry: $severity\n";
$msg .= " Condition being monitored: $sn_condname\n";
$msg .= " Node where the condition was monitored: $sn_name\n"; # do we have to use $ERRM_NODE_NAMELIST here?
$msg .= " Node where the condition was monitored: $sn_name\n"; # do we have to use $ERRM_NODE_NAMELIST here?
$msg .= " SN batch files name: $filename\n";
#copy the batch file from sn to mn
$filename =~ s/"//g;
my $bn=basename($filename);
my $bn = basename($filename);
#printf stderr "ful path :$filename\n";
#printf stderr "base name:$bn\n";
my $dirname="/tmp/batch_process/";
if (! -d $dirname) {
my $dirname = "/tmp/batch_process/";
if (!-d $dirname) {
mkdir($dirname);
}
my $cmd;
my $isHMC=0;
my $isHMC = 0;
if ($filename =~ /\/home\/hscroot\/tmp/) {
$isHMC=1;
$cmd="scp hscroot\@$sn_name:$filename $dirname/$bn";
$isHMC = 1;
$cmd = "scp hscroot\@$sn_name:$filename $dirname/$bn";
}
else {
$cmd="scp $sn_name:$filename $dirname/$bn";
$cmd = "scp $sn_name:$filename $dirname/$bn";
}
my $rc=`$cmd 2>&1`;
my $rc = `$cmd 2>&1`;
if ($? != 0) {
$msg .= "$rc\n";
}
#now process the batch file
open(FILE1, "<$dirname/$bn");
readline(FILE1);#skip first 2 lines
readline(FILE1); #skip first 2 lines
readline(FILE1);
my $line1=readline(FILE1);
my @aTemp=split(/=/, $line1);
my $num_events=$aTemp[1];
my $line1 = readline(FILE1);
my @aTemp = split(/=/, $line1);
my $num_events = $aTemp[1];
close(FILE1);
my $count;
for ($count = 1; $count <= $num_events; $count++) {
my $content=`sed -n "/Event $count:/,/ERRM_COND_BATCH/ p" $dirname/$bn`;
my @content_array=split(/\n/, $content);
pop(@content_array); #get rid of last line
shift(@content_array); #get rid of firt line
my %content_hash=();
foreach(@content_array) {
/([^\=]+)\=(.*)/;
$content_hash{$1}=$2;
}
for ($count = 1 ; $count <= $num_events ; $count++) {
my $content = `sed -n "/Event $count:/,/ERRM_COND_BATCH/ p" $dirname/$bn`;
my @content_array = split(/\n/, $content);
pop(@content_array); #get rid of last line
shift(@content_array); #get rid of firt line
my %content_hash = ();
foreach (@content_array) {
/([^\=]+)\=(.*)/;
$content_hash{$1} = $2;
}
my $event = "Event count: $count\n";
#$event .= " Event time: " . $content_hash{ERRM_TIME} . "\n";
$event .= " Node where the event occurred: " . $content_hash{ERRM_NODE_NAMELIST} . "\n";
$event .= " Resource class: " . $content_hash{ERRM_RSRC_CLASS_PNAME} . "\n";
$event .= " Resource name: " . $content_hash{ERRM_RSRC_NAME} . "\n";
$event .= " Attribute name: " . $content_hash{ERRM_ATTR_PNAME} . "\n";
$event .= " Attribute value: " . $content_hash{ERRM_VALUE} . "\n\n";
$msg .= $event;
}
}
#send the mail out
`echo "$msg"| mail -s "xxx$severity $type: $ENV{ERRM_COND_NAME}" $user`;
@ -143,9 +144,9 @@ for ($count = 1; $count <= $num_events; $count++) {
#remove the batch file on the sn if needed
if ($delete) {
if ($isHMC) {
`ssh -l hscroot $sn_name "rm $filename"`;
`ssh -l hscroot $sn_name "rm $filename"`;
} else {
`ssh -l root $sn_name "rm $filename"`;
`ssh -l root $sn_name "rm $filename"`;
}
}
@ -154,6 +155,6 @@ exit;
# convert time string
sub convertTime {
my ($seconds, $micro) = split(/\./, $_[0]);
return strftime("%A %D %T", localtime($seconds));
my ($seconds, $micro) = split(/\./, $_[0]);
return strftime("%A %D %T", localtime($seconds));
}

View File

@ -28,65 +28,66 @@ use strict;
use Getopt::Std;
use POSIX qw(strftime);
my $user=shift;
my $user = shift;
# Convert Severity and Type environment variables from integers to strings
my @COND_SEVERITY = qw(Informational Warning Critical);
my @TYPE = ('event', 'rearm event');
my $severity=$COND_SEVERITY[$ENV{ERRM_COND_SEVERITYID}];
my $type=$TYPE[$ENV{ERRM_TYPEID }];
my @TYPE = ('event', 'rearm event');
my $severity = $COND_SEVERITY[ $ENV{ERRM_COND_SEVERITYID} ];
my $type = $TYPE[ $ENV{ERRM_TYPEID} ];
# Parse the ERRM_VALUE attribute, which will contain the EventOccurred structured data variable from the Condition class
# The fields in this structured data variable are documented below where we parse them out.
my $event = $ENV{ERRM_VALUE};
$event =~ s/^\[(.*)\]$/$1/; # SD variables have square brackets around them
$event =~ s/^\[(.*)\]$/$1/; # SD variables have square brackets around them
# This parse the LastEvent
my ( # split the SD into the following fields:
$Occurred, # One if the condition has been triggered
$ErrNum, # Non-zero if there was in error in the event registration
$ErrMsg, # The string msg related to ErrNum
$EventFlags, # Bit mask giving some additional info about the event
$EventTime, # Time of event expressed in seconds since 1/1/1970
$EventTimeMicros, # Number of microseconds past EventTime
$ResourceHandle, # Binary address of the RMC resource that caused the condition to be triggered
$NodeName, # The node on which the event occurred. For conditions that use the management domain scope (4),
# this will be the leaf node. For conditions that use the local scope (e.g. NodeReachability),
# this will be the FMS.
$NumAttrs, # Number of attr values from the resource returned in this event
$NumAttrsInExpr, # How many of the above were attributes in the event expression
$IndexForAttrs, # The starting index of the array of values. Until new fixed fields are added
# to LastEvent, this will be the element right after this one.
$AttrArray # This list of attribute names, types, and values
) = split(/,/, $event, 12);
my ( # split the SD into the following fields:
$Occurred, # One if the condition has been triggered
$ErrNum, # Non-zero if there was in error in the event registration
$ErrMsg, # The string msg related to ErrNum
$EventFlags, # Bit mask giving some additional info about the event
$EventTime, # Time of event expressed in seconds since 1/1/1970
$EventTimeMicros, # Number of microseconds past EventTime
$ResourceHandle, # Binary address of the RMC resource that caused the condition to be triggered
$NodeName, # The node on which the event occurred. For conditions that use the management domain scope (4),
# this will be the leaf node. For conditions that use the local scope (e.g. NodeReachability),
# this will be the FMS.
$NumAttrs, # Number of attr values from the resource returned in this event
$NumAttrsInExpr, # How many of the above were attributes in the event expression
$IndexForAttrs, # The starting index of the array of values. Until new fixed fields are added
# to LastEvent, this will be the element right after this one.
$AttrArray # This list of attribute names, types, and values
) = split(/,/, $event, 12);
my @attrArray = split(/,/, $AttrArray); # Note: parsing this way does not support SDs or SD Arrays that may be in this list
my @attrArray = split(/,/, $AttrArray); # Note: parsing this way does not support SDs or SD Arrays that may be in this list
my ($ResourceName, $valuesMsg);
my $j = 0; # index into attrArray
for (my $i=0; $i<$NumAttrs; $i++) {
my $attrName = $attrArray[$j++];
my $attrType = $attrArray[$j++]; # Types <= 8 are "simple" types. Types > 8 are SDs and arrays.
my $attrValue = $attrArray[$j++];
if ($attrName eq '"Name"') { $ResourceName = $attrValue; }
$valuesMsg .= " Attribute Value $i: $attrName = $attrValue\n";
my $j = 0; # index into attrArray
for (my $i = 0 ; $i < $NumAttrs ; $i++) {
my $attrName = $attrArray[ $j++ ];
my $attrType = $attrArray[ $j++ ]; # Types <= 8 are "simple" types. Types > 8 are SDs and arrays.
my $attrValue = $attrArray[ $j++ ];
if ($attrName eq '"Name"') { $ResourceName = $attrValue; }
$valuesMsg .= " Attribute Value $i: $attrName = $attrValue\n";
}
if (!length($ResourceName)) { $ResourceName = '(unknown)'; }
my $msg;
$msg .= "The following $TYPE[$ENV{ERRM_TYPEID}] occurred:\n";
$msg .= " MN Condition: $ENV{ERRM_COND_NAME}\n";
$msg .= " SN: $ENV{ERRM_NODE_NAME}\n"; # do we have to use $ERRM_NODE_NAMELIST here?
$msg .= " SN: $ENV{ERRM_NODE_NAME}\n"; # do we have to use $ERRM_NODE_NAMELIST here?
$msg .= " SN Condition: $ENV{ERRM_RSRC_NAME}\n";
$msg .= " Node: $NodeName\n";
$msg .= " Resource Name: $ResourceName\n";
$msg .= " Event Time: " . convertTime($EventTime) . "\n";
if (length($valuesMsg)) {
$msg .= " Attributes that came in the event for condition $ENV{ERRM_RSRC_NAME} from node $NodeName for resource $ResourceName:\n";
$msg .= $valuesMsg;
$msg .= " Attributes that came in the event for condition $ENV{ERRM_RSRC_NAME} from node $NodeName for resource $ResourceName:\n";
$msg .= $valuesMsg;
}
# Skipped the following: $ERRM_EXPR $ERRM_RSRC_CLASS_PNAME $ERRM_DATA_TYPE $ERRM_NODE_NAMELIST $ERRM_RSRC_TYPE
`echo "$msg"| mail -s "$severity $type: $ENV{ERRM_COND_NAME}" $user`;
@ -95,6 +96,6 @@ exit;
# convert time string
sub convertTime {
my ($seconds, $micro) = split(/\./, $_[0]);
return strftime("%A %D %T", localtime($seconds));
my ($seconds, $micro) = split(/\./, $_[0]);
return strftime("%A %D %T", localtime($seconds));
}

View File

@ -16,34 +16,35 @@ my $key = IPC::SysV::ftok("/var/adm/ras/errlog", $m);
# my $message = join " ", @ARGV;
# $msg->snd(1, "$message");
my $message = join " ", @ARGV;
my $message = join " ", @ARGV;
runcmd("/usr/bin/refsensor ErrorLogSensor String=\"$message\" 1>/dev/null 2>/dev/null", 0);
if($::RUNCMD_RC != 0){
my $msg = new IPC::Msg($key, IPC_CREAT|S_IRUSR|S_IWUSR );
my $stat = $msg->stat;
my $qcurrentlen = $$stat[5];
if ($qcurrentlen >= 10000)
{
if (!-d "/var/opt/xcat_err_mon/")
{
my $cmd = "mkdir -p \"/var/opt/xcat_err_mon\"";
runcmd($cmd, -1);
}
open(FILE, ">>/var/opt/xcat_err_mon/errmsgqueerr.log");
my $sdate = `/bin/date`;
chomp $sdate;
print FILE "$sdate:\n";
print FILE "Can not write the message to queue because the queue is almost full, the message content is: $message\n\n\n";
close FILE;
exit 0;
}
$msg->snd(1, "$message");
if ($::RUNCMD_RC != 0) {
my $msg = new IPC::Msg($key, IPC_CREAT | S_IRUSR | S_IWUSR);
my $stat = $msg->stat;
my $qcurrentlen = $$stat[5];
if ($qcurrentlen >= 10000)
{
if (!-d "/var/opt/xcat_err_mon/")
{
my $cmd = "mkdir -p \"/var/opt/xcat_err_mon\"";
runcmd($cmd, -1);
}
open(FILE, ">>/var/opt/xcat_err_mon/errmsgqueerr.log");
my $sdate = `/bin/date`;
chomp $sdate;
print FILE "$sdate:\n";
print FILE "Can not write the message to queue because the queue is almost full, the message content is: $message\n\n\n";
close FILE;
exit 0;
}
$msg->snd(1, "$message");
}
exit 0;
#--------------------------------------------------------------------------------
=head3 runcmd
Run the given cmd and return the output in an array (already chopped). Alternatively,
if this function is used in a scalar context, the output is joined into a single string
@ -69,72 +70,74 @@ exit 0;
If refoutput is true, then the output will be returned as a reference to
an array for efficiency.
=cut
#--------------------------------------------------------------------------------
sub runcmd
{
my ($cmd, $exitcode, $refoutput) = @_;
$::RUNCMD_RC = 0;
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
my $outref = [];
@$outref = `$cmd`;
if ($?)
{
$::RUNCMD_RC = $? >> 8;
my $displayerror = 1;
my $rc;
if (defined($exitcode) && length($exitcode) && $exitcode != -2)
my ($cmd, $exitcode, $refoutput) = @_;
$::RUNCMD_RC = 0;
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
my $outref = [];
@$outref = `$cmd`;
if ($?)
{
if ($exitcode > 0)
{
$rc = $exitcode;
} # if not zero, exit with specified code
elsif ($exitcode <= 0)
{
$rc = ''; # if zero or negative, do not exit
if ($exitcode < 0) { $displayerror = 0; }
}
$::RUNCMD_RC = $? >> 8;
my $displayerror = 1;
my $rc;
if (defined($exitcode) && length($exitcode) && $exitcode != -2)
{
if ($exitcode > 0)
{
$rc = $exitcode;
} # if not zero, exit with specified code
elsif ($exitcode <= 0)
{
$rc = ''; # if zero or negative, do not exit
if ($exitcode < 0) { $displayerror = 0; }
}
}
else
{
$rc = $::RUNCMD_RC;
} # if exitcode not specified, use cmd exit code
if ($displayerror)
{
my $errmsg = '';
if (($^O =~ /^linux/i) && $::RUNCMD_RC == 139)
{
$errmsg = "Segmentation fault $errmsg";
}
else
{
# The error msgs from the -api cmds are pretty messy. Clean them up a little.
filterRmcApiOutput($cmd, $outref);
$errmsg = join('', @$outref);
chomp $errmsg;
}
print "Exit code $::RUNCMD_RC from command: $cmd\nError message from cmd: $errmsg\n"
}
}
if ($refoutput)
{
chomp(@$outref);
return $outref;
}
elsif (wantarray)
{
chomp(@$outref);
return @$outref;
}
else
{
$rc = $::RUNCMD_RC;
} # if exitcode not specified, use cmd exit code
if ($displayerror)
{
my $errmsg = '';
if (($^O =~ /^linux/i) && $::RUNCMD_RC == 139)
{
$errmsg = "Segmentation fault $errmsg";
}
else
{
# The error msgs from the -api cmds are pretty messy. Clean them up a little.
filterRmcApiOutput($cmd, $outref);
$errmsg = join('', @$outref);
chomp $errmsg;
}
print "Exit code $::RUNCMD_RC from command: $cmd\nError message from cmd: $errmsg\n"
my $line = join('', @$outref);
chomp $line;
return $line;
}
}
if ($refoutput)
{
chomp(@$outref);
return $outref;
}
elsif (wantarray)
{
chomp(@$outref);
return @$outref;
}
else
{
my $line = join('', @$outref);
chomp $line;
return $line;
}
}
#--------------------------------------------------------------------------------
=head3 filterRmcApiOutput
filter RMC Api Output
Arguments:
@ -152,25 +155,26 @@ sub runcmd
The error msgs from the RPM -api cmds are pretty messy.
This routine cleans them up a little bit.
=cut
#--------------------------------------------------------------------------------
sub filterRmcApiOutput
{
my ($cmd, $outref) = @_;
if (!($cmd =~ m|^/usr/bin/\S+-api |)) {
return;
} # give as much info as possible, if verbose
my ($cmd, $outref) = @_;
if (!($cmd =~ m|^/usr/bin/\S+-api |)) {
return;
} # give as much info as possible, if verbose
# Figure out the output delimiter
my ($d) = $cmd =~ / -D\s+(\S+)/;
if (length($d)) {
$d =~ s/^(\'|\")(.*)(\"|\')$/$2/; # remove any surrounding quotes
# escape any chars perl pattern matching would intepret as special chars
$d =~ s/([\|\^\*\+\?\.])/\\$1/g;
}
else
{
$d = '::';
} # this is the default output delimiter for the -api cmds
$$outref[0] =~ s/^ERROR${d}.*${d}.*${d}.*${d}.*${d}//;
# Figure out the output delimiter
my ($d) = $cmd =~ / -D\s+(\S+)/;
if (length($d)) {
$d =~ s/^(\'|\")(.*)(\"|\')$/$2/; # remove any surrounding quotes
# escape any chars perl pattern matching would intepret as special chars
$d =~ s/([\|\^\*\+\?\.])/\\$1/g;
}
else
{
$d = '::';
} # this is the default output delimiter for the -api cmds
$$outref[0] =~ s/^ERROR${d}.*${d}.*${d}.*${d}.*${d}//;
}

View File

@ -5,7 +5,7 @@
# Condition that is watching another Condition in a hierarchical cluster environment.
# The condition that is being watched is a batch event. This script will go th the
# node that has the watched condition, get the event batch file. And parse the file
# and then send email to a user with the detailed info of the events in the batch file.
# and then send email to a user with the detailed info of the events in the batch file.
# The batch file will be then deleted if -d flag is set.
# To use this script, create a Response that invokes this script with user id as the input.
@ -31,123 +31,125 @@ use File::Basename;
use File::Path;
my $logfn = join(' ', @ARGV);
my $delete=0;
my $delete = 0;
if ($logfn =~ /-d/) {
$delete=1;
$delete = 1;
}
$logfn =~ s/-d//; #remove -d
$logfn =~ s/-d//; #remove -d
# Convert Severity and Type environment variables from integers to strings
my @COND_SEVERITY = qw(Informational Warning Critical);
my @TYPE = ('event', 'rearm event');
my $severity=$COND_SEVERITY[$ENV{ERRM_COND_SEVERITYID}];
my $type=$TYPE[$ENV{ERRM_TYPEID }];
my @TYPE = ('event', 'rearm event');
my $severity = $COND_SEVERITY[ $ENV{ERRM_COND_SEVERITYID} ];
my $type = $TYPE[ $ENV{ERRM_TYPEID} ];
# Parse the ERRM_VALUE attribute, which will contain the EventOccurred structured data variable from the Condition class
# The fields in this structured data variable are documented below where we parse them out.
my $event = $ENV{ERRM_VALUE};
$event =~ s/^\[(.*)\]$/$1/; # SD variables have square brackets around them
$event =~ s/^\[(.*)\]$/$1/; # SD variables have square brackets around them
# This parse the LastEvent
my ( # split the SD into the following fields:
$Saved, # batch file has been saved
$filename, # location of the batch file
$Size, # The size of the batch file
) = split(/,/, $event);
my ( # split the SD into the following fields:
$Saved, # batch file has been saved
$filename, # location of the batch file
$Size, # The size of the batch file
) = split(/,/, $event);
my $sn_condname=$ENV{ERRM_RSRC_NAME};
my $sn_name=$ENV{ERRM_NODE_NAME};
my $sn_condname = $ENV{ERRM_RSRC_NAME};
my $sn_name = $ENV{ERRM_NODE_NAME};
my (
$EventTime, # Time of event expressed in seconds since 1/1/1970
$EventTimeMicros, # Number of microseconds past EventTime
) = split(/,/, $ENV{ERRM_TIME});
my (
$EventTime, # Time of event expressed in seconds since 1/1/1970
$EventTimeMicros, # Number of microseconds past EventTime
) = split(/,/, $ENV{ERRM_TIME});
my $msg="===================================================================\n";;
my $msg = "===================================================================\n";
$msg .= " Event Time: " . convertTime($EventTime) . "\n";
$msg .= " Condition name: $ENV{ERRM_COND_NAME}\n";
$msg .= " Event Type: $type\n";
$msg .= " Severiry: $severity\n";
$msg .= " Condition being monitored: $sn_condname\n";
$msg .= " Node where the condition was monitored: $sn_name\n"; # do we have to use $ERRM_NODE_NAMELIST here?
$msg .= " Node where the condition was monitored: $sn_name\n"; # do we have to use $ERRM_NODE_NAMELIST here?
$msg .= " SN batch files name: $filename\n";
#copy the batch file from sn to mn
$filename =~ s/"//g;
my $bn=basename($filename);
my $bn = basename($filename);
#printf stderr "ful path :$filename\n";
#printf stderr "base name:$bn\n";
my $dirname="/tmp/batch_process/";
if (! -d $dirname) {
my $dirname = "/tmp/batch_process/";
if (!-d $dirname) {
mkdir($dirname);
}
my $cmd;
my $isHMC=0;
my $isHMC = 0;
if ($filename =~ /\/home\/hscroot\/tmp/) {
$isHMC=1;
$cmd="scp hscroot\@$sn_name:$filename $dirname/$bn";
$isHMC = 1;
$cmd = "scp hscroot\@$sn_name:$filename $dirname/$bn";
}
else {
$cmd="scp $sn_name:$filename $dirname/$bn";
$cmd = "scp $sn_name:$filename $dirname/$bn";
}
my $rc=`$cmd 2>&1`;
my $rc = `$cmd 2>&1`;
if ($? != 0) {
$msg .= "$rc\n";
}
#now process the batch file
open(FILE1, "<$dirname/$bn");
readline(FILE1);#skip first 2 lines
readline(FILE1); #skip first 2 lines
readline(FILE1);
my $line1=readline(FILE1);
my @aTemp=split(/=/, $line1);
my $num_events=$aTemp[1];
my $line1 = readline(FILE1);
my @aTemp = split(/=/, $line1);
my $num_events = $aTemp[1];
close(FILE1);
my $count;
for ($count = 1; $count <= $num_events; $count++) {
my $content=`sed -n "/Event $count:/,/ERRM_COND_BATCH/ p" $dirname/$bn`;
my @content_array=split(/\n/, $content);
pop(@content_array); #get rid of last line
shift(@content_array); #get rid of firt line
my %content_hash=();
foreach(@content_array) {
/([^\=]+)\=(.*)/;
$content_hash{$1}=$2;
}
for ($count = 1 ; $count <= $num_events ; $count++) {
my $content = `sed -n "/Event $count:/,/ERRM_COND_BATCH/ p" $dirname/$bn`;
my @content_array = split(/\n/, $content);
pop(@content_array); #get rid of last line
shift(@content_array); #get rid of firt line
my %content_hash = ();
foreach (@content_array) {
/([^\=]+)\=(.*)/;
$content_hash{$1} = $2;
}
my $event = "Event count: $count\n";
#$event .= " Event time: " . $content_hash{ERRM_TIME} . "\n";
$event .= " Node where the event occurred: " . $content_hash{ERRM_NODE_NAMELIST} . "\n";
$event .= " Resource class: " . $content_hash{ERRM_RSRC_CLASS_PNAME} . "\n";
$event .= " Resource name: " . $content_hash{ERRM_RSRC_NAME} . "\n";
$event .= " Attribute name: " . $content_hash{ERRM_ATTR_PNAME} . "\n";
$event .= " Attribute value: " . $content_hash{ERRM_VALUE} . "\n\n";
$msg .= $event;
}
}
#log the events
if (open (FILE, ">>$logfn")) {
if (open(FILE, ">>$logfn")) {
print FILE "$msg\n";
close (FILE);
}
close(FILE);
}
#delete the batch file on the mn
`rm $dirname/$bn`;
#remove the batch file on the sn if needed
if ($delete) {
if ($isHMC) {
`ssh -l hscroot $sn_name "rm $filename"`;
`ssh -l hscroot $sn_name "rm $filename"`;
} else {
`ssh -l root $sn_name "rm $filename"`;
`ssh -l root $sn_name "rm $filename"`;
}
}
@ -156,6 +158,6 @@ exit;
# convert time string
sub convertTime {
my ($seconds, $micro) = split(/\./, $_[0]);
return strftime("%A %D %T", localtime($seconds));
my ($seconds, $micro) = split(/\./, $_[0]);
return strftime("%A %D %T", localtime($seconds));
}

View File

@ -32,77 +32,77 @@ use File::Path;
# Convert Severity and Type environment variables from integers to strings
my @COND_SEVERITY = qw(Informational Warning Critical);
my @TYPE = ('Event', 'Rearm event');
my $severity=$COND_SEVERITY[$ENV{ERRM_COND_SEVERITYID}];
my $type=$TYPE[$ENV{ERRM_TYPEID }];
my @TYPE = ('Event', 'Rearm event');
my $severity = $COND_SEVERITY[ $ENV{ERRM_COND_SEVERITYID} ];
my $type = $TYPE[ $ENV{ERRM_TYPEID} ];
my $filename = shift;
# Parse the ERRM_VALUE attribute, which will contain the EventOccurred structured data variable from the Condition class
# The fields in this structured data variable are documented below where we parse them out.
my $event = $ENV{ERRM_VALUE};
$event =~ s/^\[(.*)\]$/$1/; # SD variables have square brackets around them
$event =~ s/^\[(.*)\]$/$1/; # SD variables have square brackets around them
# This parse the LastEvent
my ( # split the SD into the following fields:
$Occurred, # One if the condition has been triggered
$ErrNum, # Non-zero if there was in error in the event registration
$ErrMsg, # The string msg related to ErrNum
$EventFlags, # Bit mask giving some additional info about the event
$EventTime, # Time of event expressed in seconds since 1/1/1970
$EventTimeMicros, # Number of microseconds past EventTime
$ResourceHandle, # Binary address of the RMC resource that caused the condition to be triggered
$NodeName, # The node on which the event occurred. For conditions that use the management domain scope (4),
# this will be the leaf node. For conditions that use the local scope (e.g. NodeReachability),
# this will be the FMS.
$NumAttrs, # Number of attr values from the resource returned in this event
$NumAttrsInExpr, # How many of the above were attributes in the event expression
$IndexForAttrs, # The starting index of the array of values. Until new fixed fields are added
# to LastEvent, this will be the element right after this one.
$AttrArray # This list of attribute names, types, and values
) = split(/,/, $event, 12);
my ( # split the SD into the following fields:
$Occurred, # One if the condition has been triggered
$ErrNum, # Non-zero if there was in error in the event registration
$ErrMsg, # The string msg related to ErrNum
$EventFlags, # Bit mask giving some additional info about the event
$EventTime, # Time of event expressed in seconds since 1/1/1970
$EventTimeMicros, # Number of microseconds past EventTime
$ResourceHandle, # Binary address of the RMC resource that caused the condition to be triggered
$NodeName, # The node on which the event occurred. For conditions that use the management domain scope (4),
# this will be the leaf node. For conditions that use the local scope (e.g. NodeReachability),
# this will be the FMS.
$NumAttrs, # Number of attr values from the resource returned in this event
$NumAttrsInExpr, # How many of the above were attributes in the event expression
$IndexForAttrs, # The starting index of the array of values. Until new fixed fields are added
# to LastEvent, this will be the element right after this one.
$AttrArray # This list of attribute names, types, and values
) = split(/,/, $event, 12);
my @attrArray = split(/,/, $AttrArray); # Note: parsing this way does not support SDs or SD Arrays that may be in this list
my @attrArray = split(/,/, $AttrArray); # Note: parsing this way does not support SDs or SD Arrays that may be in this list
my ($ResourceName, $valuesMsg);
my $j = 0; # index into attrArray
for (my $i=0; $i<$NumAttrs; $i++) {
my $attrName = $attrArray[$j++];
my $attrType = $attrArray[$j++]; # Types <= 8 are "simple" types. Types > 8 are SDs and arrays.
my $attrValue = $attrArray[$j++];
if ($attrName eq '"Name"') { $ResourceName = $attrValue; }
$valuesMsg .= " Attribute Value $i: $attrName = $attrValue\n";
my $j = 0; # index into attrArray
for (my $i = 0 ; $i < $NumAttrs ; $i++) {
my $attrName = $attrArray[ $j++ ];
my $attrType = $attrArray[ $j++ ]; # Types <= 8 are "simple" types. Types > 8 are SDs and arrays.
my $attrValue = $attrArray[ $j++ ];
if ($attrName eq '"Name"') { $ResourceName = $attrValue; }
$valuesMsg .= " Attribute Value $i: $attrName = $attrValue\n";
}
if (!length($ResourceName)) { $ResourceName = '(unknown)'; }
my $msg="=============================================================================\n";
my $msg = "=============================================================================\n";
$msg .= " Time: " . convertTime($EventTime) . " \n";
$msg .= " MN Condition: $ENV{ERRM_COND_NAME}\n";
$msg .= " Severity: $severity\n";
$msg .= " Event Type: $type\n";
$msg .= " SN Condition: $ENV{ERRM_RSRC_NAME}\n";
$msg .= " SN: $ENV{ERRM_NODE_NAME}\n"; # do we have to use $ERRM_NODE_NAMELIST here?
$msg .= " SN: $ENV{ERRM_NODE_NAME}\n"; # do we have to use $ERRM_NODE_NAMELIST here?
$msg .= " Node: $NodeName\n";
$msg .= " Resource Name: $ResourceName\n";
if (length($valuesMsg)) {
$msg .= " Attributes:\n";
$msg .= $valuesMsg;
$msg .= " Attributes:\n";
$msg .= $valuesMsg;
}
# Skipped the following: $ERRM_EXPR $ERRM_RSRC_CLASS_PNAME $ERRM_DATA_TYPE $ERRM_NODE_NAMELIST $ERRM_RSRC_TYPE
#$str = escape_chars($str);
if (open (FILE, ">>$filename")) {
if (open(FILE, ">>$filename")) {
print FILE "$msg\n";
close (FILE);
}
close(FILE);
}
exit;
# convert time string
sub convertTime {
my ($seconds, $micro) = split(/\./, $_[0]);
return strftime("%A %D %T", localtime($seconds));
my ($seconds, $micro) = split(/\./, $_[0]);
return strftime("%A %D %T", localtime($seconds));
}

View File

@ -1,39 +1,40 @@
#!/usr/bin/env perl
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
open(FILE, ">>/var/log/logevent_simple.log") or dir ("cannot open the file\n");
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
printf FILE "\n-----------%2d-%02d-%04d %02d:%02d:%02d-----------\n", $mon+1,$mday,$year+1900,$hour,$min,$sec;
open(FILE, ">>/var/log/logevent_simple.log") or dir("cannot open the file\n");
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
printf FILE "\n-----------%2d-%02d-%04d %02d:%02d:%02d-----------\n", $mon + 1, $mday, $year + 1900, $hour, $min, $sec;
my $respname=$ENV{ERRM_ER_NAME};
my $cond_name=$ENV{ERRM_COND_NAME};
my $batch=0;
if (exists($ENV{ERRM_COND_BATCH})) { $batch=$ENV{ERRM_COND_BATCH}; }
my $respname = $ENV{ERRM_ER_NAME};
my $cond_name = $ENV{ERRM_COND_NAME};
my $batch = 0;
if (exists($ENV{ERRM_COND_BATCH})) { $batch = $ENV{ERRM_COND_BATCH}; }
if ($batch) {
if ($ENV{ERRM_COND_BATCH_NUM} > 0) {
#check if event detail file exist
if (!exists($ENV{ERRM_EVENT_DETAIL_FILE})){
xCAT::MsgUtils->message('S', "logeventtoxcat: no event detail file specified in the response $respname for condition $cond_name.\n");
exit (1);
}
my $filename=$ENV{ERRM_EVENT_DETAIL_FILE};
if (! -f $filename) {
xCAT::MsgUtils->message('S', "logeventtoxcat: cannot find event detail file $filename in response $respname for condition $cond_name.\n");
exit (1);
}
open(FILE1, "<$filename");
my $line1=readline(FILE1);
my @aTemp=split(/=/, $line1);
my $num_events=$aTemp[1];
close(FILE1);
print FILE "Total events=$num_events\n\n";
#check if event detail file exist
if (!exists($ENV{ERRM_EVENT_DETAIL_FILE})) {
xCAT::MsgUtils->message('S', "logeventtoxcat: no event detail file specified in the response $respname for condition $cond_name.\n");
exit(1);
}
my $filename = $ENV{ERRM_EVENT_DETAIL_FILE};
if (!-f $filename) {
xCAT::MsgUtils->message('S', "logeventtoxcat: cannot find event detail file $filename in response $respname for condition $cond_name.\n");
exit(1);
}
open(FILE1, "<$filename");
my $line1 = readline(FILE1);
my @aTemp = split(/=/, $line1);
my $num_events = $aTemp[1];
close(FILE1);
print FILE "Total events=$num_events\n\n";
}
}
}
close(FILE);
return 0;

View File

@ -1,12 +1,12 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
# This script is used by LogEventToTealEventLog response to put RMC events into
# the TEAL's x_tealeventlog table. It handles both batch and non-batching events.
# This script is used by LogEventToTealEventLog response to put RMC events into
# the TEAL's x_tealeventlog table. It handles both batch and non-batching events.
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use strict;
@ -19,91 +19,92 @@ use IO::File;
use TEAL::Semaphore;
use TEAL::event_id;
my $batch=0;
if (exists($ENV{ERRM_COND_BATCH})) { $batch=$ENV{ERRM_COND_BATCH}; }
my @a=();
my $condname=$ENV{ERRM_COND_NAME};
my $respname=$ENV{ERRM_ER_NAME};
my $eventid = $TEAL::event_id::tabeventid{$condname};
my $batch = 0;
if (exists($ENV{ERRM_COND_BATCH})) { $batch = $ENV{ERRM_COND_BATCH}; }
my @a = ();
my $condname = $ENV{ERRM_COND_NAME};
my $respname = $ENV{ERRM_ER_NAME};
my $eventid = $TEAL::event_id::tabeventid{$condname};
if (!$batch) { #handle single event
my $time=$ENV{ERRM_TIME};
my $nodenamelist=$ENV{ERRM_NODE_NAMELIST};
if (!$batch) { #handle single event
my $time = $ENV{ERRM_TIME};
my $nodenamelist = $ENV{ERRM_NODE_NAMELIST};
$nodenamelist =~ s/\{(.*)\}/$1/;
my $event={
event_id => $eventid,
time_occurred => convertTime($time),
src_comp => $ENV{ERRM_RSRC_CLASS_PNAME},
src_loc_type => "A",
src_loc => "$nodenamelist##" . $ENV{ERRM_RSRC_NAME},
rpt_comp => 'IBM.Condition',
rpt_loc_type =>"A",
rpt_loc => $ENV{ERRM_NODE_NAME} . "##" . $ENV{ERRM_COND_NAME},
raw_data_fmt =>"0",
raw_data => $ENV{ERRM_ATTR_PNAME} . "=" . $ENV{ERRM_VALUE},
};
my $event = {
event_id => $eventid,
time_occurred => convertTime($time),
src_comp => $ENV{ERRM_RSRC_CLASS_PNAME},
src_loc_type => "A",
src_loc => "$nodenamelist##" . $ENV{ERRM_RSRC_NAME},
rpt_comp => 'IBM.Condition',
rpt_loc_type => "A",
rpt_loc => $ENV{ERRM_NODE_NAME} . "##" . $ENV{ERRM_COND_NAME},
raw_data_fmt => "0",
raw_data => $ENV{ERRM_ATTR_PNAME} . "=" . $ENV{ERRM_VALUE},
};
push(@a, $event);
} else { #handle event batching
} else { #handle event batching
if ($ENV{ERRM_COND_BATCH_NUM} > 0) {
#check if event detail file exist
if (!exists($ENV{ERRM_EVENT_DETAIL_FILE})){
xCAT::MsgUtils->message('S', "logeventtoteal: no event detail file specified in the response $respname for condition $condname.\n");
exit (1);
}
my $filename=$ENV{ERRM_EVENT_DETAIL_FILE};
if (! -f $filename) {
xCAT::MsgUtils->message('S', "logeventtoteal: cannot find event detail file $filename in response $respname for condition $condname.\n");
exit (1);
}
if (!exists($ENV{ERRM_EVENT_DETAIL_FILE})) {
xCAT::MsgUtils->message('S', "logeventtoteal: no event detail file specified in the response $respname for condition $condname.\n");
exit(1);
}
open(FILE1, "<$filename");
readline(FILE1);#skip first 2 lines
my $filename = $ENV{ERRM_EVENT_DETAIL_FILE};
if (!-f $filename) {
xCAT::MsgUtils->message('S', "logeventtoteal: cannot find event detail file $filename in response $respname for condition $condname.\n");
exit(1);
}
open(FILE1, "<$filename");
readline(FILE1); #skip first 2 lines
readline(FILE1);
my $line1=readline(FILE1);
my @aTemp=split(/=/, $line1);
my $num_events=$aTemp[1];
close(FILE1);
my $line1 = readline(FILE1);
my @aTemp = split(/=/, $line1);
my $num_events = $aTemp[1];
close(FILE1);
my $count;
for ($count = 1; $count <= $num_events; $count++) {
my $content=`sed -n "/Event $count:/,/ERRM_COND_BATCH/ p" $filename`;
my @content_array=split(/\n/, $content);
pop(@content_array); #get rid of last line
shift(@content_array); #get rid of firt line
my %content_hash=();
foreach(@content_array) {
my $count;
for ($count = 1 ; $count <= $num_events ; $count++) {
my $content = `sed -n "/Event $count:/,/ERRM_COND_BATCH/ p" $filename`;
my @content_array = split(/\n/, $content);
pop(@content_array); #get rid of last line
shift(@content_array); #get rid of firt line
my %content_hash = ();
foreach (@content_array) {
/([^\=]+)\=(.*)/;
$content_hash{$1}=$2;
}
$content_hash{$1} = $2;
}
my $time=$content_hash{ERRM_TIME};
my $nodenamelist=$content_hash{ERRM_NODE_NAMELIST};
$nodenamelist =~ s/\{(.*)\}/$1/;
my $event={
event_id => $eventid,
time_occurred => convertTime($time),
src_comp => $content_hash{ERRM_RSRC_CLASS_PNAME},
src_loc_type => "A",
src_loc => $nodenamelist . "##" . $content_hash{ERRM_RSRC_NAME},
rpt_comp => "IBM.Condition",
rpt_loc_type =>"A",
rpt_loc => $content_hash{ERRM_NODE_NAME} . "##" . $content_hash{ERRM_COND_NAME},
my $time = $content_hash{ERRM_TIME};
my $nodenamelist = $content_hash{ERRM_NODE_NAMELIST};
$nodenamelist =~ s/\{(.*)\}/$1/;
my $event = {
event_id => $eventid,
time_occurred => convertTime($time),
src_comp => $content_hash{ERRM_RSRC_CLASS_PNAME},
src_loc_type => "A",
src_loc => $nodenamelist . "##" . $content_hash{ERRM_RSRC_NAME},
rpt_comp => "IBM.Condition",
rpt_loc_type => "A",
rpt_loc => $content_hash{ERRM_NODE_NAME} . "##" . $content_hash{ERRM_COND_NAME},
raw_data_fmt => "0",
raw_data => $content_hash{ERRM_ATTR_PNAME} . "=" . $content_hash{ERRM_VALUE},
};
push(@a, $event);
}
raw_data => $content_hash{ERRM_ATTR_PNAME} . "=" . $content_hash{ERRM_VALUE},
};
push(@a, $event);
}
}
}
}
my ($rc, $msg)=xCAT::TableUtils->logEventsToTealDatabase(\@a);
my ($rc, $msg) = xCAT::TableUtils->logEventsToTealDatabase(\@a);
if ($rc) {
xCAT::MsgUtils->message('S', "logeventtoteal:$msg. The condition is $condname. The response is $respname.\n");
xCAT::MsgUtils->message('S', "logeventtoteal:$msg. The condition is $condname. The response is $respname.\n");
} else {
my $s = TEAL::Semaphore->new();
$s->post()
@ -111,11 +112,12 @@ if ($rc) {
# convert time string that can be used for timestamp datatype for db
sub convertTime {
my ($seconds, $micro) = split(/\,/, $_[0]);
#return strftime("%A %D %T", localtime($seconds));
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime($seconds);
my $result=sprintf("%4d-%02d-%02d %02d:%02d:%02d.%06d", $year+1900,$mon+1,$mday,$hour,$min,$sec,$micro);
return $result;
my ($seconds, $micro) = split(/\,/, $_[0]);
#return strftime("%A %D %T", localtime($seconds));
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($seconds);
my $result = sprintf("%4d-%02d-%02d %02d:%02d:%02d.%06d", $year + 1900, $mon + 1, $mday, $hour, $min, $sec, $micro);
return $result;
}

View File

@ -1,12 +1,12 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
# This script is used by LogEventToxCATDatabase event response to put RMC events into
# This script is used by LogEventToxCATDatabase event response to put RMC events into
# the xCAT evnetlog table. It handles both batch and non-batching events.
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use strict;
@ -17,90 +17,91 @@ use xCAT::TableUtils;
use xCAT::MsgUtils;
use IO::File;
my $batch=0;
if (exists($ENV{ERRM_COND_BATCH})) { $batch=$ENV{ERRM_COND_BATCH}; }
my @a=();
my $condname=$ENV{ERRM_COND_NAME};
my $respname=$ENV{ERRM_ER_NAME};
my $batch = 0;
if (exists($ENV{ERRM_COND_BATCH})) { $batch = $ENV{ERRM_COND_BATCH}; }
my @a = ();
my $condname = $ENV{ERRM_COND_NAME};
my $respname = $ENV{ERRM_ER_NAME};
if (!$batch) { #handle single event
my $time=$ENV{ERRM_TIME};
my $nodenamelist=$ENV{ERRM_NODE_NAMELIST};
if (!$batch) { #handle single event
my $time = $ENV{ERRM_TIME};
my $nodenamelist = $ENV{ERRM_NODE_NAMELIST};
$nodenamelist =~ s/\{(.*)\}/$1/;
my $event={
eventtype => $ENV{ERRM_TYPE},
monitor => $ENV{ERRM_COND_NAME},
monnode => $ENV{ERRM_NODE_NAME},
node => $nodenamelist,
application => 'RMC',
component => $ENV{ERRM_RSRC_CLASS_PNAME},
id => $ENV{ERRM_RSRC_NAME} . "," . $ENV{ERRM_ATTR_PNAME},
severity => $ENV{ERRM_COND_SEVERITY},
message => '',
rawdata => $ENV{ERRM_ATTR_PNAME} . "=" . $ENV{ERRM_VALUE},
};
my $event = {
eventtype => $ENV{ERRM_TYPE},
monitor => $ENV{ERRM_COND_NAME},
monnode => $ENV{ERRM_NODE_NAME},
node => $nodenamelist,
application => 'RMC',
component => $ENV{ERRM_RSRC_CLASS_PNAME},
id => $ENV{ERRM_RSRC_NAME} . "," . $ENV{ERRM_ATTR_PNAME},
severity => $ENV{ERRM_COND_SEVERITY},
message => '',
rawdata => $ENV{ERRM_ATTR_PNAME} . "=" . $ENV{ERRM_VALUE},
};
push(@a, $event);
} else { #handle event batching
} else { #handle event batching
if ($ENV{ERRM_COND_BATCH_NUM} > 0) {
#check if event detail file exist
if (!exists($ENV{ERRM_EVENT_DETAIL_FILE})){
xCAT::MsgUtils->message('S', "logeventtoxcat: no event detail file specified in the response $respname for condition $condname.\n");
exit (1);
}
my $filename=$ENV{ERRM_EVENT_DETAIL_FILE};
if (! -f $filename) {
xCAT::MsgUtils->message('S', "logeventtoxcat: cannot find event detail file $filename in response $respname for condition $condname.\n");
exit (1);
}
if (!exists($ENV{ERRM_EVENT_DETAIL_FILE})) {
xCAT::MsgUtils->message('S', "logeventtoxcat: no event detail file specified in the response $respname for condition $condname.\n");
exit(1);
}
open(FILE1, "<$filename");
readline(FILE1);#skip first 2 lines
my $filename = $ENV{ERRM_EVENT_DETAIL_FILE};
if (!-f $filename) {
xCAT::MsgUtils->message('S', "logeventtoxcat: cannot find event detail file $filename in response $respname for condition $condname.\n");
exit(1);
}
open(FILE1, "<$filename");
readline(FILE1); #skip first 2 lines
readline(FILE1);
my $line1=readline(FILE1);
my @aTemp=split(/=/, $line1);
my $num_events=$aTemp[1];
close(FILE1);
my $line1 = readline(FILE1);
my @aTemp = split(/=/, $line1);
my $num_events = $aTemp[1];
close(FILE1);
my $count;
for ($count = 1; $count <= $num_events; $count++) {
my $content=`sed -n "/Event $count:/,/ERRM_COND_BATCH/ p" $filename`;
my @content_array=split(/\n/, $content);
pop(@content_array); #get rid of last line
shift(@content_array); #get rid of firt line
my %content_hash=();
foreach(@content_array) {
my $count;
for ($count = 1 ; $count <= $num_events ; $count++) {
my $content = `sed -n "/Event $count:/,/ERRM_COND_BATCH/ p" $filename`;
my @content_array = split(/\n/, $content);
pop(@content_array); #get rid of last line
shift(@content_array); #get rid of firt line
my %content_hash = ();
foreach (@content_array) {
/([^\=]+)\=(.*)/;
$content_hash{$1}=$2;
}
$content_hash{$1} = $2;
}
my $time=$content_hash{ERRM_TIME};
my $nodenamelist=$content_hash{ERRM_NODE_NAMELIST};
$nodenamelist =~ s/\{(.*)\}/$1/;
my $event={
eventtype => $content_hash{ERRM_TYPE},
monitor => $content_hash{ERRM_COND_NAME},
monnode => $content_hash{ERRM_NODE_NAME},
node => $nodenamelist,
application => 'RMC',
component => $content_hash{ERRM_RSRC_CLASS_PNAME},
id => $content_hash{ERRM_RSRC_NAME} . "," . $content_hash{ERRM_ATTR_PNAME},
severity => $content_hash{ERRM_COND_SEVERITY},
message => '',
rawdata => $content_hash{ERRM_ATTR_PNAME} . "=" . $content_hash{ERRM_VALUE},
};
push(@a, $event);
}
my $time = $content_hash{ERRM_TIME};
my $nodenamelist = $content_hash{ERRM_NODE_NAMELIST};
$nodenamelist =~ s/\{(.*)\}/$1/;
my $event = {
eventtype => $content_hash{ERRM_TYPE},
monitor => $content_hash{ERRM_COND_NAME},
monnode => $content_hash{ERRM_NODE_NAME},
node => $nodenamelist,
application => 'RMC',
component => $content_hash{ERRM_RSRC_CLASS_PNAME},
id => $content_hash{ERRM_RSRC_NAME} . "," . $content_hash{ERRM_ATTR_PNAME},
severity => $content_hash{ERRM_COND_SEVERITY},
message => '',
rawdata => $content_hash{ERRM_ATTR_PNAME} . "=" . $content_hash{ERRM_VALUE},
};
push(@a, $event);
}
}
}
}
my ($rc, $msg)=xCAT::TableUtils->logEventsToDatabase(\@a);
my ($rc, $msg) = xCAT::TableUtils->logEventsToDatabase(\@a);
if ($rc) {
xCAT::MsgUtils->message('S', "logeventtoxcat:$msg. The condition is $condname. The response is $respname.\n");
xCAT::MsgUtils->message('S', "logeventtoxcat:$msg. The condition is $condname. The response is $respname.\n");
}
exit $rc;

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,21 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#------------------------------------------------------------------------------
=head1 monaixsyslog
=head2
=cut
#------------------------------------------------------------------------------
use locale;
use Getopt::Long;
my $dirname = "xcat_aix_syslog";
my $vardir = "/var/opt/$dirname";
my $vardir = "/var/opt/$dirname";
my $default_runfile = "$vardir/.monaixsyslog_run";
my $default_file = "$vardir/syslog.out";
my $default_pri = "*.warn";
my $default_file = "$vardir/syslog.out";
my $default_pri = "*.warn";
$::MAX_SENSOR_STRING = 65535;
my ($facility_priority, $logfile, $runfile) = &getArgs();
@ -21,35 +23,35 @@ my ($facility_priority, $logfile, $runfile) = &getArgs();
my ($syslogconf, $embedinfo);
$syslogconf = "/etc/syslog.conf";
$embedinfo = "$facility_priority $logfile rotate size 4m files 1";
$embedinfo = "$facility_priority $logfile rotate size 4m files 1";
if (!-d $vardir) { mkdir($vardir); }
#check to see if this is the first time this script has been run
if (!-e $runfile)
{ #first time
if ($^O =~ /^aix/i)
{
runcmd("grep \"$embedinfo\" $syslogconf", -1);
if ($::RUNCMD_RC == 1)
{ #grep did not find embedinfo
#update syslog.conf
if (!-d $vardir) { mkdir($vardir); }
if (!-e $logfile)
{
touchFile($logfile);
}
runcmd("echo \"$embedinfo\" >> $syslogconf");
my $cmd = "refresh -s syslogd";
runcmd($cmd);
}
touchFile($runfile);
}
else
{
print "non-AIX platform, this scripts should not be ran.\n";
exit 1;
}
{ #first time
if ($^O =~ /^aix/i)
{
runcmd("grep \"$embedinfo\" $syslogconf", -1);
if ($::RUNCMD_RC == 1)
{ #grep did not find embedinfo
#update syslog.conf
if (!-d $vardir) { mkdir($vardir); }
if (!-e $logfile)
{
touchFile($logfile);
}
runcmd("echo \"$embedinfo\" >> $syslogconf");
my $cmd = "refresh -s syslogd";
runcmd($cmd);
}
touchFile($runfile);
}
else
{
print "non-AIX platform, this scripts should not be ran.\n";
exit 1;
}
}
#Check for errors
@ -58,14 +60,15 @@ if ($^O =~ /^aix/i)
{
unless (open(RUNFILE, "<$runfile"))
{
print "Cannot open file $runfile\n";
print "Cannot open file $runfile\n";
exit 1;
}
my $marker = <RUNFILE>;
close(RUNFILE);
my ($new_number, $new_content, $to_rfile);
# If the $runfile is empty, then we should read the $logfile from the beginning.
if (!$marker)
{
@ -75,9 +78,9 @@ if ($^O =~ /^aix/i)
{
my @info = split ':::', $marker;
my ($last_modified_time, $line_number, $mark_content) = @info;
my @stats = stat($logfile);
my $time = $stats[9];
my $time = $stats[9];
if ($time == $last_modified_time)
{
# The log file has not been updated since last modified.
@ -97,9 +100,9 @@ if ($^O =~ /^aix/i)
($new_number, $new_content, $to_rfile) = &refreshSensorFromLogfile($logfile, 0, undef);
}
}
# Get the last modified time for this log file
my @stats = stat($logfile);
my @stats = stat($logfile);
my $new_time = $stats[9];
&updateRunfile($new_time, $new_number, $new_content, $runfile);
@ -107,7 +110,7 @@ if ($^O =~ /^aix/i)
else
{
print "non-AIX platform, this scripts should not be ran.\n";
exit 1;
exit 1;
}
exit 0;
@ -131,7 +134,7 @@ sub getArgs()
print "ENTERING: $routine\n" if $::DEBUG;
my @command_line = ();
@command_line = @ARGV;
@command_line = @ARGV;
# Checks case in GetOptions
$Getopt::Long::ignorecase = 0;
@ -140,8 +143,8 @@ sub getArgs()
if (
!GetOptions(
'p=s' => \$facility_priority,
'f=s' => \$file,
'p=s' => \$facility_priority,
'f=s' => \$file,
)
)
{
@ -154,7 +157,7 @@ sub getArgs()
{
my @para = split '/', $file;
my $newpara = join '-', @para;
$runfile = "$vardir/.monaixsyslog_run" . "-$facility_priority". "-$newpara";
$runfile = "$vardir/.monaixsyslog_run" . "-$facility_priority" . "-$newpara";
}
else
{
@ -163,14 +166,14 @@ sub getArgs()
if (!$file)
{
$file = $default_file;
$file = $default_file;
}
if (!$facility_priority)
{
$facility_priority = $default_pri;
}
return ($facility_priority, $file, $runfile);
}
@ -202,10 +205,10 @@ sub refreshSensorFromLogfile()
# The file may be opened by syslogd.
exit 0;
}
my $i = 0;
my $i = 0;
my $matchflag = 0;
my $to_rfile = 0;
my $to_rfile = 0;
my $mark_content;
my $allinfo = "";
while (my $line = <FILE>)
@ -215,8 +218,8 @@ sub refreshSensorFromLogfile()
# Start reading the file from this line and push it to the sensor
# and update the mark file
$allinfo .= $line;
$i = $i + 1;
$mark_content = $line;
$i = $i + 1;
$mark_content = $line;
}
else
{
@ -229,7 +232,7 @@ sub refreshSensorFromLogfile()
if ($line eq $bgncontent)
{
$matchflag = 1;
$i = $i + 1;
$i = $i + 1;
next;
}
else
@ -244,6 +247,7 @@ sub refreshSensorFromLogfile()
if ($allinfo)
{
my $strlen = length($allinfo);
# The condition/response can not handle
# the long sensor String very well,
# use file to pass messages.
@ -270,7 +274,7 @@ sub refreshSensorFromLogfile()
}
else
{
print $allinfo;
print $allinfo;
}
}
close(FILE);
@ -300,13 +304,14 @@ sub refreshSensorFromLogfile()
sub updateRunfile()
{
my ($time, $line, $content, $file) = @_;
# the marker line is something like "last_modified_time:::line_number:::mark_content"
my $new_marker = join(":::", $time, $line, $content);
runcmd("echo \"$new_marker\" > $file");
}
#--------------------------------------------------------------------------------
=head3 runcmd
Run the given cmd and return the output in an array (already chopped). Alternatively,
if this function is used in a scalar context, the output is joined into a single string
@ -332,72 +337,74 @@ sub updateRunfile()
If refoutput is true, then the output will be returned as a reference to
an array for efficiency.
=cut
#--------------------------------------------------------------------------------
sub runcmd
{
my ($cmd, $exitcode, $refoutput) = @_;
$::RUNCMD_RC = 0;
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
my $outref = [];
@$outref = `$cmd`;
if ($?)
{
$::RUNCMD_RC = $? >> 8;
my $displayerror = 1;
my $rc;
if (defined($exitcode) && length($exitcode) && $exitcode != -2)
my ($cmd, $exitcode, $refoutput) = @_;
$::RUNCMD_RC = 0;
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
my $outref = [];
@$outref = `$cmd`;
if ($?)
{
if ($exitcode > 0)
{
$rc = $exitcode;
} # if not zero, exit with specified code
elsif ($exitcode <= 0)
{
$rc = ''; # if zero or negative, do not exit
if ($exitcode < 0) { $displayerror = 0; }
}
$::RUNCMD_RC = $? >> 8;
my $displayerror = 1;
my $rc;
if (defined($exitcode) && length($exitcode) && $exitcode != -2)
{
if ($exitcode > 0)
{
$rc = $exitcode;
} # if not zero, exit with specified code
elsif ($exitcode <= 0)
{
$rc = ''; # if zero or negative, do not exit
if ($exitcode < 0) { $displayerror = 0; }
}
}
else
{
$rc = $::RUNCMD_RC;
} # if exitcode not specified, use cmd exit code
if ($displayerror)
{
my $errmsg = '';
if (($^O =~ /^linux/i) && $::RUNCMD_RC == 139)
{
$errmsg = "Segmentation fault $errmsg";
}
else
{
# The error msgs from the -api cmds are pretty messy. Clean them up a little.
filterRmcApiOutput($cmd, $outref);
$errmsg = join('', @$outref);
chomp $errmsg;
}
print "Exit code $::RUNCMD_RC from command: $cmd\nError message from cmd: $errmsg\n"
}
}
if ($refoutput)
{
chomp(@$outref);
return $outref;
}
elsif (wantarray)
{
chomp(@$outref);
return @$outref;
}
else
{
$rc = $::RUNCMD_RC;
} # if exitcode not specified, use cmd exit code
if ($displayerror)
{
my $errmsg = '';
if (($^O =~ /^linux/i) && $::RUNCMD_RC == 139)
{
$errmsg = "Segmentation fault $errmsg";
}
else
{
# The error msgs from the -api cmds are pretty messy. Clean them up a little.
filterRmcApiOutput($cmd, $outref);
$errmsg = join('', @$outref);
chomp $errmsg;
}
print "Exit code $::RUNCMD_RC from command: $cmd\nError message from cmd: $errmsg\n"
my $line = join('', @$outref);
chomp $line;
return $line;
}
}
if ($refoutput)
{
chomp(@$outref);
return $outref;
}
elsif (wantarray)
{
chomp(@$outref);
return @$outref;
}
else
{
my $line = join('', @$outref);
chomp $line;
return $line;
}
}
#--------------------------------------------------------------------------------
=head3 filterRmcApiOutput
filter RMC Api Output
Arguments:
@ -415,26 +422,27 @@ sub runcmd
The error msgs from the RPM -api cmds are pretty messy.
This routine cleans them up a little bit.
=cut
#--------------------------------------------------------------------------------
sub filterRmcApiOutput
{
my ($cmd, $outref) = @_;
if (!($cmd =~ m|^/usr/bin/\S+-api |)) {
return;
} # give as much info as possible, if verbose
my ($cmd, $outref) = @_;
if (!($cmd =~ m|^/usr/bin/\S+-api |)) {
return;
} # give as much info as possible, if verbose
# Figure out the output delimiter
my ($d) = $cmd =~ / -D\s+(\S+)/;
if (length($d)) {
$d =~ s/^(\'|\")(.*)(\"|\')$/$2/; # remove any surrounding quotes
# escape any chars perl pattern matching would intepret as special chars
$d =~ s/([\|\^\*\+\?\.])/\\$1/g;
}
else
{
$d = '::';
} # this is the default output delimiter for the -api cmds
$$outref[0] =~ s/^ERROR${d}.*${d}.*${d}.*${d}.*${d}//;
# Figure out the output delimiter
my ($d) = $cmd =~ / -D\s+(\S+)/;
if (length($d)) {
$d =~ s/^(\'|\")(.*)(\"|\')$/$2/; # remove any surrounding quotes
# escape any chars perl pattern matching would intepret as special chars
$d =~ s/([\|\^\*\+\?\.])/\\$1/g;
}
else
{
$d = '::';
} # this is the default output delimiter for the -api cmds
$$outref[0] =~ s/^ERROR${d}.*${d}.*${d}.*${d}.*${d}//;
}
#--------------------------------------------------------------------------------
@ -448,28 +456,29 @@ sub filterRmcApiOutput
#--------------------------------------------------------------------------------
sub touchFile
{
my ($filename, $donotExit) = @_;
my $fh;
my $rc = 0;
if (!-e $filename) {
#if the file doesn't exist we need to open and close it
open($fh, ">>$filename") or $rc++;
if ($rc > 0 && !$donotExit) {
print "Touch of file $filename failed with: $!\n";
return $rc;
my ($filename, $donotExit) = @_;
my $fh;
my $rc = 0;
if (!-e $filename) {
#if the file doesn't exist we need to open and close it
open($fh, ">>$filename") or $rc++;
if ($rc > 0 && !$donotExit) {
print "Touch of file $filename failed with: $!\n";
return $rc;
}
close($fh) or $rc++;
}
close($fh) or $rc++;
}
else {
#if the file does exist we can just utime it (see the perlfunc man page entry on utime)
my $now = time;
utime($now, $now, $filename);
}
if ($rc > 0 && !$donotExit) {
print "Touch of file $filename failed with: $!\n";
return $rc;
}
return 0;
else {
#if the file does exist we can just utime it (see the perlfunc man page entry on utime)
my $now = time;
utime($now, $now, $filename);
}
if ($rc > 0 && !$donotExit) {
print "Touch of file $filename failed with: $!\n";
return $rc;
}
return 0;
}
@ -496,12 +505,12 @@ sub touchFile
sub createRandomName
{
my $name=shift;
my $name = shift;
my $nI;
for ($nI = 0 ; $nI < 8 ; $nI++)
{
my $char = ('a' .. 'z', 'A' .. 'Z')[int(rand(52)) + 1];
my $char = ('a' .. 'z', 'A' .. 'Z')[ int(rand(52)) + 1 ];
$name .= $char;
}
$name;

View File

@ -1,6 +1,7 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#------------------------------------------------------------------------------
=head1 monaixsyslog
=head2
When first run (by the sensor) this script adds an entry to the AIX ODM
@ -9,10 +10,11 @@
it checks for any logged errors. On all subsequent runs this script just
checks for errors.
=cut
#------------------------------------------------------------------------------#
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use strict;
@ -24,15 +26,15 @@ use xCAT::Utils;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
my $dirname = "xcat_err_mon";
my $vardir = "/var/opt/$dirname";
my $vardir = "/var/opt/$dirname";
my $default_runfile = "$vardir/.monerrorlog_run";
my $default_fifo = "$vardir/syslog_fifo";
my $default_pri = "*.warn";
my $default_fifo = "$vardir/syslog_fifo";
my $default_pri = "*.warn";
$::MAX_SENSOR_STRING = 65535;
my ($facility_priority, $fifo, $runfile) = &getArgs();
@ -43,20 +45,20 @@ if (isNg())
$syslogconf = "/etc/syslog-ng/syslog-ng.conf";
if (($facility_priority eq $default_pri) && ($fifo eq $default_fifo))
{
$embedinfo = "destination warn_fifo { pipe(\\\"$fifo\\\" group(root) perm(0644)); };\nlog { source(src); filter(f_warn); destination(warn_fifo); };";
$embedinfo = "destination warn_fifo { pipe(\\\"$fifo\\\" group(root) perm(0644)); };\nlog { source(src); filter(f_warn); destination(warn_fifo); };";
}
else
{
my $tmp_dest = createRandomName("fifo");
$embedinfo = "destination $tmp_dest { pipe(\\\"$fifo\\\" group(root) perm(0644)); };\nlog { source(src); filter($facility_priority); destination($tmp_dest); };";
$embedinfo = "destination $tmp_dest { pipe(\\\"$fifo\\\" group(root) perm(0644)); };\nlog { source(src); filter($facility_priority); destination($tmp_dest); };";
}
}
else
{
$syslogconf = "/etc/syslog.conf";
$embedinfo = "$facility_priority |$fifo";
$syslogconf = "/etc/syslog.conf";
$embedinfo = "$facility_priority |$fifo";
}
my $odmstanza = "$vardir/odmstanza";
my $odmstanza = "$vardir/odmstanza";
if (!-d $vardir) { mkdir($vardir); }
@ -79,170 +81,173 @@ Returns:
#--------------------------------------------------------------------------------
sub first_time_run()
{
if($^O =~ /^aix/i)
{
my $output = runcmd("/bin/odmget -q \"en_name=xcat_errlog_sen\" errnotify", -1);
if (!$output)
{
return 1;
}
return 0;
}
else
{
if (!-e $runfile)
{
return 1;
}
return 0;
}
if ($^O =~ /^aix/i)
{
my $output = runcmd("/bin/odmget -q \"en_name=xcat_errlog_sen\" errnotify", -1);
if (!$output)
{
return 1;
}
return 0;
}
else
{
if (!-e $runfile)
{
return 1;
}
return 0;
}
}
#check to see if this is the first time this script has been run
if (&first_time_run)
{ #first time
if ($^O =~ /^linux/i)
{
runcmd("grep \"$embedinfo\" $syslogconf", -1);
if ($::RUNCMD_RC == 1)
{ #grep did not find dirname
#update syslog.conf
if (!-d $vardir) { mkdir($vardir); }
if (!-e $fifo)
{
runcmd("/usr/bin/mkfifo $fifo");
}
runcmd("echo \"$embedinfo\" >> $syslogconf");
#my $cmd = service("syslog", "restart");
#runcmd($cmd);
xCAT::Utils->restartservice("syslog");
}
touchFile($runfile);
}
elsif ($^O =~ /^aix/i)
{
open(ODM, ">$odmstanza") or die $!;
print ODM '
{ #first time
if ($^O =~ /^linux/i)
{
runcmd("grep \"$embedinfo\" $syslogconf", -1);
if ($::RUNCMD_RC == 1)
{ #grep did not find dirname
#update syslog.conf
if (!-d $vardir) { mkdir($vardir); }
if (!-e $fifo)
{
runcmd("/usr/bin/mkfifo $fifo");
}
runcmd("echo \"$embedinfo\" >> $syslogconf");
#my $cmd = service("syslog", "restart");
#runcmd($cmd);
xCAT::Utils->restartservice("syslog");
}
touchFile($runfile);
}
elsif ($^O =~ /^aix/i)
{
open(ODM, ">$odmstanza") or die $!;
print ODM '
errnotify:
en_pid = 0
en_name = "xcat_errlog_sen"
en_persistenceflg = 1
en_method = "' . "$::XCATROOT/sbin/rmcmon/errmsgque" . ' sequence = $1 error_id = $2 class = $3 type = $4 alert_flags = $5 res_name = $6 res_type = $7 res_class = $8 label = $9"
';
close ODM or die $!;
runcmd("/usr/bin/odmadd $odmstanza");
}
else
{
print "unknown platform\n";
exit 1;
}
close ODM or die $!;
runcmd("/usr/bin/odmadd $odmstanza");
}
else
{
print "unknown platform\n";
exit 1;
}
}
#Check for errors
if ($^O =~ /^linux/i)
{
local $SIG{ALRM} = sub { die "alarm\n" };
eval {
alarm 4;
open(PIPE, $fifo) or die
print "cannot open file$fifo";
alarm 0;
};
if ($@ =~ /alarm/) { close PIPE; exit 0; }
local $SIG{ALRM} = sub { die "alarm\n" };
eval {
alarm 4;
open(PIPE, $fifo) or die
print "cannot open file$fifo";
alarm 0;
};
if ($@ =~ /alarm/) { close PIPE; exit 0; }
my $allinfo = "";
while (1)
{
my $line;
eval {
alarm 2;
$line = <PIPE>;
alarm 0;
};
if ($@ =~ /alarm/) {
close PIPE;
# send the messages to sensor
if ($allinfo)
{
my $strlen = length($allinfo);
# The condition/response can not handle
# the long sensor String very well,
# use file to pass messages.
# file name: /var/opt/xcat_err_mon/tmplogmsg
if ($strlen > $::MAX_SENSOR_STRING)
{
srand(time | $$);
my $filename = "$vardir/tmplogmsg_$$";
while (-e $filename)
{
$filename = createRandomName($filename);
}
if (open(TMPLOG, ">$filename"))
{
print TMPLOG $allinfo;
close TMPLOG;
print "XCAT_MONERRORLOG_FILE:$filename";
}
else
{
#open failed, why?
print "OPEN_FILE_FAILED: $filename";
}
}
else
{
print $allinfo;
}
}
my $allinfo = "";
while (1)
{
my $line;
eval {
alarm 2;
$line = <PIPE>;
alarm 0;
};
if ($@ =~ /alarm/) {
close PIPE;
exit 0;
}
$allinfo .= $line;
}
close PIPE;
# send the messages to sensor
if ($allinfo)
{
my $strlen = length($allinfo);
# The condition/response can not handle
# the long sensor String very well,
# use file to pass messages.
# file name: /var/opt/xcat_err_mon/tmplogmsg
if ($strlen > $::MAX_SENSOR_STRING)
{
srand(time | $$);
my $filename = "$vardir/tmplogmsg_$$";
while (-e $filename)
{
$filename = createRandomName($filename);
}
if (open(TMPLOG, ">$filename"))
{
print TMPLOG $allinfo;
close TMPLOG;
print "XCAT_MONERRORLOG_FILE:$filename";
}
else
{
#open failed, why?
print "OPEN_FILE_FAILED: $filename";
}
}
else
{
print $allinfo;
}
}
exit 0;
}
$allinfo .= $line;
}
close PIPE;
}
elsif ($^O =~ /^aix/i)
{
# the monitoring is stopped
if ($ENV{'SENSOR_MonitorStatus'} eq '2')
{
# stopsrc -s IBM.SensorRM will also
# set $ENV{'SENSOR_MonitorStatus'} to 2
# should not do clean up when IBM.SensorRM is stopped
if (isRMrunning("IBM.SensorRM"))
{
runcmd("/bin/odmdelete -o errnotify -q \" en_name=xcat_errlog_sen\"", -1);
if (-e $runfile)
{
unlink($runfile);
}
}
exit 0;
}
# the monitoring is stopped
if ($ENV{'SENSOR_MonitorStatus'} eq '2')
{
# stopsrc -s IBM.SensorRM will also
# set $ENV{'SENSOR_MonitorStatus'} to 2
# should not do clean up when IBM.SensorRM is stopped
if (isRMrunning("IBM.SensorRM"))
{
runcmd("/bin/odmdelete -o errnotify -q \" en_name=xcat_errlog_sen\"", -1);
if (-e $runfile)
{
unlink($runfile);
}
}
exit 0;
}
my $m = ord('xcat');
my $key = IPC::SysV::ftok("/var/adm/ras/errlog", $m);
my $buf;
my $msg = new IPC::Msg($key, IPC_CREAT | S_IRUSR | S_IWUSR);
local $SIG{ALRM} = sub { die "alarm\n" };
while (1)
{
eval {
alarm 2;
my $rectype = $msg->rcv($buf, 256);
alarm 0;
};
if ($@ =~ /alarm/) { close PIPE; exit 0; }
runcmd(
"echo \"/usr/bin/refsensor ErrorLogSensor String=\'$buf\' 1>/dev/null 2>/dev/null\" | at now",
0
);
}
my $m = ord('xcat');
my $key = IPC::SysV::ftok("/var/adm/ras/errlog", $m);
my $buf;
my $msg = new IPC::Msg($key, IPC_CREAT | S_IRUSR | S_IWUSR);
local $SIG{ALRM} = sub { die "alarm\n" };
while (1)
{
eval {
alarm 2;
my $rectype = $msg->rcv($buf, 256);
alarm 0;
};
if ($@ =~ /alarm/) { close PIPE; exit 0; }
runcmd(
"echo \"/usr/bin/refsensor ErrorLogSensor String=\'$buf\' 1>/dev/null 2>/dev/null\" | at now",
0
);
}
exit 0;
exit 0;
}
exit 0;
@ -266,7 +271,7 @@ sub getArgs()
print "ENTERING: $routine\n" if $::DEBUG;
my @command_line = ();
@command_line = @ARGV;
@command_line = @ARGV;
# Checks case in GetOptions
$Getopt::Long::ignorecase = 0;
@ -275,8 +280,8 @@ sub getArgs()
if (
!GetOptions(
'p=s' => \$facility_priority,
'f=s' => \$fifo,
'p=s' => \$facility_priority,
'f=s' => \$fifo,
)
)
{
@ -289,7 +294,7 @@ sub getArgs()
{
my @para = split '/', $fifo;
my $newpara = join '-', @para;
$runfile = "$vardir/.monerrorlog_run" . "-$facility_priority". "-$newpara";
$runfile = "$vardir/.monerrorlog_run" . "-$facility_priority" . "-$newpara";
}
else
{
@ -298,19 +303,20 @@ sub getArgs()
if (!$fifo)
{
$fifo = $default_fifo;
$fifo = $default_fifo;
}
if (!$facility_priority)
{
$facility_priority = $default_pri;
}
return ($facility_priority, $fifo, $runfile);
}
#--------------------------------------------------------------------------------
=head3 runcmd
Run the given cmd and return the output in an array (already chopped). Alternatively,
if this function is used in a scalar context, the output is joined into a single string
@ -336,72 +342,74 @@ sub getArgs()
If refoutput is true, then the output will be returned as a reference to
an array for efficiency.
=cut
#--------------------------------------------------------------------------------
sub runcmd
{
my ($cmd, $exitcode, $refoutput) = @_;
$::RUNCMD_RC = 0;
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
my $outref = [];
@$outref = `$cmd`;
if ($?)
{
$::RUNCMD_RC = $? >> 8;
my $displayerror = 1;
my $rc;
if (defined($exitcode) && length($exitcode) && $exitcode != -2)
my ($cmd, $exitcode, $refoutput) = @_;
$::RUNCMD_RC = 0;
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
my $outref = [];
@$outref = `$cmd`;
if ($?)
{
if ($exitcode > 0)
{
$rc = $exitcode;
} # if not zero, exit with specified code
elsif ($exitcode <= 0)
{
$rc = ''; # if zero or negative, do not exit
if ($exitcode < 0) { $displayerror = 0; }
}
$::RUNCMD_RC = $? >> 8;
my $displayerror = 1;
my $rc;
if (defined($exitcode) && length($exitcode) && $exitcode != -2)
{
if ($exitcode > 0)
{
$rc = $exitcode;
} # if not zero, exit with specified code
elsif ($exitcode <= 0)
{
$rc = ''; # if zero or negative, do not exit
if ($exitcode < 0) { $displayerror = 0; }
}
}
else
{
$rc = $::RUNCMD_RC;
} # if exitcode not specified, use cmd exit code
if ($displayerror)
{
my $errmsg = '';
if (($^O =~ /^linux/i) && $::RUNCMD_RC == 139)
{
$errmsg = "Segmentation fault $errmsg";
}
else
{
# The error msgs from the -api cmds are pretty messy. Clean them up a little.
filterRmcApiOutput($cmd, $outref);
$errmsg = join('', @$outref);
chomp $errmsg;
}
print "Exit code $::RUNCMD_RC from command: $cmd\nError message from cmd: $errmsg\n"
}
}
if ($refoutput)
{
chomp(@$outref);
return $outref;
}
elsif (wantarray)
{
chomp(@$outref);
return @$outref;
}
else
{
$rc = $::RUNCMD_RC;
} # if exitcode not specified, use cmd exit code
if ($displayerror)
{
my $errmsg = '';
if (($^O =~ /^linux/i) && $::RUNCMD_RC == 139)
{
$errmsg = "Segmentation fault $errmsg";
}
else
{
# The error msgs from the -api cmds are pretty messy. Clean them up a little.
filterRmcApiOutput($cmd, $outref);
$errmsg = join('', @$outref);
chomp $errmsg;
}
print "Exit code $::RUNCMD_RC from command: $cmd\nError message from cmd: $errmsg\n"
my $line = join('', @$outref);
chomp $line;
return $line;
}
}
if ($refoutput)
{
chomp(@$outref);
return $outref;
}
elsif (wantarray)
{
chomp(@$outref);
return @$outref;
}
else
{
my $line = join('', @$outref);
chomp $line;
return $line;
}
}
#--------------------------------------------------------------------------------
=head3 filterRmcApiOutput
filter RMC Api Output
Arguments:
@ -419,26 +427,27 @@ sub runcmd
The error msgs from the RPM -api cmds are pretty messy.
This routine cleans them up a little bit.
=cut
#--------------------------------------------------------------------------------
sub filterRmcApiOutput
{
my ($cmd, $outref) = @_;
if (!($cmd =~ m|^/usr/bin/\S+-api |)) {
return;
} # give as much info as possible, if verbose
my ($cmd, $outref) = @_;
if (!($cmd =~ m|^/usr/bin/\S+-api |)) {
return;
} # give as much info as possible, if verbose
# Figure out the output delimiter
my ($d) = $cmd =~ / -D\s+(\S+)/;
if (length($d)) {
$d =~ s/^(\'|\")(.*)(\"|\')$/$2/; # remove any surrounding quotes
# escape any chars perl pattern matching would intepret as special chars
$d =~ s/([\|\^\*\+\?\.])/\\$1/g;
}
else
{
$d = '::';
} # this is the default output delimiter for the -api cmds
$$outref[0] =~ s/^ERROR${d}.*${d}.*${d}.*${d}.*${d}//;
# Figure out the output delimiter
my ($d) = $cmd =~ / -D\s+(\S+)/;
if (length($d)) {
$d =~ s/^(\'|\")(.*)(\"|\')$/$2/; # remove any surrounding quotes
# escape any chars perl pattern matching would intepret as special chars
$d =~ s/([\|\^\*\+\?\.])/\\$1/g;
}
else
{
$d = '::';
} # this is the default output delimiter for the -api cmds
$$outref[0] =~ s/^ERROR${d}.*${d}.*${d}.*${d}.*${d}//;
}
#--------------------------------------------------------------------------------
@ -452,29 +461,31 @@ sub filterRmcApiOutput
#--------------------------------------------------------------------------------
sub touchFile
{
my ($filename, $donotExit) = @_;
my $fh;
my $rc = 0;
if (!-e $filename) {
#if the file doesn't exist we need to open and close it
open($fh, ">>$filename") or $rc++;
if ($rc > 0 && !$donotExit) {
print "Touch of file $filename failed with: $!\n";
return $rc;
my ($filename, $donotExit) = @_;
my $fh;
my $rc = 0;
if (!-e $filename) {
#if the file doesn't exist we need to open and close it
open($fh, ">>$filename") or $rc++;
if ($rc > 0 && !$donotExit) {
print "Touch of file $filename failed with: $!\n";
return $rc;
}
close($fh) or $rc++;
}
close($fh) or $rc++;
}
else {
#if the file does exist we can just utime it (see the perlfunc man page entry on utime)
my $now = time;
utime($now, $now, $filename);
}
if ($rc > 0 && !$donotExit) {
print "Touch of file $filename failed with: $!\n";
return $rc;
}
return 0;
else {
#if the file does exist we can just utime it (see the perlfunc man page entry on utime)
my $now = time;
utime($now, $now, $filename);
}
if ($rc > 0 && !$donotExit) {
print "Touch of file $filename failed with: $!\n";
return $rc;
}
return 0;
}
#--------------------------------------------------------------------------------
=head3 createRandomName
@ -503,13 +514,14 @@ sub createRandomName
my $nI;
for ($nI = 0 ; $nI < 8 ; $nI++)
{
my $char = ('a' .. 'z', 'A' .. 'Z')[int(rand(52)) + 1];
my $char = ('a' .. 'z', 'A' .. 'Z')[ int(rand(52)) + 1 ];
$name .= $char;
}
$name;
}
#--------------------------------------------------------------------------------
=head3 service
Send a service request to an init script.
Arguments:
@ -526,50 +538,51 @@ sub createRandomName
#--------------------------------------------------------------------------------
sub service
{
my ($service, $svcarg) = @_;
my $cmd;
my $SVCCLI = "/sbin/service";
my $SVCDIR = "/etc/init.d";
my ($service, $svcarg) = @_;
my $cmd;
my $SVCCLI = "/sbin/service";
my $SVCDIR = "/etc/init.d";
# On SLES, nfs server script is "nfsserver".
if (((-e "/etc/SuSE-release") || isHMC()) && $service eq "nfs") {
$service = "nfsserver";
}
if (-f $SVCCLI) {
$cmd = "$SVCCLI $service $svcarg ";
}
else {
$cmd = "$SVCDIR/$service $svcarg";
}
return $cmd;
# On SLES, nfs server script is "nfsserver".
if (((-e "/etc/SuSE-release") || isHMC()) && $service eq "nfs") {
$service = "nfsserver";
}
if (-f $SVCCLI) {
$cmd = "$SVCCLI $service $svcarg ";
}
else {
$cmd = "$SVCDIR/$service $svcarg";
}
return $cmd;
}
sub isHMC
{
my $hmcfile = "/opt/hsc/data/hmcType.properties";
if (-e $hmcfile) { return 1; }
else { return 0; }
my $hmcfile = "/opt/hsc/data/hmcType.properties";
if (-e $hmcfile) { return 1; }
else { return 0; }
}
sub isNg {
if (-f "/etc/SuSE-release") {
my $sysconfig="/etc/sysconfig/syslog";
my $result=`grep "^SYSLOG_DAEMON=" $sysconfig 2>&1`;
if ($result =~ /syslog-ng/) { return 1; }
my $sysconfig = "/etc/sysconfig/syslog";
my $result = `grep "^SYSLOG_DAEMON=" $sysconfig 2>&1`;
if ($result =~ /syslog-ng/) { return 1; }
}
return 0;
}
sub isRMrunning{
my $resMan = $_[0];
my @output = runcmd("LANG=C /usr/bin/lssrc -s $resMan", -1);
if ($::RUNCMD_RC) { return 0; } # maybe we should try to catch real errors here
my ($subsys, $group, $pid, $status) = split(' ', $output[1]);
if (defined($status) && $status eq 'active') {
#now check to see if IBM.AuditRM is up
return 1;
}
return 0;
sub isRMrunning {
my $resMan = $_[0];
my @output = runcmd("LANG=C /usr/bin/lssrc -s $resMan", -1);
if ($::RUNCMD_RC) { return 0; } # maybe we should try to catch real errors here
my ($subsys, $group, $pid, $status) = split(' ', $output[1]);
if (defined($status) && $status eq 'active') {
#now check to see if IBM.AuditRM is up
return 1;
}
return 0;
}

View File

@ -5,7 +5,7 @@
# Condition that is watching another Condition in a hierarchical cluster environment.
# The condition that is being watched is a batch event. This script will go th the
# node that has the watched condition, get the event batch file. And parse the file
# and then send email to a user with the detailed info of the events in the batch file.
# and then send email to a user with the detailed info of the events in the batch file.
# The batch file will be then deleted if -d flag is set.
# To use this script, create a Response that invokes this script with user id as the input.
@ -31,39 +31,39 @@ use File::Basename;
use File::Path;
my $where = join(' ', @ARGV);
my $delete=0;
my $delete = 0;
if ($where =~ /-d/) {
$delete=1;
$delete = 1;
}
$where =~ s/-d//; #remove -d
$where =~ s/-d//; #remove -d
# Convert Severity and Type environment variables from integers to strings
my @COND_SEVERITY = qw(Informational Warning Critical);
my @TYPE = ('event', 'rearm event');
my $severity=$COND_SEVERITY[$ENV{ERRM_COND_SEVERITYID}];
my $type=$TYPE[$ENV{ERRM_TYPEID }];
my @TYPE = ('event', 'rearm event');
my $severity = $COND_SEVERITY[ $ENV{ERRM_COND_SEVERITYID} ];
my $type = $TYPE[ $ENV{ERRM_TYPEID} ];
# Parse the ERRM_VALUE attribute, which will contain the EventOccurred structured data variable from the Condition class
# The fields in this structured data variable are documented below where we parse them out.
my $event = $ENV{ERRM_VALUE};
$event =~ s/^\[(.*)\]$/$1/; # SD variables have square brackets around them
$event =~ s/^\[(.*)\]$/$1/; # SD variables have square brackets around them
# This parse the LastEvent
my ( # split the SD into the following fields:
$Saved, # batch file has been saved
$filename, # location of the batch file
$Size, # The size of the batch file
) = split(/,/, $event);
my ( # split the SD into the following fields:
$Saved, # batch file has been saved
$filename, # location of the batch file
$Size, # The size of the batch file
) = split(/,/, $event);
my $sn_condname=$ENV{ERRM_RSRC_NAME};
my $sn_name=$ENV{ERRM_NODE_NAME};
my $sn_condname = $ENV{ERRM_RSRC_NAME};
my $sn_name = $ENV{ERRM_NODE_NAME};
my (
$EventTime, # Time of event expressed in seconds since 1/1/1970
$EventTimeMicros, # Number of microseconds past EventTime
) = split(/,/, $ENV{ERRM_TIME});
my (
$EventTime, # Time of event expressed in seconds since 1/1/1970
$EventTimeMicros, # Number of microseconds past EventTime
) = split(/,/, $ENV{ERRM_TIME});
my $msg;
$msg .= "The following $type occurred:\n";
@ -71,69 +71,70 @@ $msg .= " Event Time: " . convertTime($EventTime) . "\n";
$msg .= " Condition name: $ENV{ERRM_COND_NAME}\n";
$msg .= " Severiry: $severity\n";
$msg .= " Condition being monitored: $sn_condname\n";
$msg .= " Node where the condition was monitored: $sn_name\n"; # do we have to use $ERRM_NODE_NAMELIST here?
$msg .= " Node where the condition was monitored: $sn_name\n"; # do we have to use $ERRM_NODE_NAMELIST here?
$msg .= " SN batch files name: $filename\n";
#copy the batch file from sn to mn
$filename =~ s/"//g;
my $bn=basename($filename);
my $bn = basename($filename);
#printf stderr "ful path :$filename\n";
#printf stderr "base name:$bn\n";
my $dirname="/tmp/batch_process/";
if (! -d $dirname) {
my $dirname = "/tmp/batch_process/";
if (!-d $dirname) {
mkdir($dirname);
}
my $cmd;
my $isHMC=0;
my $isHMC = 0;
if ($filename =~ /\/home\/hscroot\/tmp/) {
$isHMC=1;
$cmd="scp hscroot\@$sn_name:$filename $dirname/$bn";
$isHMC = 1;
$cmd = "scp hscroot\@$sn_name:$filename $dirname/$bn";
}
else {
$cmd="scp $sn_name:$filename $dirname/$bn";
$cmd = "scp $sn_name:$filename $dirname/$bn";
}
my $rc=`$cmd 2>&1`;
my $rc = `$cmd 2>&1`;
if ($? != 0) {
$msg .= "$rc\n";
}
#now process the batch file
open(FILE1, "<$dirname/$bn");
readline(FILE1);#skip first 2 lines
readline(FILE1); #skip first 2 lines
readline(FILE1);
my $line1=readline(FILE1);
my @aTemp=split(/=/, $line1);
my $num_events=$aTemp[1];
my $line1 = readline(FILE1);
my @aTemp = split(/=/, $line1);
my $num_events = $aTemp[1];
close(FILE1);
my $count;
for ($count = 1; $count <= $num_events; $count++) {
my $content=`sed -n "/Event $count:/,/ERRM_COND_BATCH/ p" $dirname/$bn`;
my @content_array=split(/\n/, $content);
pop(@content_array); #get rid of last line
shift(@content_array); #get rid of firt line
my %content_hash=();
foreach(@content_array) {
/([^\=]+)\=(.*)/;
$content_hash{$1}=$2;
}
for ($count = 1 ; $count <= $num_events ; $count++) {
my $content = `sed -n "/Event $count:/,/ERRM_COND_BATCH/ p" $dirname/$bn`;
my @content_array = split(/\n/, $content);
pop(@content_array); #get rid of last line
shift(@content_array); #get rid of firt line
my %content_hash = ();
foreach (@content_array) {
/([^\=]+)\=(.*)/;
$content_hash{$1} = $2;
}
my $event = "Event count: $count\n";
#$event .= " Event time: " . $content_hash{ERRM_TIME} . "\n";
$event .= " Node where the event occurred: " . $content_hash{ERRM_NODE_NAMELIST} . "\n";
$event .= " Resource class: " . $content_hash{ERRM_RSRC_CLASS_PNAME} . "\n";
$event .= " Resource name: " . $content_hash{ERRM_RSRC_NAME} . "\n";
$event .= " Attribute name: " . $content_hash{ERRM_ATTR_PNAME} . "\n";
$event .= " Attribute value: " . $content_hash{ERRM_VALUE} . "\n\n";
$msg .= $event;
}
}
#send the mail out
my $rc = system(qq(echo "$msg" | write $where)) >> 8;
@ -143,9 +144,9 @@ my $rc = system(qq(echo "$msg" | write $where)) >> 8;
#remove the batch file on the sn if needed
if ($delete) {
if ($isHMC) {
`ssh -l hscroot $sn_name "rm $filename"`;
`ssh -l hscroot $sn_name "rm $filename"`;
} else {
`ssh -l root $sn_name "rm $filename"`;
`ssh -l root $sn_name "rm $filename"`;
}
}
@ -154,6 +155,6 @@ exit $rc;
# convert time string
sub convertTime {
my ($seconds, $micro) = split(/\./, $_[0]);
return strftime("%A %D %T", localtime($seconds));
my ($seconds, $micro) = split(/\./, $_[0]);
return strftime("%A %D %T", localtime($seconds));
}

View File

@ -30,46 +30,46 @@ use POSIX qw(strftime);
# Convert Severity and Type environment variables from integers to strings
my @COND_SEVERITY = qw(Informational Warning Critical);
my @TYPE = ('Event', 'Rearm event');
my $severity=$COND_SEVERITY[$ENV{ERRM_COND_SEVERITYID}];
my $type=$TYPE[$ENV{ERRM_TYPEID }];
my @TYPE = ('Event', 'Rearm event');
my $severity = $COND_SEVERITY[ $ENV{ERRM_COND_SEVERITYID} ];
my $type = $TYPE[ $ENV{ERRM_TYPEID} ];
my $where = join(' ', @ARGV);
# Parse the ERRM_VALUE attribute, which will contain the EventOccurred structured data variable from the Condition class
# The fields in this structured data variable are documented below where we parse them out.
my $event = $ENV{ERRM_VALUE};
$event =~ s/^\[(.*)\]$/$1/; # SD variables have square brackets around them
$event =~ s/^\[(.*)\]$/$1/; # SD variables have square brackets around them
# This parse the LastEvent
my ( # split the SD into the following fields:
$Occurred, # One if the condition has been triggered
$ErrNum, # Non-zero if there was in error in the event registration
$ErrMsg, # The string msg related to ErrNum
$EventFlags, # Bit mask giving some additional info about the event
$EventTime, # Time of event expressed in seconds since 1/1/1970
$EventTimeMicros, # Number of microseconds past EventTime
$ResourceHandle, # Binary address of the RMC resource that caused the condition to be triggered
$NodeName, # The node on which the event occurred. For conditions that use the management domain scope (4),
# this will be the leaf node. For conditions that use the local scope (e.g. NodeReachability),
# this will be the FMS.
$NumAttrs, # Number of attr values from the resource returned in this event
$NumAttrsInExpr, # How many of the above were attributes in the event expression
$IndexForAttrs, # The starting index of the array of values. Until new fixed fields are added
# to LastEvent, this will be the element right after this one.
$AttrArray # This list of attribute names, types, and values
) = split(/,/, $event, 12);
my ( # split the SD into the following fields:
$Occurred, # One if the condition has been triggered
$ErrNum, # Non-zero if there was in error in the event registration
$ErrMsg, # The string msg related to ErrNum
$EventFlags, # Bit mask giving some additional info about the event
$EventTime, # Time of event expressed in seconds since 1/1/1970
$EventTimeMicros, # Number of microseconds past EventTime
$ResourceHandle, # Binary address of the RMC resource that caused the condition to be triggered
$NodeName, # The node on which the event occurred. For conditions that use the management domain scope (4),
# this will be the leaf node. For conditions that use the local scope (e.g. NodeReachability),
# this will be the FMS.
$NumAttrs, # Number of attr values from the resource returned in this event
$NumAttrsInExpr, # How many of the above were attributes in the event expression
$IndexForAttrs, # The starting index of the array of values. Until new fixed fields are added
# to LastEvent, this will be the element right after this one.
$AttrArray # This list of attribute names, types, and values
) = split(/,/, $event, 12);
my @attrArray = split(/,/, $AttrArray); # Note: parsing this way does not support SDs or SD Arrays that may be in this list
my @attrArray = split(/,/, $AttrArray); # Note: parsing this way does not support SDs or SD Arrays that may be in this list
my ($ResourceName, $valuesMsg);
my $j = 0; # index into attrArray
for (my $i=0; $i<$NumAttrs; $i++) {
my $attrName = $attrArray[$j++];
my $attrType = $attrArray[$j++]; # Types <= 8 are "simple" types. Types > 8 are SDs and arrays.
my $attrValue = $attrArray[$j++];
if ($attrName eq '"Name"') { $ResourceName = $attrValue; }
$valuesMsg .= " Attribute Value $i: $attrName = $attrValue\n";
my $j = 0; # index into attrArray
for (my $i = 0 ; $i < $NumAttrs ; $i++) {
my $attrName = $attrArray[ $j++ ];
my $attrType = $attrArray[ $j++ ]; # Types <= 8 are "simple" types. Types > 8 are SDs and arrays.
my $attrValue = $attrArray[ $j++ ];
if ($attrName eq '"Name"') { $ResourceName = $attrValue; }
$valuesMsg .= " Attribute Value $i: $attrName = $attrValue\n";
}
if (!length($ResourceName)) { $ResourceName = '(unknown)'; }
@ -77,13 +77,13 @@ my $msg;
$msg .= "$severity $type occurred:\n";
$msg .= " MN Condition: $ENV{ERRM_COND_NAME}\n";
$msg .= " SN Condition: $ENV{ERRM_RSRC_NAME}\n";
$msg .= " SN: $ENV{ERRM_NODE_NAME}\n"; # do we have to use $ERRM_NODE_NAMELIST here?
$msg .= " SN: $ENV{ERRM_NODE_NAME}\n"; # do we have to use $ERRM_NODE_NAMELIST here?
$msg .= " Node: $NodeName\n";
$msg .= " Resource Name: $ResourceName\n";
$msg .= " Time: " . convertTime($EventTime) . " \n";
if (length($valuesMsg)) {
$msg .= " Attributes:\n";
$msg .= $valuesMsg;
$msg .= " Attributes:\n";
$msg .= $valuesMsg;
}
# Skipped the following: $ERRM_EXPR $ERRM_RSRC_CLASS_PNAME $ERRM_DATA_TYPE $ERRM_NODE_NAMELIST $ERRM_RSRC_TYPE
@ -100,8 +100,8 @@ exit $rc;
# convert time string
sub convertTime {
my ($seconds, $micro) = split(/\./, $_[0]);
return strftime("%A %D %T", localtime($seconds));
my ($seconds, $micro) = split(/\./, $_[0]);
return strftime("%A %D %T", localtime($seconds));
}

View File

@ -14,14 +14,14 @@ $mtime = 0;
$startdir = @ARGV[0];
chomp($startdir);
if (-d $startdir) { #directory
&directory("/", *mtime);
if (-d $startdir) { #directory
&directory("/", *mtime);
}
elsif (-f $startdir) { #file
my ($dv, $in, $m, $nl, $u, $g, $rd, $siz, $at, $mtime1) = stat($startdir);
$mtime = $mtime1;
elsif (-f $startdir) { #file
my ($dv, $in, $m, $nl, $u, $g, $rd, $siz, $at, $mtime1) = stat($startdir);
$mtime = $mtime1;
}
else { exit 1; } #not a recognized format
else { exit 1; } #not a recognized format
print $mtime;
exit 0;
@ -34,75 +34,75 @@ exit 0;
#
sub directory
{
local ($dir, *mtime, $nlink) = @_;
local ($dev, $ino, $mode, $subcount, $dirtry, $namedirtry, $name1, $name,
$dir1, $mtime1, $dv, $in, $m, $nl, $u, $g, $rd, $siz, $at);
local ($dir, *mtime, $nlink) = @_;
local ($dev, $ino, $mode, $subcount, $dirtry, $namedirtry, $name1, $name,
$dir1, $mtime1, $dv, $in, $m, $nl, $u, $g, $rd, $siz, $at);
($dev, $ino, $nlink) = stat($dir) unless $nlink;
($dev, $ino, $nlink) = stat($dir) unless $nlink;
$dirtry = $startdir;
$dirtry .= $dir;
$dirtry = $startdir;
$dirtry .= $dir;
$dir1 = substr($dir, 1);
$dir1 = substr($dir, 1);
opendir(DIR, $dirtry);
opendir(DIR, $dirtry);
local (@filenames) = readdir(DIR);
local (@filenames) = readdir(DIR);
if ($nlink == 2) {
for (@filenames) {
next if $_ eq '.';
next if $_ eq '..';
#
# Check to see if the mtime of this file is later than the current mtime
#
$name = "$dir/$_";
$name1 = "$dir1/$_";
$name2 = "/$startdir/$name1";
if ($nlink == 2) {
for (@filenames) {
next if $_ eq '.';
next if $_ eq '..';
#
# Check to see if the mtime of this file is later than the current mtime
#
$name = "$dir/$_";
$name1 = "$dir1/$_";
$name2 = "/$startdir/$name1";
($dv, $in, $m, $nl, $u, $g, $rd, $siz, $at, $mtime1) = stat($name2);
($dv, $in, $m, $nl, $u, $g, $rd, $siz, $at, $mtime1) = stat($name2);
if ($mtime1 > $mtime) {
$mtime = $mtime1;
}
if ($mtime1 > $mtime) {
$mtime = $mtime1;
}
}
}
}
else {
$subcount = $nlink - 2;
for (@filenames) {
next if $_ eq '.';
next if $_ eq '..';
else {
$subcount = $nlink - 2;
for (@filenames) {
next if $_ eq '.';
next if $_ eq '..';
#
# Check to see if the mtime of this file is later than the current mtime
#
#
# Check to see if the mtime of this file is later than the current mtime
#
$name = "$dir/$_";
$name1 = "$dir1/$_";
$name2 = "/$startdir/$name1";
$name = "$dir/$_";
$name1 = "$dir1/$_";
$name2 = "/$startdir/$name1";
($dev, $ino, $m, $nl, $u, $g, $rd, $siz, $at, $mtime1) = stat($name2);
($dev, $ino, $m, $nl, $u, $g, $rd, $siz, $at, $mtime1) = stat($name2);
if ($mtime1 > $mtime && !(-d $name2)) {
$mtime = $mtime1;
}
if ($mtime1 > $mtime && !(-d $name2)) {
$mtime = $mtime1;
}
next if $subcount == 0;
next if $subcount == 0;
#
# Recurse into next lower subdirectory
#
#
# Recurse into next lower subdirectory
#
$namedirtry = "/$startdir/";
$namedirtry .= $name;
$namedirtry = "/$startdir/";
$namedirtry .= $name;
($dev, $ino, $mode, $nlink) = lstat($namedirtry);
($dev, $ino, $mode, $nlink) = lstat($namedirtry);
#next unless -d _;
next unless { $nlink > 1 }
&directory($name, *mtime, $nlink);
#next unless -d _;
next unless { $nlink > 1 }
&directory($name, *mtime, $nlink);
--$subcount;
--$subcount;
}
}
}
}

View File

@ -1,9 +1,11 @@
#!/usr/bin/env perl
use Getopt::Long;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
#Modules to use
use lib "$::XCATROOT/lib/perl";
use xCAT::Utils;
@ -20,11 +22,11 @@ use xCAT_monitoring::rmcmetrix;
##############################################################
sub err_handle
{
my ($c, $m) = @_;
if($c != 0){
print "ERROR: $m\n";
exit($c);
}
my ($c, $m) = @_;
if ($c != 0) {
print "ERROR: $m\n";
exit($c);
}
}
###############################################################
#sub getcrontime
@ -35,57 +37,57 @@ sub err_handle
##############################################################
sub getcrontime
{
my $minute = shift @_;
my ($min, $hour, $day, $month);
my $temp = undef;
my $temp1 = undef;
$temp = $minute % 60 ;
if($temp < 2){
$min = '*';
} else {
$temp1 = $temp;
$min = '0';
while($temp1 < 60){
$min = $min.",$temp1";
$temp1 = $temp1 + $temp;
}
}
$minute = int $minute/60;
$temp = $minute % 24;
if($temp < 2){
$hour = '*';
} else {
$temp1 = $temp;
$hour = '0';
while($temp1 < 24){
$hour = $hour.",$temp1";
$temp1 = $temp1 + $temp;
}
}
$minute = int $minute/24;
$temp = $minute % 31;
if($temp < 2){
$day = '*';
} else {
$temp1 = $temp;
$day = '0';
while($day < 31){
$day = $day.",$temp1";
$temp1 = $temp1 + $temp;
}
}
$minute = int $minute/31;
$temp = $minute % 12;
if($temp < 2){
$month = '*';
} else {
$month = '0';
while($month < 12){
$month = $month.",$temp1";
$temp1 = $temp1 + $temp;
}
}
return "$min $hour $day $month *";
my $minute = shift @_;
my ($min, $hour, $day, $month);
my $temp = undef;
my $temp1 = undef;
$temp = $minute % 60;
if ($temp < 2) {
$min = '*';
} else {
$temp1 = $temp;
$min = '0';
while ($temp1 < 60) {
$min = $min . ",$temp1";
$temp1 = $temp1 + $temp;
}
}
$minute = int $minute / 60;
$temp = $minute % 24;
if ($temp < 2) {
$hour = '*';
} else {
$temp1 = $temp;
$hour = '0';
while ($temp1 < 24) {
$hour = $hour . ",$temp1";
$temp1 = $temp1 + $temp;
}
}
$minute = int $minute / 24;
$temp = $minute % 31;
if ($temp < 2) {
$day = '*';
} else {
$temp1 = $temp;
$day = '0';
while ($day < 31) {
$day = $day . ",$temp1";
$temp1 = $temp1 + $temp;
}
}
$minute = int $minute / 31;
$temp = $minute % 12;
if ($temp < 2) {
$month = '*';
} else {
$month = '0';
while ($month < 12) {
$month = $month . ",$temp1";
$temp1 = $temp1 + $temp;
}
}
return "$min $hour $day $month *";
}
################################################################
@ -97,61 +99,61 @@ sub getcrontime
# 3. To start a data collector
# ./rmcmetrixmon init resourceclass resoucename attr0, attr1, attr2, ... minute
# 4. To stop all data collectors and data consolidators
# ./rmcmetrixmon clean
# 5. To work as a data collector
# ./rmcmetrixmon clean
# 5. To work as a data collector
# ./rmcmetrixmon data resourceclass resourcename attr0, attr1, attr2, ... minute
# 6. To work as a data consolidator
# 6. To work as a data consolidator
# ./rmcmetrixmon sum resourceclass attr0, attr1, attr2, ... minute
#################################################################
#################################################################
my $cmd = $ARGV[0];
my @tabs = ();
my $entry = undef;
my $minute = undef;
my $cmd = $ARGV[0];
my @tabs = ();
my $entry = undef;
my $minute = undef;
my $crontime = undef;
my $code = 0;
my $msg = undef;
if($cmd eq 'init'){
if ($ARGV[1] eq 'rrdserver'){
$code = xCAT_monitoring::rrdutil::start_RRD_server('13900', "/var/rrd/");
&err_handle($code, "can't start RRD server");
exit 0;
}
$minute = $ARGV[4];
$crontime = &getcrontime($minute);
($code, $msg) = xCAT::Utils->add_cron_job("$crontime /opt/xcat/sbin/rmcmon/rmcmetrixmon data $ARGV[1] $ARGV[2] $ARGV[3] $ARGV[4] > /dev/null");
&err_handle($code, $msg);
if(xCAT::Utils->isMN()){
$minute = $minute * 5;
$crontime = &getcrontime($minute);
($code, $msg) = xCAT::Utils->add_cron_job("$crontime /opt/xcat/sbin/rmcmon/rmcmetrixmon sum $ARGV[1] $ARGV[3] $ARGV[4] > /dev/null");
&err_handle($code, $msg);
}
} elsif ($cmd eq 'clean'){
if ($ARGV[1] eq 'rrdserver'){
$code = xCAT_monitoring::rrdutil::stop_RRD_server();
&err_handle($code, "can't stop RRD server");
exit 0;
}
my $code = 0;
my $msg = undef;
if ($cmd eq 'init') {
if ($ARGV[1] eq 'rrdserver') {
$code = xCAT_monitoring::rrdutil::start_RRD_server('13900', "/var/rrd/");
&err_handle($code, "can't start RRD server");
exit 0;
}
$minute = $ARGV[4];
$crontime = &getcrontime($minute);
($code, $msg) = xCAT::Utils->add_cron_job("$crontime /opt/xcat/sbin/rmcmon/rmcmetrixmon data $ARGV[1] $ARGV[2] $ARGV[3] $ARGV[4] > /dev/null");
&err_handle($code, $msg);
if (xCAT::Utils->isMN()) {
$minute = $minute * 5;
$crontime = &getcrontime($minute);
($code, $msg) = xCAT::Utils->add_cron_job("$crontime /opt/xcat/sbin/rmcmon/rmcmetrixmon sum $ARGV[1] $ARGV[3] $ARGV[4] > /dev/null");
&err_handle($code, $msg);
}
} elsif ($cmd eq 'clean') {
if ($ARGV[1] eq 'rrdserver') {
$code = xCAT_monitoring::rrdutil::stop_RRD_server();
&err_handle($code, "can't stop RRD server");
exit 0;
}
$msg = `rm -rf /var/rrd/*`;
&err_handle($?, $msg);
@tabs = `/usr/bin/crontab -l 2>/dev/null;`;
foreach $entry (@tabs){
chomp($entry);
if($entry =~ /rmcmetrixmon/){
($code, $msg) = xCAT::Utils->remove_cron_job($entry);
&err_handle($code, $msg);
}
}
} elsif ($cmd eq 'data'){
($code, $msg) = &xCAT_monitoring::rmcmetrix::getmetrix($ARGV[1], $ARGV[2], $ARGV[3], $ARGV[4]);
&err_handle($code, $msg);
} elsif ($cmd eq 'sum'){
($code, $msg) = &xCAT_monitoring::rmcmetrix::get_sum_metrix($ARGV[2], $ARGV[3]);
&err_handle($code, $msg);
$msg = `rm -rf /var/rrd/*`;
&err_handle($?, $msg);
@tabs = `/usr/bin/crontab -l 2>/dev/null;`;
foreach $entry (@tabs) {
chomp($entry);
if ($entry =~ /rmcmetrixmon/) {
($code, $msg) = xCAT::Utils->remove_cron_job($entry);
&err_handle($code, $msg);
}
}
} elsif ($cmd eq 'data') {
($code, $msg) = &xCAT_monitoring::rmcmetrix::getmetrix($ARGV[1], $ARGV[2], $ARGV[3], $ARGV[4]);
&err_handle($code, $msg);
} elsif ($cmd eq 'sum') {
($code, $msg) = &xCAT_monitoring::rmcmetrix::get_sum_metrix($ARGV[2], $ARGV[3]);
&err_handle($code, $msg);
} else {
print "ERROR:Invalid parameter\n";
print "ERROR:Invalid parameter\n";
}
1;

View File

@ -6,180 +6,182 @@
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use strict;
use Getopt::Std;
use POSIX qw(strftime);
my $respname=$ENV{ERRM_ER_NAME};
my $cond_name=$ENV{ERRM_COND_NAME};
my $batch=0;
if (exists($ENV{ERRM_COND_BATCH})) { $batch=$ENV{ERRM_COND_BATCH}; }
my $respname = $ENV{ERRM_ER_NAME};
my $cond_name = $ENV{ERRM_COND_NAME};
my $batch = 0;
if (exists($ENV{ERRM_COND_BATCH})) { $batch = $ENV{ERRM_COND_BATCH}; }
my $currtime;
if (!$batch) {
my $node;
my $status;
if ($cond_name eq "NodeReachability") {
$node=$ENV{ERRM_RSRC_NAME};
$status=$ENV{ERRM_VALUE};
} elsif ($cond_name eq "NodeReachability_H") {
# Parse the ERRM_VALUE attribute, which will contain the
# LastEvent structured data variable from the Condition class
# The fields in this structured data variable are documented below where we parse them out.
my $event = $ENV{ERRM_VALUE};
$event =~ s/^\[(.*)\]$/$1/; # SD variables have square brackets around them
# This parse the LastEvent
my ( # split the SD into the following fields:
$Occurred, # One if the condition has been triggered
$ErrNum, # Non-zero if there was in error in the event registration
$ErrMsg, # The string msg related to ErrNum
$EventFlags, # Bit mask giving some additional info about the event
$EventTime, # Time of event expressed in seconds since 1/1/1970
$EventTimeMicros, # Number of microseconds past EventTime
$ResourceHandle, # Binary address of the RMC resource that caused the condition to be triggered
$NodeName, # The node on which the event occurred. For conditions that use the management domain scope (4),
# this will be the leaf node. For conditions that use the local scope (e.g. NodeReachability),
# this will be the FMS.
$NumAttrs, # Number of attr values from the resource returned in this event
$NumAttrsInExpr, # How many of the above were attributes in the event expression
$IndexForAttrs, # The starting index of the array of values. Until new fixed fields are added
# to LastEvent, this will be the element right after this one.
$AttrArray # This list of attribute names, types, and values
) = split(/,/, $event, 12);
my @attrArray = split(/,/, $AttrArray); # Note: parsing this way does not support SDs or SD Arrays that may be in this list
my $j = 0; # index into attrArray
for (my $i=0; $i<$NumAttrs; $i++) {
my $attrName = $attrArray[$j++];
my $attrType = $attrArray[$j++]; # Types <= 8 are "simple" types. Types > 8 are SDs and arrays.
my $attrValue = $attrArray[$j++];
if ($attrName eq '"Name"') { $node = $attrValue; }
if ($attrName eq '"Status"') { $status = $attrValue; }
}
} else {
`logger -t xcat -p local4.err "[mon]: updatexcatnodestatus: This script does not handle condition $cond_name"`;
exit 1;
$node = $ENV{ERRM_RSRC_NAME};
$status = $ENV{ERRM_VALUE};
} elsif ($cond_name eq "NodeReachability_H") {
# Parse the ERRM_VALUE attribute, which will contain the
# LastEvent structured data variable from the Condition class
# The fields in this structured data variable are documented below where we parse them out.
my $event = $ENV{ERRM_VALUE};
$event =~ s/^\[(.*)\]$/$1/; # SD variables have square brackets around them
# This parse the LastEvent
my ( # split the SD into the following fields:
$Occurred, # One if the condition has been triggered
$ErrNum, # Non-zero if there was in error in the event registration
$ErrMsg, # The string msg related to ErrNum
$EventFlags, # Bit mask giving some additional info about the event
$EventTime, # Time of event expressed in seconds since 1/1/1970
$EventTimeMicros, # Number of microseconds past EventTime
$ResourceHandle, # Binary address of the RMC resource that caused the condition to be triggered
$NodeName, # The node on which the event occurred. For conditions that use the management domain scope (4),
# this will be the leaf node. For conditions that use the local scope (e.g. NodeReachability),
# this will be the FMS.
$NumAttrs, # Number of attr values from the resource returned in this event
$NumAttrsInExpr, # How many of the above were attributes in the event expression
$IndexForAttrs, # The starting index of the array of values. Until new fixed fields are added
# to LastEvent, this will be the element right after this one.
$AttrArray # This list of attribute names, types, and values
) = split(/,/, $event, 12);
my @attrArray = split(/,/, $AttrArray); # Note: parsing this way does not support SDs or SD Arrays that may be in this list
my $j = 0; # index into attrArray
for (my $i = 0 ; $i < $NumAttrs ; $i++) {
my $attrName = $attrArray[ $j++ ];
my $attrType = $attrArray[ $j++ ]; # Types <= 8 are "simple" types. Types > 8 are SDs and arrays.
my $attrValue = $attrArray[ $j++ ];
if ($attrName eq '"Name"') { $node = $attrValue; }
if ($attrName eq '"Status"') { $status = $attrValue; }
}
} else {
`logger -t xcat -p local4.err "[mon]: updatexcatnodestatus: This script does not handle condition $cond_name"`;
exit 1;
}
my $status_string;
if ($status == 1) { $status_string="alive"; }
else { $status_string="unreachable"; }
if ($status == 1) { $status_string = "alive"; }
else { $status_string = "unreachable"; }
if (!$currtime) {
my (
$sec, $min, $hour, $mday, $mon,
$year, $wday, $yday, $isdst
)
= localtime(time);
$currtime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",
$mon + 1, $mday, $year + 1900,
$hour, $min, $sec);
my (
$sec, $min, $hour, $mday, $mon,
$year, $wday, $yday, $isdst
)
= localtime(time);
$currtime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",
$mon + 1, $mday, $year + 1900,
$hour, $min, $sec);
}
my $result=`$::XCATROOT/sbin/chtab node=$node nodelist.status=$status_string nodelist.statustime="$currtime" 2>&1`;
my $code=$?;
my $result = `$::XCATROOT/sbin/chtab node=$node nodelist.status=$status_string nodelist.statustime="$currtime" 2>&1`;
my $code = $?;
if ($code) {
`logger -t xcat -p local4.err "[mon]: Error saving node status ($node,$status_string) to xCAT:$result"`;
exit $code;
`logger -t xcat -p local4.err "[mon]: Error saving node status ($node,$status_string) to xCAT:$result"`;
exit $code;
}
} else { #batch event
} else { #batch event
if ($cond_name ne "NodeReachability_Batch") {
`logger -t xcat -p local4.err "[mon]: updatexcatnodestatus: This script does not handle condition $cond_name"`;
exit 1;
`logger -t xcat -p local4.err "[mon]: updatexcatnodestatus: This script does not handle condition $cond_name"`;
exit 1;
}
if ($ENV{ERRM_COND_BATCH_NUM} > 0) {
#check if event detail file exist
if (!exists($ENV{ERRM_EVENT_DETAIL_FILE})){
xCAT::MsgUtils->message('S', "logeventtoxcat: no event detail file specified in the response $respname for condition $cond_name.\n");
exit (1);
}
my $filename=$ENV{ERRM_EVENT_DETAIL_FILE};
if (! -f $filename) {
xCAT::MsgUtils->message('S', "logeventtoxcat: cannot find event detail file $filename in response $respname for condition $cond_name.\n");
exit (1);
}
if (!exists($ENV{ERRM_EVENT_DETAIL_FILE})) {
xCAT::MsgUtils->message('S', "logeventtoxcat: no event detail file specified in the response $respname for condition $cond_name.\n");
exit(1);
}
open(FILE1, "<$filename");
readline(FILE1);#skip first 2 lines
my $filename = $ENV{ERRM_EVENT_DETAIL_FILE};
if (!-f $filename) {
xCAT::MsgUtils->message('S', "logeventtoxcat: cannot find event detail file $filename in response $respname for condition $cond_name.\n");
exit(1);
}
open(FILE1, "<$filename");
readline(FILE1); #skip first 2 lines
readline(FILE1);
my $line1=readline(FILE1);
my @aTemp=split(/=/, $line1);
my $num_events=$aTemp[1];
close(FILE1);
my $line1 = readline(FILE1);
my @aTemp = split(/=/, $line1);
my $num_events = $aTemp[1];
close(FILE1);
my $count;
my @active=();
my @inactive=();
my %new_value=();
for ($count = 1; $count <= $num_events; $count++) {
my $content=`sed -n "/Event $count:/,/ERRM_COND_BATCH/ p" $filename`;
my @content_array=split(/\n/, $content);
pop(@content_array); #get rid of last line
shift(@content_array); #get rid of firt line
my %content_hash=();
foreach(@content_array) {
my $count;
my @active = ();
my @inactive = ();
my %new_value = ();
for ($count = 1 ; $count <= $num_events ; $count++) {
my $content = `sed -n "/Event $count:/,/ERRM_COND_BATCH/ p" $filename`;
my @content_array = split(/\n/, $content);
pop(@content_array); #get rid of last line
shift(@content_array); #get rid of firt line
my %content_hash = ();
foreach (@content_array) {
/([^\=]+)\=(.*)/;
$content_hash{$1}=$2;
}
$content_hash{$1} = $2;
}
my $node;
my $status;
my $status_string;
$node=$content_hash{ERRM_RSRC_NAME};
$status=$content_hash{ERRM_VALUE};
my $node;
my $status;
my $status_string;
$node = $content_hash{ERRM_RSRC_NAME};
$status = $content_hash{ERRM_VALUE};
if ($status == 1) { $new_value{$node}=1; }
else { $new_value{$node}=0; }
} #end for
if ($status == 1) { $new_value{$node} = 1; }
else { $new_value{$node} = 0; }
} #end for
foreach my $node (keys %new_value) {
if ($new_value{$node} == 1) { push(@active, $node);}
else { push(@inactive, $node);}
} #end foreach
if ($new_value{$node} == 1) { push(@active, $node); }
else { push(@inactive, $node); }
} #end foreach
if (@active > 0) {
if (!$currtime) {
my (
$sec, $min, $hour, $mday, $mon,
$year, $wday, $yday, $isdst
)
= localtime(time);
$currtime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",
$mon + 1, $mday, $year + 1900,
$hour, $min, $sec);
}
my $node_string=join(',',@active);
my $result=`XCATBYPASS=Y $::XCATROOT/bin/nodech $node_string nodelist.status=active nodelist.statustime="$currtime" 2>&1`;
my $code=$?;
if ($code) {
`logger -t xcat -p local4.warning "[mon]: Error saving node status ($node_string,active) to xCAT:$result"`;
}
}
if (@active > 0) {
if (!$currtime) {
my (
$sec, $min, $hour, $mday, $mon,
$year, $wday, $yday, $isdst
)
= localtime(time);
$currtime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",
$mon + 1, $mday, $year + 1900,
$hour, $min, $sec);
}
my $node_string = join(',', @active);
my $result = `XCATBYPASS=Y $::XCATROOT/bin/nodech $node_string nodelist.status=active nodelist.statustime="$currtime" 2>&1`;
my $code = $?;
if ($code) {
`logger -t xcat -p local4.warning "[mon]: Error saving node status ($node_string,active) to xCAT:$result"`;
}
}
if (@inactive > 0) {
if (!$currtime) {
my (
$sec, $min, $hour, $mday, $mon,
$year, $wday, $yday, $isdst
)
= localtime(time);
$currtime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",
$mon + 1, $mday, $year + 1900,
$hour, $min, $sec);
}
my $node_string=join(',',@inactive);
my $result=`XCATBYPASS=Y $::XCATROOT/bin/nodech $node_string nodelist.status=inactive nodelist.statustime="$currtime" 2>&1`;
if (!$currtime) {
my (
$sec, $min, $hour, $mday, $mon,
$year, $wday, $yday, $isdst
)
= localtime(time);
$currtime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",
$mon + 1, $mday, $year + 1900,
$hour, $min, $sec);
}
my $node_string = join(',', @inactive);
my $result = `XCATBYPASS=Y $::XCATROOT/bin/nodech $node_string nodelist.status=inactive nodelist.statustime="$currtime" 2>&1`;
my $code=$?;
if ($code) {
`logger -t xcat -p local4.warning "[mon]: Error saving node status ($node_string,inactive) to xCAT:$result"`;
}
}
}
my $code = $?;
if ($code) {
`logger -t xcat -p local4.warning "[mon]: Error saving node status ($node_string,inactive) to xCAT:$result"`;
}
}
}
}
exit 0

View File

@ -3,7 +3,7 @@
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
@ -15,8 +15,8 @@ use xCAT::NetworkUtils;
use xCAT::MsgUtils;
use Getopt::Long;
my $usage_string=
"Usage:
my $usage_string =
"Usage:
replaycons node [bps] [tail]
replaycons -h|--help
replaycons -v|--version
@ -27,93 +27,95 @@ my $usage_string=
-h|--help Display this usage statement.
-v|--version Display the version number.";
my $version_string="Version 2.0";
my $version_string = "Version 2.0";
$Getopt::Long::ignorecase=0;
if(!GetOptions(
'h|help' => \$::HELP,
'v|version' => \$::VERSION)) {
$Getopt::Long::ignorecase = 0;
if (!GetOptions(
'h|help' => \$::HELP,
'v|version' => \$::VERSION)) {
exit(1);
}
if ($::HELP) {
}
if ($::HELP) {
print "$usage_string\n";
exit(0);
}
if ($::VERSION) {
}
if ($::VERSION) {
print "$version_string\n";
exit(0);
}
}
if (@ARGV<1) {
print "Please specify a node name.\n";
exit(1);
if (@ARGV < 1) {
print "Please specify a node name.\n";
exit(1);
}
my $node = @ARGV[0];
my $bps = 19200;
if (@ARGV>1) {
$bps=@ARGV[1];
if ($bps==0) {$bps = 19200;}
my $bps = 19200;
if (@ARGV > 1) {
$bps = @ARGV[1];
if ($bps == 0) { $bps = 19200; }
}
my $tail=0;
if (@ARGV>2) { $tail=@ARGV[2];}
my $tail = 0;
if (@ARGV > 2) { $tail = @ARGV[2]; }
print "node=$node, bps=$bps, tail=$tail\n";
# get the conserver for the node
my $conserver;
my $hmtab = xCAT::Table->new('nodehm');
if ($hmtab) {
my $ent=$hmtab->getNodeAttribs($node,['node', 'conserver']);
if ($ent->{conserver}) {$conserver=$ent->{conserver};}
my $ent = $hmtab->getNodeAttribs($node, [ 'node', 'conserver' ]);
if ($ent->{conserver}) { $conserver = $ent->{conserver}; }
} else {
print "nodehm table cannot be opened\n";
exit(1);
print "nodehm table cannot be opened\n";
exit(1);
}
my $file = "/var/log/consoles/$node";
#use confluent if it is there
if ((-x "/opt/confluent/bin/confetty") || (-x "/usr/bin/confetty")) {
$file = "/var/log/confluent/consoles/$node";
$file = "/var/log/confluent/consoles/$node";
}
#print "file=$file\n";
#if has conserver, goto conserver the execute replaycons command
my @hostinfo=xCAT::NetworkUtils->determinehostname();
my %iphash=();
foreach(@hostinfo) {$iphash{$_}=1;}
my @hostinfo = xCAT::NetworkUtils->determinehostname();
my %iphash = ();
foreach (@hostinfo) { $iphash{$_} = 1; }
if (($conserver) && ($iphash{$conserver} != 1)) {
system("ssh -o BatchMode=yes $conserver $::XCATROOT/bin/replaycons $node $bps $tail 2>&1");
exit(0);
system("ssh -o BatchMode=yes $conserver $::XCATROOT/bin/replaycons $node $bps $tail 2>&1");
exit(0);
}
my $cps = $bps / 8;
my $ms = 1 / $cps;
my $msc = 0;
my $cps = $bps / 8;
my $ms = 1 / $cps;
my $msc = 0;
my $debug = 0;
my @c;
select(STDOUT);
$| = 1;
if(!open(FILE,$file)) {
print "replaycons: cannot open $file\n";
exit(1);
if (!open(FILE, $file)) {
print "replaycons: cannot open $file\n";
exit(1);
}
if($tail > 0) {
seek(FILE,-$tail,2);
if ($tail > 0) {
seek(FILE, -$tail, 2);
}
while(<FILE>) {
@c = split(//);
foreach(@c) {
print $_;
$msc += $ms;
if($msc > .1) {
select(undef, undef, undef, $msc);
$msc = 0;
while (<FILE>) {
@c = split(//);
foreach (@c) {
print $_;
$msc += $ms;
if ($msc > .1) {
select(undef, undef, undef, $msc);
$msc = 0;
}
}
}
}
close(FILE);

View File

@ -6,14 +6,17 @@
# html version).
use strict;
#use lib '.';
my $toolsdir = 'share/xcat/tools';
my $toolsdir = 'share/xcat/tools';
my $textreadme = "$toolsdir/README.txt";
my $htmlreadme = "$toolsdir/README.html";
#my $cachedir = '/tmp';
my @tools = getToolList($toolsdir);
#foreach (@tools) { print "$_\n"; }
# Put the intro text in the readme files
@ -24,14 +27,14 @@ writeintro(\*TXT, \*HTML, @tools);
# Run each tool with --help flag
foreach my $toolfile (@tools) {
my $cmd = "./$toolsdir/$toolfile --help";
my $cmd = "./$toolsdir/$toolfile --help";
my $output = `$cmd`;
if ($?) {
my $err = "Error: execution of '$cmd' failed with rc=" . ($?>>8) . ".\n";
print $err;
$output .= $err;
}
writetoolhelp(\*TXT, \*HTML, $toolfile, $output);
if ($?) {
my $err = "Error: execution of '$cmd' failed with rc=" . ($? >> 8) . ".\n";
print $err;
$output .= $err;
}
writetoolhelp(\*TXT, \*HTML, $toolfile, $output);
}
# close files
@ -44,50 +47,51 @@ exit;
# get the list of tool script files.
sub getToolList {
my $toolsdir = shift;
my $toolsdir = shift;
# 1st get toplevel dir listing
opendir(DIR, $toolsdir) or die "Error: could not read $toolsdir.\n";
my @files = grep !/^\./, readdir(DIR); # /
close(DIR);
# 1st get toplevel dir listing
opendir(DIR, $toolsdir) or die "Error: could not read $toolsdir.\n";
my @files = grep !/^\./, readdir(DIR); # /
close(DIR);
# remove files that are not regular files (not dirs) and executable
my @newlist;
foreach my $f (@files) {
my $file = "$toolsdir/$f";
if ((-f $file) && (-x $file)) { push @newlist, $f; }
}
#foreach (@files) { print "$_\n"; }
#foreach (@newlist) { print "$_\n"; }
# remove files that are not regular files (not dirs) and executable
my @newlist;
foreach my $f (@files) {
my $file = "$toolsdir/$f";
if ((-f $file) && (-x $file)) { push @newlist, $f; }
}
return sort @newlist;
#foreach (@files) { print "$_\n"; }
#foreach (@newlist) { print "$_\n"; }
return sort @newlist;
}
# print some text to both readmes
sub printtoboth {
my $txt = shift;
my $html = shift;
my $str = shift;
print $txt $str;
print $html $str;
my $txt = shift;
my $html = shift;
my $str = shift;
print $txt $str;
print $html $str;
}
# write the up front stuff of the readme
sub writeintro {
my $txt = shift; # the file handle to the txt readme file
my $html = shift; # the file handle to the html readme file
# the rest of @_ contains the tool files in the dir
my $txt = shift; # the file handle to the txt readme file
my $html = shift; # the file handle to the html readme file
# the rest of @_ contains the tool files in the dir
# write title part of readmes
print $txt <<'TXTEOS1';
# write title part of readmes
print $txt <<'TXTEOS1';
xCAT TOOL DESCRIPTIONS
----------------------
TXTEOS1
print $html <<'HTMLEOS1';
print $html <<'HTMLEOS1';
<html>
<head>
<title>xCAT Tool Descriptions</title>
@ -96,17 +100,17 @@ TXTEOS1
<h1 align="center">xCAT Tool Descriptions</h1>
HTMLEOS1
# write the table of contents for the html readme
print $html "<ul><li><a href='#Introduction'>Introduction</a>\n";
foreach my $tool (@_) {
print $html "<li><a href='#$tool'>$tool</a>\n";
}
print $html "</ul>\n";
# write the table of contents for the html readme
print $html "<ul><li><a href='#Introduction'>Introduction</a>\n";
foreach my $tool (@_) {
print $html "<li><a href='#$tool'>$tool</a>\n";
}
print $html "</ul>\n";
# write the intro
print $html "<a id='Introduction'></a><h2>Introduction</h2><p>\n";
# write the intro
print $html "<a id='Introduction'></a><h2>Introduction</h2><p>\n";
printtoboth $txt, $html, <<'EOS1';
printtoboth $txt, $html, <<'EOS1';
This is a list of additional tools that are provided by xCAT. They are located
in /opt/xcat/share/xcat/tools/, but should also be in your path. Many of these
tools have been contributed by xCAT users that are not part of the core xCAT
@ -116,20 +120,20 @@ risk. If you have problems with a tool, post to the xCAT mailing list and
the author will try to help you.
EOS1
print $html "</p>\n";
print $html "</p>\n";
}
# write the help for one tool
sub writetoolhelp {
my $txt = shift; # the file handle to the txt readme file
my $html = shift; # the file handle to the html readme file
my $toolname = shift; # the script name of the tool
my $toolhelp = shift; # the --help output from the tool
my $txt = shift; # the file handle to the txt readme file
my $html = shift; # the file handle to the html readme file
my $toolname = shift; # the script name of the tool
my $toolhelp = shift; # the --help output from the tool
# write the heading for this tool
print $txt <<"TXTEOS2";
# write the heading for this tool
print $txt <<"TXTEOS2";
$toolname
@ -137,28 +141,29 @@ $toolname
TXTEOS2
print $html <<"HTMLEOS2";
print $html <<"HTMLEOS2";
<hr>
<a id='$toolname'></a>
<h2>$toolname</h2>
<pre>
HTMLEOS2
# write the actual contents of the tool help
printtoboth $txt, $html, $toolhelp;
# write the actual contents of the tool help
printtoboth $txt, $html, $toolhelp;
# finish up
print $html <<"HTMLEOS3";
# finish up
print $html <<"HTMLEOS3";
</pre>
HTMLEOS3
}
sub writeending {
my $html = shift;
# finish up the html readme
print $html <<'HTMLEOS4';
my $html = shift;
# finish up the html readme
print $html <<'HTMLEOS4';
</body>
</html>
HTMLEOS4
}
}

View File

@ -10,157 +10,161 @@ use xCAT::NodeRange;
use Getopt::Long;
use strict;
#This or something like this must always be available and not depend on server
#Otherwise, can't set things to let server run in the first place
#
sub usage {
print "Usage:\n";
print " To add or update rows for tables:
print "Usage:\n";
print " To add or update rows for tables:
chtab [keycolname=keyvalue[,keycolname=keyvalue...]] [tablename.colname=newvalue] [tablename.colname=newvalue]...\n";
print " To delete rows from tables:
print " To delete rows from tables:
chtab -d|--delete keycolname=keyvalue[,keycolname=keyvalue...] tablename [tablename]...\n";
print " To display usage and other information:
print " To display usage and other information:
chtab [-h|--help|-v|--Version]\n\n";
print " -d|--delete Delete the rows from a list of tables.
print " -d|--delete Delete the rows from a list of tables.
-v|--version Display the version of this command.
-h|--help Display this usage information.
keycolname=keyvalue a column name-and-value pair that identifies the rows in a table to be changed.
tablename.colname=newvalue the new value for the specified row and column of the table.\n";
}
}
my %tables;
# options can be bundled up like -vV
Getopt::Long::Configure("bundling") ;
$Getopt::Long::ignorecase=0;
Getopt::Long::Configure("bundling");
$Getopt::Long::ignorecase = 0;
# parse the options
if(!GetOptions(
'd|delete' => \$::DELETE,
'h|help' => \$::HELP,
'v|version' => \$::VERSION,))
if (!GetOptions(
'd|delete' => \$::DELETE,
'h|help' => \$::HELP,
'v|version' => \$::VERSION,))
{
&usage;
exit(1);
&usage;
exit(1);
}
# display the usage if -h or --help is specified
if ($::HELP) { &usage; exit(0);}
if ($::HELP) { &usage; exit(0); }
# display the version statement if -v or --verison is specified
if ($::VERSION)
{
my $version = xCAT::Utils->Version();
print "chtab $version\n";
exit(0);
my $version = xCAT::Utils->Version();
print "chtab $version\n";
exit(0);
}
my $target = shift @ARGV;
unless ($target) {
usage;
exit(1);
usage;
exit(1);
}
my %keyhash=();
my @keypairs=split(/,/,$target);
my %keyhash = ();
my @keypairs = split(/,/, $target);
if ($keypairs[0] !~ /([^\.\=]+)\.([^\.\=]+)\=(.+)/) {
foreach (@keypairs) {
m/(.*)=(.*)/;
my $key=$1;
my $val=$2;
if (!defined($key) || !defined($val)) {
print "Incorrect argument \"$_\".\n";
usage;
exit(1);
foreach (@keypairs) {
m/(.*)=(.*)/;
my $key = $1;
my $val = $2;
if (!defined($key) || !defined($val)) {
print "Incorrect argument \"$_\".\n";
usage;
exit(1);
}
$keyhash{$key} = $val;
}
$keyhash{$key}=$val;
}
} else {
unshift(@ARGV, $target);
}
if ($::DELETE) {
#delete option is specified
my @tables_to_del=@ARGV;
if(@tables_to_del == 0) {
#delete option is specified
my @tables_to_del = @ARGV;
if (@tables_to_del == 0) {
print "Missing table name.\n";
usage;
exit(1);
}
for (@tables_to_del) {
$tables{$_} = xCAT::Table->new($_,-create => 1,-autocommit => 0);
$tables{$_}->delEntries(\%keyhash);
$tables{$_}->commit;
}
}
for (@tables_to_del) {
$tables{$_} = xCAT::Table->new($_, -create => 1, -autocommit => 0);
$tables{$_}->delEntries(\%keyhash);
$tables{$_}->commit;
}
}
else {
#update or create option
my %tableupdates;
for (@ARGV) {
my $temp;
my $table;
my $column;
my $value;
#update or create option
my %tableupdates;
for (@ARGV) {
my $temp;
my $table;
my $column;
my $value;
($table,$temp) = split('\.',$_,2);
($table, $temp) = split('\.', $_, 2);
#try to create the entry if it doesn't exist
unless ($tables{$table}) {
my $tab = xCAT::Table->new($table,-create => 1,-autocommit => 0);
if ($tab) {
$tables{$table}=$tab;
} else {
print "Table $table does not exist.\n";
exit(1);
}
#try to create the entry if it doesn't exist
unless ($tables{$table}) {
my $tab = xCAT::Table->new($table, -create => 1, -autocommit => 0);
if ($tab) {
$tables{$table} = $tab;
} else {
print "Table $table does not exist.\n";
exit(1);
}
}
#splice assignment
if(grep /\+=/, $temp) {
($column,$value) = split('\+=',$temp,2);
if (grep /\+=/, $temp) {
($column, $value) = split('\+=', $temp, 2);
#grab the current values to check against
my ($attrHash) = $tables{$table}->getAttribs(\%keyhash, $column);
my @existing = split(",",$attrHash->{$column});
my @existing = split(",", $attrHash->{$column});
#if it has values, merge the new and old ones together so no dupes
if (@existing) {
my @values = split(",",$value);
my %seen = ();
my @uniq = ();
my @values = split(",", $value);
my %seen = ();
my @uniq = ();
my $item;
foreach $item (@existing,@values) {
foreach $item (@existing, @values) {
unless ($seen{$item}) {
# if we get here, we have not seen it before
$seen{$item} = 1;
push(@uniq, $item);
}
}
$value = join(",",@uniq);
$value = join(",", @uniq);
}
}
#normal non-splicing assignment
else {
($column,$value) = split("=",$temp,2);
else {
($column, $value) = split("=", $temp, 2);
}
$tableupdates{$table}{$column}=$value;
}
#commit all the changes
foreach (keys %tables) {
if (exists($tableupdates{$_})) {
my $rc = $tables{$_}->setAttribs(\%keyhash,\%{$tableupdates{$_}});
if ($rc) {
$::exitcode = 1;
}
$tableupdates{$table}{$column} = $value;
}
#commit all the changes
foreach (keys %tables) {
if (exists($tableupdates{$_})) {
my $rc = $tables{$_}->setAttribs(\%keyhash, \%{ $tableupdates{$_} });
if ($rc) {
$::exitcode = 1;
}
}
$tables{$_}->commit;
}
$tables{$_}->commit;
}
}
if ($::exitcode) {
exit $::exitcode;
exit $::exitcode;
}

View File

@ -1,9 +1,9 @@
#!/usr/bin/env perl
# This script is used to configure the mics on the host.
# This script is run by xdsh from MN/SN to the host
# This script is used to configure the mics on the host.
# This script is run by xdsh from MN/SN to the host
# parameters
# -m xcatmaster
# -m xcatmaster
# -p the path of the mic configuration file. Generally, it's /tftpboot/xcat/miccfg/miccfg.hostname
use strict;
@ -20,16 +20,17 @@ $| = 1;
my $tmppath = "/tmp/mictmp";
my $logpath = "/var/log/xcat/";
my $logfile = "$logpath/configmic.log";
my $micmnt = "/var/mpss/mnt";
my $micmnt = "/var/mpss/mnt";
mkpath $tmppath;
mkpath $micmnt;
#open the log file
open (LOG, ">>$logfile") or die "Error: cannot open $logfile\n";
print LOG "\n\n====================================================\nStart mic configuratoin: ".`date`."\n";
open(LOG, ">>$logfile") or die "Error: cannot open $logfile\n";
print LOG "\n\n====================================================\nStart mic configuratoin: " . `date` . "\n";
my ($master, $cfgpath);
GetOptions ('m=s'=>\$master, 'p=s'=>\$cfgpath);
GetOptions('m=s' => \$master, 'p=s' => \$cfgpath);
unless ($master && $cfgpath) {
outputmsg("Error: the -m master and -p path arguments must be specified for configmic.\n", 1);
}
@ -41,7 +42,7 @@ if ($masterip) {
chomp($masterip);
my $myip = `ip route get $masterip| head -n 1 | sed 's/^.*src//g' | awk {'print \$1'}`;
if ($myip) {
my $myipinfo =`getent hosts $myip`;
my $myipinfo = `getent hosts $myip`;
if ($myipinfo && $myipinfo =~ /([^\s]+)\s+([^\s]+)\s+([^\s]+)/) {
my $n1 = $2;
@ -67,22 +68,23 @@ unless ($nodename_short) {
# download the mic configuration file from master
my $cmd = "wget -N --waitretry=10 --random-wait -T 60 http://$master/$cfgpath/miccfg.$nodename_short -P $tmppath";
my ($rc, $output) = runsyscmd ($cmd);
my ($rc, $output) = runsyscmd($cmd);
if ($rc) {
$cmd = "wget -N --waitretry=10 --random-wait -T 60 http://$master/$cfgpath/miccfg.$nodename -P $tmppath";
runsyscmd ($cmd, "Error: failed to download mic configuration file from $master\n", 3);
runsyscmd($cmd, "Error: failed to download mic configuration file from $master\n", 3);
} else {
# use the correct short hotname in $nodename_short
$nodename=$nodename_short;
$nodename = $nodename_short;
}
unless (-r "$tmppath/miccfg.$nodename") {
runsyscmd ("Error: cannot get the mic configuration file from http://$master/$cfgpath/miccfg.$nodename\n", 4);
runsyscmd("Error: cannot get the mic configuration file from http://$master/$cfgpath/miccfg.$nodename\n", 4);
}
# parse the configuration file
unless (open (CFGFILE, "<$tmppath/miccfg.$nodename")) {
runsyscmd ("Error: cannot open $tmppath/miccfg.$nodename\n", 5);
# parse the configuration file
unless (open(CFGFILE, "<$tmppath/miccfg.$nodename")) {
runsyscmd("Error: cannot open $tmppath/miccfg.$nodename\n", 5);
}
# the configureation file should have the following format
@ -99,11 +101,12 @@ my $brgname;
my $brgip;
my $brgtype;
while (<CFGFILE>) {
if (/(\d+):(.*)/) {
my $deviceid = $1;
my @params = split (/\|/, $2);
my @params = split(/\|/, $2);
foreach (@params) {
my ($n, $v) = split (/=/, $_, 2);
my ($n, $v) = split(/=/, $_, 2);
$miccfg{$deviceid}{$n} = $v;
if ($n eq 'br') {
$brgname = $v;
@ -125,36 +128,39 @@ while (<CFGFILE>) {
}
}
}
close (CFGFILE);
close(CFGFILE);
$miclist =~ s/,/ /g;
# add the mount entry for mounting of root fs from master to /etc/fstab
# e.g. mount $master:/install/mpss3 /var/mpss/mnt
$cmd = "grep \'$master:$ospath \' $micmnt /etc/fstab ";
($rc, $output) = runsyscmd ($cmd);
($rc, $output) = runsyscmd($cmd);
if ($rc) {
# not found the exact mount entry
$cmd = "grep $micmnt /etc/fstab";
($rc, $output) = runsyscmd ($cmd);
($rc, $output) = runsyscmd($cmd);
if (!$rc) {
# found the mount to $micmnt with another master or directory, remove the entry and umount it
my $trans = $micmnt;
$trans =~ s/\//\\\//g;
$cmd = "sed \"/$trans/d\" /etc/fstab > $tmppath/fstab.tmp";
runsyscmd ($cmd, "Error: failed to configure fstab.\n", 6);
copy ("$tmppath/fstab.tmp", "/etc/fstab");
runsyscmd($cmd, "Error: failed to configure fstab.\n", 6);
copy("$tmppath/fstab.tmp", "/etc/fstab");
$cmd = "umount -l -f $micmnt";
runsyscmd ($cmd, "Error: failed to run umount -l -f $micmnt\n", 7);
runsyscmd($cmd, "Error: failed to run umount -l -f $micmnt\n", 7);
}
$cmd = "echo \"$master:$ospath $micmnt nfs timeo=14,intr 1 2\" >>/etc/fstab";
runsyscmd ($cmd);
runsyscmd($cmd);
$cmd = "mount -a";
runsyscmd ($cmd);
runsyscmd($cmd);
} else {
# run mount -a anyway
$cmd = "mount -a";
runsyscmd ($cmd);
runsyscmd($cmd);
}
# the dir structure in mount opint 'mnt'
@ -175,27 +181,27 @@ if ($rc) {
# | |--xx.filelist
# | `--xx
# make sure the remote files are accessable
# make sure the remote files are accessable
unless (-r "$micmnt/common.filelist") {
outputmsg("Error: cannot access the $micmnt/common.filelist\n", 8);
}
# initialize mic card if it has not been
if (! -f "/etc/mpss/default.conf") {
if (!-f "/etc/mpss/default.conf") {
$cmd = "micctrl --initdefaults";
runsyscmd ($cmd, "Error: failed to initiate the mic configuration file.\n", 200)
runsyscmd($cmd, "Error: failed to initiate the mic configuration file.\n", 200)
}
# start to configure the mic
# stop the mpss service first
$cmd = "service mpss stop";
runsyscmd ($cmd, "Error: failed to stop mpss service.\n", 100);
runsyscmd($cmd, "Error: failed to stop mpss service.\n", 100);
# make sute the mpss has been stopped
my $i = 5;
while ($i > 0) {
$cmd = "service mpss status";
($rc, $output) = runsyscmd ($cmd);
$cmd = "service mpss status";
($rc, $output) = runsyscmd($cmd);
if (grep /mpss is stopped/, @$output) {
last;
}
@ -204,16 +210,16 @@ while ($i > 0) {
}
# remove the mic configuration files and source files for ramfs, them will be recreated base on setting
unlink ("/etc/mpss/default.conf");
foreach my $mic (split (/ /, $miclist)) {
unlink ("/etc/mpss/$mic.conf");
unlink ("/var/mpss/$mic.filelist");
rmtree ("/var/mpss/$mic");
unlink("/etc/mpss/default.conf");
foreach my $mic (split(/ /, $miclist)) {
unlink("/etc/mpss/$mic.conf");
unlink("/var/mpss/$mic.filelist");
rmtree("/var/mpss/$mic");
}
# reset the configuration to default
$cmd = "micctrl --initdefaults $miclist";
runsyscmd ($cmd, "Error: failed to initiate the mic devices.\n", 200);
runsyscmd($cmd, "Error: failed to initiate the mic devices.\n", 200);
# configure the base dir
#$cmd = "micctrl --basedir=/opt/intel/mic/mnt/opt/intel/mic/filesystem/base --list=/opt/intel/mic/mnt/opt/intel/mic/filesystem/base.filelist $miclist";
@ -221,16 +227,16 @@ runsyscmd ($cmd, "Error: failed to initiate the mic devices.\n", 200);
# configure the commondir
$cmd = "micctrl --commondir=$micmnt/common --list=$micmnt/common.filelist $miclist";
runsyscmd ($cmd, "Error: failed to set the common dir for mic file system.\n", 102);
runsyscmd($cmd, "Error: failed to set the common dir for mic file system.\n", 102);
# configure the overlay file system
my @ols = split (/,/, $overlay);
my @ols = split(/,/, $overlay);
foreach (@ols) {
if (/^filelist:(.+)/) {
$cmd = "micctrl --overlay=Filelist --source=$micmnt/overlay/$1/ --target=$micmnt/overlay/$1.filelist --state=on $miclist";
} elsif (/^ofilelist:(.+)/) { # for 2.8.4 and later
} elsif (/^ofilelist:(.+)/) { # for 2.8.4 and later
$cmd = "micctrl --overlay=Filelist --source=$micmnt/overlay/rootimg/ --target=$micmnt/overlay/rootimg/opt/mic/$1.filelist --state=on $miclist";
} elsif (/^pfilelist:(.+)/) { # only for 2.8.3
} elsif (/^pfilelist:(.+)/) { # only for 2.8.3
$cmd = "micctrl --overlay=Filelist --source=$micmnt/overlay/package/ --target=$micmnt/overlay/package/opt/mic/$1.filelist --state=on $miclist";
} elsif (/^rpm:(.+)/) {
$cmd = "micctrl --overlay=RPM --source=$micmnt/overlay/rpm/ --state=on $miclist";
@ -238,26 +244,27 @@ foreach (@ols) {
$cmd = "micctrl --overlay=Simple --source=$micmnt/overlay/simple/$1 --target=$2 --state=on $miclist";
}
runsyscmd ($cmd, "Error: failed to set the overlay dir for mic file system.\n", 103);
runsyscmd($cmd, "Error: failed to set the overlay dir for mic file system.\n", 103);
}
# configure bridge for mic
my ($netbit, $brc, $mtu);
if ($brgtype && $brgtype =~ /Internal/i) {
$cmd = "micctrl --addbridge=$brgname --type=Internal --ip=$brgip";
runsyscmd ($cmd, "Error: failed to add bridge for mic.\n", 111);
runsyscmd($cmd, "Error: failed to add bridge for mic.\n", 111);
} else {
# for External bridge, it must has been set up correctly
# get the ip of the bridge
$cmd = "ip -4 addr show";
($rc, $output) = runsyscmd ($cmd);
($rc, $output) = runsyscmd($cmd);
$cmd = "ip -4 route show";
my ($rc2, $output2) = runsyscmd ($cmd);
my ($rc2, $output2) = runsyscmd($cmd);
foreach (@$output) {
if (/inet\s+([\d\.]+)\/(\d+)\s+brd\s+([\d\.]+) scope global $brgname/) {
$brgip = $1;
$brgip = $1;
$netbit = $2;
$brc = $3;
$brc = $3;
last;
} elsif (/\d+:\s+$brgname:.*mtu\s+(\d+)/) {
$mtu = $1;
@ -274,16 +281,18 @@ if ($brgtype && $brgtype =~ /Internal/i) {
#$cmd = "echo \"Bridge $brg External $brip $netbit $mtu\" >> /etc/sysconfig/mic/default.conf";
#runsyscmd ($cmd);
$cmd = "micctrl --addbridge=$brgname --type=external --ip=$brgip --netbits=$netbit --mtu=$mtu";
runsyscmd ($cmd, "Error: failed to add bridge for mic.\n", 111);
runsyscmd($cmd, "Error: failed to add bridge for mic.\n", 111);
}
# do the mic specific configuration
foreach my $micid (keys %miccfg) {
if ($micid !~ /^\d*$/) {
# not mic specific, return
next;
}
my $micname = $miccfg{$micid}{'name'};
# set the boot device to be staticramfs so that the osimage don't need to generated for every boot
#$cmd = "micctrl --rootdev=StaticRamFS --target=/opt/intel/mic/filesystem/$micname.image mic$micid";
#runsyscmd ($cmd, "Error: failed to set root image for mic.\n", 104);
@ -295,71 +304,73 @@ foreach my $micid (keys %miccfg) {
# set the autoboot
if ($miccfg{$micid}{'onboot'} =~ /no/i) {
$cmd = "micctrl --autoboot=no mic$micid";
runsyscmd ($cmd, "Error: failed to set the autoboot for mic.\n", 106);
} elsif($miccfg{$micid}{'onboot'} =~ /yes/i) {
runsyscmd($cmd, "Error: failed to set the autoboot for mic.\n", 106);
} elsif ($miccfg{$micid}{'onboot'} =~ /yes/i) {
$cmd = "micctrl --autoboot=yes mic$micid";
runsyscmd ($cmd, "Error: failed to set the autoboot for mic.\n", 106);
runsyscmd($cmd, "Error: failed to set the autoboot for mic.\n", 106);
}
# set the hostname
$cmd = "sed \"s/Hostname .*/Hostname \"$micname\"/\" /etc/mpss/mic$micid.conf > $tmppath/mic$micid.conf";
runsyscmd ($cmd, "Error: failed to set hostname for mic.\n", 107);
copy ("$tmppath/mic$micid.conf", "/etc/mpss/mic$micid.conf");
runsyscmd($cmd, "Error: failed to set hostname for mic.\n", 107);
copy("$tmppath/mic$micid.conf", "/etc/mpss/mic$micid.conf");
# configure the Verbose log
if ($miccfg{$micid}{'vlog'} =~ /yes/i) {
$cmd = "sed \"s/VerboseLogging .*/VerboseLogging \"Enabled\"/\" /etc/mpss/mic$micid.conf > $tmppath/mic$micid.conf";
runsyscmd ($cmd, "Error: failed to set Verbose log for mic.\n", 108);
copy ("$tmppath/mic$micid.conf", "/etc/mpss/mic$micid.conf");
runsyscmd($cmd, "Error: failed to set Verbose log for mic.\n", 108);
copy("$tmppath/mic$micid.conf", "/etc/mpss/mic$micid.conf");
}
# configure the power management
if (defined ($miccfg{$micid}{'powermgt'})) {
if (defined($miccfg{$micid}{'powermgt'})) {
$cmd = "micctrl --pm=set ";
foreach my $item (split (/!/, $miccfg{$micid}{'powermgt'})) {
foreach my $item (split(/!/, $miccfg{$micid}{'powermgt'})) {
$cmd .= " --$item ";
}
$cmd .= " mic$micid";
runsyscmd ($cmd, "Error: failed to set power management for mic.\n", 109);
runsyscmd($cmd, "Error: failed to set power management for mic.\n", 109);
}
# configure network for each mic
$cmd = "micctrl --network=static --bridge=".$miccfg{$micid}{br}." --ip=".$miccfg{$micid}{ip}." mic$micid";
runsyscmd ($cmd, "Error: failed to generate IP configuration for mic.\n", 104);
$cmd = "micctrl --network=static --bridge=" . $miccfg{$micid}{br} . " --ip=" . $miccfg{$micid}{ip} . " mic$micid";
runsyscmd($cmd, "Error: failed to generate IP configuration for mic.\n", 104);
# configure nfs mount for each mic
foreach my $msrc (keys %{$miccfg{'micmount'}}) {
foreach my $msrc (keys %{ $miccfg{'micmount'} }) {
my $mntsrc;
if (defined $miccfg{$micid}{'statemnt'}) {
if ($miccfg{$micid}{'statemnt'} =~ /:/) {
# for 'statemnt' is a nfs server plus dir like 192.168.1:/nfs
$mntsrc = $miccfg{$micid}{'statemnt'}."/$msrc";
$mntsrc = $miccfg{$micid}{'statemnt'} . "/$msrc";
} else {
# for 'statemnt' is a nfs server ip 192.168.0.1
$mntsrc = $miccfg{$micid}{'statemnt'}.":/$msrc";
$mntsrc = $miccfg{$micid}{'statemnt'} . ":/$msrc";
}
} else {
$mntsrc = "$brgip:/$msrc";
}
$cmd = "micctrl --addnfs=$mntsrc --dir=$miccfg{micmount}{$msrc} mic$micid";
runsyscmd ($cmd, "Error: failed to add nfs mount for mic.\n", 104);
runsyscmd($cmd, "Error: failed to add nfs mount for mic.\n", 104);
# since there's a bug that nfsserver cannot be set, just manully change it
if ($mntsrc =~ /^(.+):/) {
if ($1 ne $brgip) {
$cmd = "sed -i \'s/$brgip/$1/g\' /var/mpss/mic$micid/etc/fstab";
runsyscmd ($cmd, "Error: failed to hack nfs mount for mic.\n", 104);
runsyscmd($cmd, "Error: failed to hack nfs mount for mic.\n", 104);
}
}
}
# take the configuration to effect
$cmd = "micctrl --resetconfig mic$micid";
runsyscmd ($cmd, "Error: failed to spread the configuration.\n", 201);
runsyscmd($cmd, "Error: failed to spread the configuration.\n", 201);
# back up the /etc/passwd and /etc/shadow which generated by 'micctrl --initdefaults'
system ("/bin/cp -rf /var/mpss/mic$micid/etc/passwd /tmp/mictmp/passwd");
system ("/bin/cp -rf /var/mpss/mic$micid/etc/shadow /tmp/mictmp/shadow");
system("/bin/cp -rf /var/mpss/mic$micid/etc/passwd /tmp/mictmp/passwd");
system("/bin/cp -rf /var/mpss/mic$micid/etc/shadow /tmp/mictmp/shadow");
# copy the system files which generated by genimage to the micdir
# e.g. /etc/hosts /etc/passwd ...
@ -367,15 +378,15 @@ foreach my $micid (keys %miccfg) {
my $dst = "/var/mpss/mic$micid";
$cmd = "/bin/cp -rf $src $dst";
runsyscmd ($cmd, "Error: failed to copy the overlay dir.\n", 300);
runsyscmd($cmd, "Error: failed to copy the overlay dir.\n", 300);
# append /etc/passwd and /etc/shadow which generated by 'micctrl --initdefaults'
system ("/bin/grep micuser /tmp/mictmp/passwd >> /var/mpss/mic$micid/etc/passwd");
system ("/bin/grep micuser /tmp/mictmp/shadow >> /var/mpss/mic$micid/etc/shadow");
system("/bin/grep micuser /tmp/mictmp/passwd >> /var/mpss/mic$micid/etc/passwd");
system("/bin/grep micuser /tmp/mictmp/shadow >> /var/mpss/mic$micid/etc/shadow");
# generate the static root file system in ramdisk format
$cmd = "micctrl --updateramfs mic$micid";
runsyscmd ($cmd, "Error: failed to generate the static ramfs.\n", 301);
runsyscmd($cmd, "Error: failed to generate the static ramfs.\n", 301);
}
# start the mpss service after the configuration
@ -384,8 +395,8 @@ system($cmd);
$i = 5;
while ($i > 0) {
$cmd = "service mpss status";
($rc, $output) = runsyscmd ($cmd, "Error: failed to get the status of mpss.\n", 100);
$cmd = "service mpss status";
($rc, $output) = runsyscmd($cmd, "Error: failed to get the status of mpss.\n", 100);
if (grep /mpss is running/, @$output) {
last;
}
@ -396,29 +407,30 @@ while ($i > 0) {
# notice nodeset command, the configuratoin has been done
foreach my $micid (keys %miccfg) {
if ($micid !~ /^\d*$/) {
# not mic specific, return
next;
}
outputmsg ("MICMSG:$miccfg{$micid}{'name'}: Done\n");
outputmsg("MICMSG:$miccfg{$micid}{'name'}: Done\n");
}
print LOG "mpss has been started\n";
print LOG "\nFinish the mic configuratoin: ".`date`."====================================================\n";
print LOG "\nFinish the mic configuratoin: " . `date` . "====================================================\n";
close (LOG);
close(LOG);
exit 0;
# run command
sub runsyscmd {
my $cmd = shift;
my $cmd = shift;
my $errmsg = shift;
my $rc = shift;
my $rc = shift;
print LOG "---------------------------------------------\n";
print LOG "Run command: $cmd\n";
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
my @output = `$cmd`;
my $errcode = 0;
@ -439,9 +451,9 @@ sub runsyscmd {
}
# display the output message
sub outputmsg{
sub outputmsg {
my $msg = shift;
my $rc =shift;
my $rc = shift;
print LOG $msg;
print $msg;
if ($rc) {

View File

@ -1,9 +1,9 @@
#!/usr/bin/env perl
# This script is used to flash the mics on the host.
# This script is run by xdsh from MN/SN to the host
# This script is used to flash the mics on the host.
# This script is run by xdsh from MN/SN to the host
# parameters
# -m xcatmaster
# -m xcatmaster
# -p the path of the mic configuration file. Generally, it's /tftpboot/xcat/miccfg/micflash.hostname
use strict;
@ -17,24 +17,25 @@ use Getopt::Long;
select STDOUT;
$| = 1;
my $tmppath = "/tmp/mictmp";
my $logpath = "/var/log/xcat/";
my $logfile = "$logpath/flash.log";
my $micmnt = "/var/mpss/mnt";
my $tmppath = "/tmp/mictmp";
my $logpath = "/var/log/xcat/";
my $logfile = "$logpath/flash.log";
my $micmnt = "/var/mpss/mnt";
my $flashpath = "$micmnt/usr/share/mpss/flash";
if (! -d "$flashpath") {
if (!-d "$flashpath") {
$flashpath = "/usr/share/mpss/flash";
}
mkpath $tmppath;
mkpath $micmnt;
#open the log file
open (LOG, ">>$logfile") or die "Error: cannot open $logfile\n";
print LOG "\n\n====================================================\nStart mic flashing: ".`date`."\n";
open(LOG, ">>$logfile") or die "Error: cannot open $logfile\n";
print LOG "\n\n====================================================\nStart mic flashing: " . `date` . "\n";
my ($master, $cfgpath);
GetOptions ('m=s'=>\$master, 'p=s'=>\$cfgpath);
GetOptions('m=s' => \$master, 'p=s' => \$cfgpath);
unless ($master && $cfgpath) {
outputmsg("Error: the -m master and -p path arguments must be specified for configmic.\n", 1);
}
@ -46,7 +47,7 @@ if ($masterip) {
chomp($masterip);
my $myip = `ip route get $masterip| head -n 1 | sed 's/^.*src//g' | awk {'print \$1'}`;
if ($myip) {
my $myipinfo =`getent hosts $myip`;
my $myipinfo = `getent hosts $myip`;
if ($myipinfo && $myipinfo =~ /([^\s]+)\s+([^\s]+)\s+([^\s]+)/) {
my $n1 = $2;
@ -72,19 +73,19 @@ unless ($nodename_short) {
# download the mic configuration file from master
my $cmd = "wget -N --waitretry=10 --random-wait -T 60 http://$master/$cfgpath/micflash.$nodename_short -P $tmppath";
my ($rc, $output) = runsyscmd ($cmd);
my ($rc, $output) = runsyscmd($cmd);
if ($rc) {
$cmd = "wget -N --waitretry=10 --random-wait -T 60 http://$master/$cfgpath/micflash.$nodename -P $tmppath";
runsyscmd ($cmd, "Error: failed to download mic configuration file from $master\n", 3);
runsyscmd($cmd, "Error: failed to download mic configuration file from $master\n", 3);
}
unless (-r "$tmppath/micflash.$nodename") {
runsyscmd ("Error: cannot get the mic configuration file from http://$master/$cfgpath/micflash.$nodename\n", 4);
runsyscmd("Error: cannot get the mic configuration file from http://$master/$cfgpath/micflash.$nodename\n", 4);
}
# parse the configuration file
unless (open (CFGFILE, "<$tmppath/micflash.$nodename")) {
runsyscmd ("Error: cannot open $tmppath/micflash.$nodename\n", 5);
# parse the configuration file
unless (open(CFGFILE, "<$tmppath/micflash.$nodename")) {
runsyscmd("Error: cannot open $tmppath/micflash.$nodename\n", 5);
}
# the configureation file should have the following format
@ -98,43 +99,45 @@ my $ospath;
while (<CFGFILE>) {
if (/(\d+):(.*)/) {
my $deviceid = $1;
my @params = split (/\|/, $2);
my @params = split(/\|/, $2);
foreach (@params) {
my ($n, $v) = split (/=/, $_);
my ($n, $v) = split(/=/, $_);
$miccfg{$deviceid}{$n} = $v;
}
} elsif (/^miclist=(.*)/) {
$miclist = $1;
} elsif (/^imgpath=(.*)/) {
$ospath= $1;
$ospath = $1;
}
}
close (CFGFILE);
close(CFGFILE);
$miclist =~ s/,/ /g;
# add the mount entry for mounting of root fs from master to /etc/fstab
# e.g. mount $master:/install/mpss3 /var/mpss/mnt
$cmd = "grep \'$master:$ospath \' $micmnt /etc/fstab ";
($rc, $output) = runsyscmd ($cmd);
($rc, $output) = runsyscmd($cmd);
if ($rc) {
# not found the exact mount entry
$cmd = "grep $micmnt /etc/fstab";
($rc, $output) = runsyscmd ($cmd);
($rc, $output) = runsyscmd($cmd);
if (!$rc) {
# found the mount to $micmnt with another master or directory, remove the entry and umount it
my $trans = $micmnt;
$trans =~ s/\//\\\//g;
$cmd = "sed \"/$trans/d\" /etc/fstab > $tmppath/fstab.tmp";
runsyscmd ($cmd, "Error: failed to configure fstab.\n", 6);
copy ("$tmppath/fstab.tmp", "/etc/fstab");
runsyscmd($cmd, "Error: failed to configure fstab.\n", 6);
copy("$tmppath/fstab.tmp", "/etc/fstab");
$cmd = "umount -l -f $micmnt";
runsyscmd ($cmd, "Error: failed to run umount -l -f $micmnt\n", 7);
runsyscmd($cmd, "Error: failed to run umount -l -f $micmnt\n", 7);
}
$cmd = "echo \"$master:$ospath $micmnt nfs timeo=14,intr 1 2\" >>/etc/fstab";
runsyscmd ($cmd);
runsyscmd($cmd);
$cmd = "mount -a";
runsyscmd ($cmd);
runsyscmd($cmd);
}
# make sure the remote flash directory is accessable
@ -146,7 +149,7 @@ unless (-d "$flashpath") {
# #
# # reset the mic to ready stat
$cmd = "micctrl -r -w $miclist";
($rc, $output) = runsyscmd ($cmd, "Error: failed to reset mic.\n", 100);
($rc, $output) = runsyscmd($cmd, "Error: failed to reset mic.\n", 100);
my $micidlist;
foreach my $micid (keys %miccfg) {
@ -160,34 +163,34 @@ $micidlist =~ s/^,//;
# do the flash
$cmd = "micflash -update $flashpath -device $micidlist";
($rc, $output) = runsyscmd ($cmd);
($rc, $output) = runsyscmd($cmd);
# generate the output messages
foreach (@$output) {
foreach my $line (split /\n/, $_) {
if ($line =~ /^mic(\d+):/) {
$line =~ s/^mic(\d+):/MICMSG:$miccfg{$1}{'name'}:/;
}
print $line."\n";
if ($line =~ /^mic(\d+):/) {
$line =~ s/^mic(\d+):/MICMSG:$miccfg{$1}{'name'}:/;
}
print $line. "\n";
}
}
print LOG "\nFinish the mic flashing: ".`date`."====================================================\n";
print LOG "\nFinish the mic flashing: " . `date` . "====================================================\n";
close (LOG);
close(LOG);
exit 0;
# run command
sub runsyscmd {
my $cmd = shift;
my $cmd = shift;
my $errmsg = shift;
my $rc = shift;
my $rc = shift;
print LOG "---------------------------------------------\n";
print LOG "Run command: $cmd\n";
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
my @output = `$cmd`;
my $errcode = 0;
@ -208,9 +211,9 @@ sub runsyscmd {
}
# display the output message
sub outputmsg{
sub outputmsg {
my $msg = shift;
my $rc =shift;
my $rc = shift;
print LOG $msg;
print $msg;
if ($rc) {

View File

@ -3,7 +3,7 @@
#package xCAT_monitoring::performance;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use xCAT::NodeRange;
@ -20,178 +20,205 @@ use strict;
use warnings;
1;
performance();
sub performance
{ #opening subroutine
my $noderef=xCAT_monitoring::monitorctrl->getMonHierarchy();
#identification of this node
my @hostinfo=xCAT::NetworkUtils->determinehostname();
#print "hosT:@hostinfo\n";
my $isSV=xCAT::Utils->isServiceNode();
#print "is sv is:$isSV \n";
my %iphash=();
foreach(@hostinfo) {$iphash{$_}=1;}
if (!$isSV) { $iphash{'noservicenode'}=1;}
my @children;
my $str;
foreach my $key (keys (%$noderef))
{ #opening foreach1
#print "opening foreach1 \n";
#print "key is: $key \n";
my @key_a=split(':', $key);
if (! $iphash{$key_a[0]}) { next;}
my $mon_nodes=$noderef->{$key};
sub performance
{ #opening subroutine
foreach(@$mon_nodes)
{ #opening foreach2
my $node=$_->[0];
my $nodetype=$_->[1];
#print "node=$node, nodetype=$nodetype\n";
if (($nodetype) && ($nodetype =~ /$::NODETYPE_OSI/))
{
push(@children,$node);
}
} #closing foreach2
} #closing foreach1
#print "children:@children\n";
my $count_child=@children;
if($count_child > 0)
{ #opening if count_child 1
#print "number of children is $count_child \n";
no strict;
no warnings;
#my $i=0;
my @inactive_children;
for ($i = 0;$i < $count_child;$i++)
{ #opening if count_child 2
$str=`pmdumptext -c $::XCATROOT/lib/perl/xCAT_monitoring/pcp/pcpmon.config -d§ -s1 -h$children[$i] -f%D:%H:%M:%S 2>&1`;
#print "before split is $str \n";
#if ($str =~ /\s*No\s*route\s*to\s*host/)
if ($str =~ /pmdumptext:\s*Error:\s*host\s*"\w*":/)
{
#print "host unreachable \n";
@inactive_children=$children[$i];
#print "inactive children is @inactive_children \n";
}
else
{
#print "into elso loop \n";
$str =~ s/\n//g;
#print "before split_1 is $str \n";
my @spl1=split(/§/,$str);
#print "splitted and #printing \n";
#print @spl1;
my $count_spl1=@spl1;
#print "the array has $count_spl1 elements \n";
#print "@spl1[0] \n";
#print "@spl1[1] \n";
#my $count3= `cat $::XCATROOT/lib/perl/xCAT_monitoring/pcp/pcpmon.config | wc -l`;
#print "the number of lines in the file is count3:$count3 \n";
#`tr "\n" "§" <$::XCATROOT/lib/perl/xCAT_monitoring/pcp/pcpmon.config> $::XCATROOT/lib/perl/xCAT_monitoring/pcp/pcpmon.config.tr`;
my $fname;
if (-e "/var/log/pcpmon.config")
{
#print "config under /var/log \n";
$fname="/var/log/pcpmon.config";
}
else
{
#print "config not under /var/log \n";
$fname = "$::XCATROOT/lib/perl/xCAT_monitoring/pcp/pcpmon.config";
}
print "config file is in $fname \n";
unless ( open( CONF, $fname ))
{
return(0);
}
my @raw_data = <CONF>;
close( CONF );
#print "before chopping @raw_data \n";
chop(@raw_data);
#print "raw data after chopping is @raw_data \n";
my $raw_data = join('§', @raw_data);
#print "the contents of the config file are $raw_data \n";
my @spl2=split(/§/,$raw_data);
#print "splitted and #printing \n";
#print @spl2;
my $count_spl2=@spl2;
#print "the array has $count_spl2 elements \n";
#print @spl2[0] ;
#print @spl2[1] ;
#print "updating table \n";
my $table1=xCAT::Table->new("performance", -create => 1,-autocommit => 1);
#print "table created \n";
my $j;
#my $k;
my $l=$j+1;
#print "l is $l \n";
my %setting_hash=();
for ($j=0;$j<$count_spl2 ;$j++)
{
#print "inside j loop \n";
#print "spl1[0] is $spl1[0] \n";
my %key_col1 = (timestamp=>$spl1[0]);
#print "time stamp updated \n";
#print "node is $children[$i] \n";
$key_col1{node}=$children[$i];
#print "children updatesd \n";
#print "spl2 is $spl2[$j] \n";
$key_col1{attrname} = $spl2[$j];
#$setting_hash{attrname}=$spl2[$j];
#print "spl1 is $spl1[$j+1] \n";
$setting_hash{attrvalue}=$spl1[$j+1];
$table1->setAttribs(\%key_col1, \%setting_hash);
}
$table1->close();
}
} #closing if count_child 2
my $noderef = xCAT_monitoring::monitorctrl->getMonHierarchy();
#identification of this node
my @hostinfo = xCAT::NetworkUtils->determinehostname();
#print "hosT:@hostinfo\n";
my $isSV = xCAT::Utils->isServiceNode();
#print "is sv is:$isSV \n";
my %iphash = ();
foreach (@hostinfo) { $iphash{$_} = 1; }
if (!$isSV) { $iphash{'noservicenode'} = 1; }
my @children;
my $str;
foreach my $key (keys(%$noderef))
{ #opening foreach1
#print "opening foreach1 \n";
#print "key is: $key \n";
my @key_a = split(':', $key);
if (!$iphash{ $key_a[0] }) { next; }
my $mon_nodes = $noderef->{$key};
foreach (@$mon_nodes)
{ #opening foreach2
my $node = $_->[0];
my $nodetype = $_->[1];
#print "node=$node, nodetype=$nodetype\n";
if (($nodetype) && ($nodetype =~ /$::NODETYPE_OSI/))
{
push(@children, $node);
}
} #closing foreach2
} #closing foreach1
#print "children:@children\n";
my $count_child = @children;
if ($count_child > 0)
{ #opening if count_child 1
#print "number of children is $count_child \n";
no strict;
no warnings;
#my $i=0;
my @inactive_children;
for ($i = 0 ; $i < $count_child ; $i++)
{ #opening if count_child 2
$str = `pmdumptext -c $::XCATROOT/lib/perl/xCAT_monitoring/pcp/pcpmon.config -d§ -s1 -h$children[$i] -f%D:%H:%M:%S 2>&1`;
#print "before split is $str \n";
#if ($str =~ /\s*No\s*route\s*to\s*host/)
if ($str =~ /pmdumptext:\s*Error:\s*host\s*"\w*":/)
{
#print "host unreachable \n";
@inactive_children = $children[$i];
#print "inactive children is @inactive_children \n";
}
else
{
#print "into elso loop \n";
$str =~ s/\n//g;
#print "before split_1 is $str \n";
my @spl1 = split(/§/, $str);
#print "splitted and #printing \n";
#print @spl1;
my $count_spl1 = @spl1;
#print "the array has $count_spl1 elements \n";
#print "@spl1[0] \n";
#print "@spl1[1] \n";
#my $count3= `cat $::XCATROOT/lib/perl/xCAT_monitoring/pcp/pcpmon.config | wc -l`;
#print "the number of lines in the file is count3:$count3 \n";
#`tr "\n" "§" <$::XCATROOT/lib/perl/xCAT_monitoring/pcp/pcpmon.config> $::XCATROOT/lib/perl/xCAT_monitoring/pcp/pcpmon.config.tr`;
my $fname;
if (-e "/var/log/pcpmon.config")
{
#print "config under /var/log \n";
$fname = "/var/log/pcpmon.config";
}
else
{
#print "config not under /var/log \n";
$fname = "$::XCATROOT/lib/perl/xCAT_monitoring/pcp/pcpmon.config";
}
print "config file is in $fname \n";
unless (open(CONF, $fname))
{
return (0);
}
my @raw_data = <CONF>;
close(CONF);
#print "before chopping @raw_data \n";
chop(@raw_data);
#print "raw data after chopping is @raw_data \n";
my $raw_data = join('§', @raw_data);
#print "the contents of the config file are $raw_data \n";
my @spl2 = split(/§/, $raw_data);
#print "splitted and #printing \n";
#print @spl2;
my $count_spl2 = @spl2;
#print "the array has $count_spl2 elements \n";
#print @spl2[0] ;
#print @spl2[1] ;
#print "updating table \n";
my $table1 = xCAT::Table->new("performance", -create => 1, -autocommit => 1);
#print "table created \n";
my $j;
#my $k;
my $l = $j + 1;
#print "l is $l \n";
my %setting_hash = ();
for ($j = 0 ; $j < $count_spl2 ; $j++)
{
#print "inside j loop \n";
#print "spl1[0] is $spl1[0] \n";
my %key_col1 = (timestamp => $spl1[0]);
#print "time stamp updated \n";
#print "node is $children[$i] \n";
$key_col1{node} = $children[$i];
#print "children updatesd \n";
#print "spl2 is $spl2[$j] \n";
$key_col1{attrname} = $spl2[$j];
#$setting_hash{attrname}=$spl2[$j];
#print "spl1 is $spl1[$j+1] \n";
$setting_hash{attrvalue} = $spl1[ $j + 1 ];
$table1->setAttribs(\%key_col1, \%setting_hash);
}
$table1->close();
}
} #closing if count_child 2
my $table2=xCAT::Table->new("monitoring", -create =>1);
if (!$table2)
{
my $rsp={};
$rsp->{data}->[0]="Cannot open the monitoring table.\n";
$callback->($rsp);
return 1;
}
my $table2 = xCAT::Table->new("monitoring", -create => 1);
if (!$table2)
{
my $rsp = {};
$rsp->{data}->[0] = "Cannot open the monitoring table.\n";
$callback->($rsp);
return 1;
}
my $ref = $table2->getAttribs({'name' => 'pcpmon'}, 'nodestatmon');
#print "array is $ref \n";
my $node_stat=$ref->{nodestatmon};
#print "nodestatmon is $node_stat \n";
if ($node_stat ='Y')
{ #opening ifnodestatusmon
#print "inside nodestatus mon $node_stat \n";
my %node_status=();
#print "2nd set is @inactive_children \n";
my $count_inactive=@inactive_children;
if ($count_inactive>0)
{
#print "more than 0 inactive children \n";
#print "3rd set is @inactive_children \n";
$node_status{$::STATUS_INACTIVE}=\@inactive_children;
my $changed1=$nodes_status{$::STATUS_INACTIVE};
#print "the changed1 is $changed1 \n";
my @final_inactive=@$changed1;
#print "final inactive is @final_inactive \n";
}
my $ref = $table2->getAttribs({ 'name' => 'pcpmon' }, 'nodestatmon');
#print "array is $ref \n";
my $node_stat = $ref->{nodestatmon};
#print "nodestatmon is $node_stat \n";
if ($node_stat = 'Y')
{ #opening ifnodestatusmon
#print "inside nodestatus mon $node_stat \n";
my %node_status = ();
#print "2nd set is @inactive_children \n";
my $count_inactive = @inactive_children;
if ($count_inactive > 0)
{
#print "more than 0 inactive children \n";
#print "3rd set is @inactive_children \n";
$node_status{$::STATUS_INACTIVE} = \@inactive_children;
my $changed1 = $nodes_status{$::STATUS_INACTIVE};
#print "the changed1 is $changed1 \n";
my @final_inactive = @$changed1;
#print "final inactive is @final_inactive \n";
}
#only set the node status for the changed ones
if (keys(%node_status) > 0)
{
#print %node_status, "\n";
#print "updating nodelist table \n";
xCAT_monitoring::xcatmon::setNodeStatusAttributes(\%node_status);
}
#only set the node status for the changed ones
if (keys(%node_status) > 0)
{
#print %node_status, "\n";
#print "updating nodelist table \n";
xCAT_monitoring::xcatmon::setNodeStatusAttributes(\%node_status);
}
} #closing if nodestatusmon
} #closing if count_child 1
} # closing subroutine
} #closing if nodestatusmon
} #closing if count_child 1
} # closing subroutine

View File

@ -7,7 +7,7 @@ use IO::Socket::INET;
use IO::Select;
use Getopt::Long;
my $quit = 0;
my $quit = 0;
my $doreload = 0;
my %nodecfg;
my $bootpmagic = pack("C*", 0x63, 0x82, 0x53, 0x63);
@ -33,14 +33,14 @@ if ($tobedaemon) {
daemonize();
}
# open syslog
# open syslog
openlog("xcat", "nofatal", "local4");
my $socket;
my $retry = 5;
while ($retry > 0) {
while ($retry > 0) {
$socket = IO::Socket::INET->new(LocalPort => 4011,
Proto => 'udp',
Proto => 'udp',
Domain => AF_INET);
if ($socket) {
last;
@ -50,18 +50,18 @@ while ($retry > 0) {
$retry--;
}
unless ($socket) {
syslog ("info", "Unable to open socket on port 4011.");
closelog();
syslog("info", "Unable to open socket on port 4011.");
closelog();
exit;
}
# regist my pid to /var/run/xcat/proxydhcp.pid
if (open (PIDF, ">/var/run/xcat/proxydhcp-xcat.pid")) {
if (open(PIDF, ">/var/run/xcat/proxydhcp-xcat.pid")) {
print PIDF $$;
close(PIDF);
} else {
syslog ("info", "Cannot open /var/run/xcat/proxydhcp.pid.");
closelog();
syslog("info", "Cannot open /var/run/xcat/proxydhcp.pid.");
closelog();
exit;
}
@ -69,32 +69,32 @@ if (open (PIDF, ">/var/run/xcat/proxydhcp-xcat.pid")) {
my $select = new IO::Select;
$select->add($socket);
load_cfg();
until ($quit) {
until ($select->can_read(5)) { #Wait for data
until ($quit) {
until ($select->can_read(5)) { #Wait for data
if ($doreload) {
load_cfg();
syslog ("info", "Reload configuration file in select.");
syslog("info", "Reload configuration file in select.");
}
if ($quit) { last; };
yield;
if ($quit) { last; }
yield;
}
if ($doreload) {
load_cfg();
syslog ("info", "Reload configuration file before recv.");
syslog("info", "Reload configuration file before recv.");
}
my $data;
my $caddr = $socket->recv($data,1500);
my $caddr = $socket->recv($data, 1500);
my ($cport, $cnip) = sockaddr_in($caddr);
my $snip = my_ip_facing($cnip);
unless ($snip) {
syslog ("info", "Cannot find the server ip of proxydhcp daemon");
syslog("info", "Cannot find the server ip of proxydhcp daemon");
next;
}
if (length ($data) < 320) {
if (length($data) < 320) {
next;
}
@ -103,51 +103,52 @@ until ($quit) {
if (pack("C*", $package[0xec], $package[0xed], $package[0xee], $package[0xef]) != $bootpmagic) {
next;
}
}
# get the node name of client
my $nodename = gethostbyaddr($cnip, AF_INET);
# get the winpepath
my $winpepath = "";
if ($nodename) {
if (defined $nodecfg{$nodename}) {
$winpepath = $nodecfg{$nodename};
if ($verbose) {syslog ("info", "Find configure for $nodename= $nodecfg{$nodename} in configuration file")};
if ($verbose) { syslog("info", "Find configure for $nodename= $nodecfg{$nodename} in configuration file") }
} else {
$nodename =~ s/\..*//;
if (defined $nodecfg{$nodename}) {
$winpepath = $nodecfg{$nodename};
if ($verbose) {syslog ("info", "Find configure for $nodename= $nodecfg{$nodename} in configuration file")};
if ($verbose) { syslog("info", "Find configure for $nodename= $nodecfg{$nodename} in configuration file") }
}
}
}
# get the Vendor class identifier
my $strp = 0xf0;
my $strp = 0xf0;
my $archp = 0;
while ($strp < $#package) {
if ($package[$strp] eq 60) {
$archp = $strp + 0x11;
last;
} else {
$strp += $package[$strp+1] + 2;
$strp += $package[ $strp + 1 ] + 2;
}
}
# get the winpe boot loader path
my $winboot = $winpepath."Boot/pxeboot.0";
# get the winpe boot loader path
my $winboot = $winpepath . "Boot/pxeboot.0";
if ($archp) {
my $clienttype = substr($data, $archp, 5);
if ($clienttype eq "00000") {
#if ("$package[$archp]$package[$archp+1]$package[$archp+2]$package[$archp+3]$package[$archp+4]" == "00000") {
$winboot = $winpepath."Boot/pxeboot.0";
#if ("$package[$archp]$package[$archp+1]$package[$archp+2]$package[$archp+3]$package[$archp+4]" == "00000") {
$winboot = $winpepath . "Boot/pxeboot.0";
} elsif ($clienttype eq "00007") {
$winboot = $winpepath."Boot/bootmgfw.efi";
$winboot = $winpepath . "Boot/bootmgfw.efi";
}
}
syslog ("info", "The boot loader path for node $nodename is $winboot");
syslog("info", "The boot loader path for node $nodename is $winboot");
# set message type
$replypkg[0] = 2;
@ -162,7 +163,7 @@ until ($quit) {
$replypkg[3] = $package[3];
# set the transaction ID
@replypkg = (@replypkg, @package[4 .. 7]);
@replypkg = (@replypkg, @package[ 4 .. 7 ]);
# set elapsed time
$replypkg[8] = 0;
@ -173,7 +174,7 @@ until ($quit) {
$replypkg[0xb] = 0;
# set client ip
@replypkg = (@replypkg, @package[0xc .. 0xf]);
@replypkg = (@replypkg, @package[ 0xc .. 0xf ]);
# set Your (client IP)
@replypkg = (@replypkg, 0, 0, 0, 0);
@ -185,7 +186,7 @@ until ($quit) {
@replypkg = (@replypkg, 0, 0, 0, 0);
# set client hardware address
@replypkg = (@replypkg, @package[0x1c .. 0x2b]);
@replypkg = (@replypkg, @package[ 0x1c .. 0x2b ]);
# set server host name
foreach (0x2c .. 0x6b) {
@ -194,7 +195,7 @@ until ($quit) {
# set the boot file name
@replypkg = (@replypkg, unpack("C*", $winboot));
my $lenth = length ($winboot);
my $lenth = length($winboot);
foreach (0x6c + $lenth .. 0xeb) {
$replypkg[$_] = 0;
}
@ -205,50 +206,50 @@ until ($quit) {
@replypkg = (@replypkg, unpack("C*", $bootpmagic));
# set dhcp msg type
$replypkg[0xf0] = 0x35; # option number
$replypkg[0xf1] = 0x1; # msg length
$replypkg[0xf2] = 0x5; # dhcp ack
$replypkg[0xf0] = 0x35; # option number
$replypkg[0xf1] = 0x1; # msg length
$replypkg[0xf2] = 0x5; # dhcp ack
# set dhcp server identifer
$replypkg[0xf3] = 0x36; # option number
$replypkg[0xf4] = 0x4; # msg length
$replypkg[0xf3] = 0x36; # option number
$replypkg[0xf4] = 0x4; # msg length
@replypkg = (@replypkg, unpack("C*", $snip));
# set the bcd path
my $winbcd = $winpepath."Boot/BCD";
$replypkg[0xf9] = 0xfc; # option number
$replypkg[0xfa] = length($winbcd) + 1; # msg length
my $winbcd = $winpepath . "Boot/BCD";
$replypkg[0xf9] = 0xfc; # option number
$replypkg[0xfa] = length($winbcd) + 1; # msg length
@replypkg = (@replypkg, unpack("C*", $winbcd));
$replypkg[0xfa + length($winbcd) + 1] = 0;
$replypkg[0xfa + length($winbcd) + 2] = 0xff;
$replypkg[ 0xfa + length($winbcd) + 1 ] = 0;
$replypkg[ 0xfa + length($winbcd) + 2 ] = 0xff;
$socket->send(pack("C*", @replypkg), 0, $caddr);
syslog ("info", "The BCD path for node $nodename is $winbcd");
syslog("info", "The BCD path for node $nodename is $winbcd");
# debug package detail
if (0) {
my $msg;
my $firstline = 1;
my $num = 0;
foreach (@replypkg) {
my $v = sprintf("%2x ", $_);
$msg .= $v;
if (($num - 5)%8 eq 0) {
$msg .= " ";
my $msg;
my $firstline = 1;
my $num = 0;
foreach (@replypkg) {
my $v = sprintf("%2x ", $_);
$msg .= $v;
if (($num - 5) % 8 eq 0) {
$msg .= " ";
}
if (($num - 5) % 16 eq 0) {
syslog("info", $msg);
print $msg. "\n";
$msg = "";
}
$num++;
}
if (($num - 5)%16 eq 0) {
syslog ("info", $msg);
print $msg."\n";
$msg = "";
}
$num++;
print $msg. "\n";
}
print $msg."\n";
}
}
closelog();
closelog();
# daemonize the service
sub daemonize
@ -262,7 +263,7 @@ sub daemonize
}
open STDOUT, '>/dev/null';
open STDERR, '>/dev/null';
$0='proxydhcp-xcat';
$0 = 'proxydhcp-xcat';
$progname = \$0;
}
@ -270,12 +271,12 @@ sub daemonize
sub load_cfg
{
$doreload = 0;
if (! -r "/var/lib/xcat/proxydhcp.cfg") {
if (!-r "/var/lib/xcat/proxydhcp.cfg") {
return;
}
if (! open (CFG, "</var/lib/xcat/proxydhcp.cfg")) {
syslog ("info", "Cannot open /var/lib/xcat/proxydhcp.cfg");
if (!open(CFG, "</var/lib/xcat/proxydhcp.cfg")) {
syslog("info", "Cannot open /var/lib/xcat/proxydhcp.cfg");
return;
}
@ -286,10 +287,10 @@ sub load_cfg
my $p = 0;
while (1) {
my $name = substr($mycfg, $p, 50);
my $name = substr($mycfg, $p, 50);
$p += 50;
my $value = substr($mycfg, $p, 150);
my $value = substr($mycfg, $p, 150);
$p += 150;
$name =~ s/\0//g;

View File

@ -3,6 +3,7 @@
#(C)IBM Corp
#-----------------------------------------------------------------------------
=head1 restartxcatd
restartxcatd - this routine is used to restart the xcatd process group.
@ -28,14 +29,15 @@
then runs 'startsrc -s xcatd' to start xcatd.
=cut
#-----------------------------------------------------------------------------
BEGIN
{
$::XCATROOT =
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
}
use lib "$::XCATROOT/lib/perl";
use Getopt::Long;
@ -44,26 +46,28 @@ use xCAT::MsgUtils;
use xCAT::Utils;
my $cmd = basename($0);
# for auditing
my $current_userid = getpwuid($>);
my $rsp = {};
my $host=`hostname`;
$host=~ s/\s*//g; # remove blanks
my $rsp = {};
my $host = `hostname`;
$host =~ s/\s*//g; # remove blanks
# check the arguments
&parse_args($cmd);
$rsp->{syslogdata}->[0] ="restartxcatd invoked by $current_userid.\n";
$rsp->{userid} ->[0] = $current_userid;
$rsp->{clientname} -> [0] = $host;
$rsp->{clienttype} -> [0]= "cli";
$rsp->{command} -> [0] = $cmd;
$rsp->{status} -> [0] = "allowed";
xCAT::MsgUtils->message("SA",$rsp); # syslog and auditlog
$rsp->{syslogdata}->[0] = "restartxcatd invoked by $current_userid.\n";
$rsp->{userid}->[0] = $current_userid;
$rsp->{clientname}->[0] = $host;
$rsp->{clienttype}->[0] = "cli";
$rsp->{command}->[0] = $cmd;
$rsp->{status}->[0] = "allowed";
xCAT::MsgUtils->message("SA", $rsp); # syslog and auditlog
# for Linux specific
if (xCAT::Utils->isLinux())
{
{
print "Restarting xCATd ";
if (-r "/etc/profile.d/xcat.sh") {
$cmd = "source /etc/profile.d/xcat.sh;";
@ -73,11 +77,11 @@ if (xCAT::Utils->isLinux())
xCAT::Utils->runcmd("$cmd", -1);
if ($::RUNCMD_RC == 0) {
print "[ OK ]\n";
system ("logger -p local4.info -t xcat Restart xcatd: [ OK ].");
system("logger -p local4.info -t xcat Restart xcatd: [ OK ].");
exit 0;
} else {
print "[ FAILED ]\n";
system ("logger -p local4.info -t xcat Restart xcatd: [ FAILED ].");
system("logger -p local4.info -t xcat Restart xcatd: [ FAILED ].");
exit 1;
}
} elsif (!(xCAT::Utils->isAIX())) {
@ -87,7 +91,7 @@ if (xCAT::Utils->isLinux())
# Following code is for AIX only
$::RE_CHECK_NUM = 10; # the times to check the result of command, the checking interval is 1 second
$::RE_CHECK_NUM = 10; # the times to check the result of command, the checking interval is 1 second
my $rc;
my @output;
@ -95,9 +99,10 @@ my $inoperative = 0;
my $check_num;
# Check whether the xcatd subsystem has been created
$cmd = "/usr/bin/lssrc -s xcatd | grep \"xcatd Subsystem is not on file\"";
$cmd = "/usr/bin/lssrc -s xcatd | grep \"xcatd Subsystem is not on file\"";
@output = `$cmd`;
if (scalar(@output)) {
# create the subsystem if it does not exist
$cmd = "mkssys -p $::XCATROOT/sbin/xcatd -s xcatd -u 0 -S -n 15 -f 15 -a \"-f\"";
$rc = system($cmd);
@ -108,7 +113,7 @@ if (scalar(@output)) {
}
# Check the current status of xcatd subsystem
$cmd = "lssrc -s xcatd | grep 'xcatd' | grep 'inoperative'";
$cmd = "lssrc -s xcatd | grep 'xcatd' | grep 'inoperative'";
@output = `$cmd`;
if (scalar(@output)) {
if ($::VERBOSE) {
@ -117,10 +122,10 @@ if (scalar(@output)) {
$inoperative = 1;
}
if (! $inoperative) { # active
# Stop the xcatd subsystem
if (!$inoperative) { # active
# Stop the xcatd subsystem
$cmd = "/usr/bin/stopsrc -s xcatd";
$rc = system($cmd);
$rc = system($cmd);
if ($rc >> 8) {
xCAT::MsgUtils->message("E", "Error: Cannot run stopsrc command correctly.\n");
exit 1;
@ -129,7 +134,7 @@ if (! $inoperative) { # active
# Wait for end of the xcatd subsystem
$check_num = $::RE_CHECK_NUM;
while ($check_num > 0) {
$cmd = "lssrc -s xcatd | grep 'xcatd' | grep 'inoperative'";
$cmd = "lssrc -s xcatd | grep 'xcatd' | grep 'inoperative'";
@output = `$cmd`;
if (scalar(@output) == 0) {
sleep 1;
@ -150,10 +155,10 @@ if (! $inoperative) { # active
}
# Kill xcatd manually if needed
$cmd = "ps -ef | grep xcatd: | grep -v grep";
$cmd = "ps -ef | grep xcatd: | grep -v grep";
@output = `$cmd`;
if (scalar(@output)) {
$cmd = "ps -ef | grep xcatd | grep 'SSL listener'";
$cmd = "ps -ef | grep xcatd | grep 'SSL listener'";
@output = `$cmd`;
foreach my $ps (@output) {
$ps =~ s/^\s+//; # strip any leading spaces
@ -161,8 +166,9 @@ if (scalar(@output)) {
my $cmd = "/usr/bin/kill -15 -$pid >/dev/null 2>&1";
`$cmd`;
}
# Kill the xcatd by force if it still there
$cmd = "ps -ef | grep xcatd: | grep -v grep";
$cmd = "ps -ef | grep xcatd: | grep -v grep";
@output = `$cmd`;
foreach my $ps (@output) {
$ps =~ s/^\s+//; # strip any leading spaces
@ -172,7 +178,7 @@ if (scalar(@output)) {
}
$check_num = $::RE_CHECK_NUM;
while ($check_num > 0) {
$cmd = "ps -ef | grep xcatd: | grep -v grep";
$cmd = "ps -ef | grep xcatd: | grep -v grep";
@output = `$cmd`;
if (scalar(@output)) {
sleep 1;
@ -208,6 +214,7 @@ if ($rc >> 8) {
xCAT::MsgUtils->message("E", "Error: Cannot run startsrc command correctly.\n");
exit 1;
}
# Sleep a while to make sure the startsrc has completed it's work
sleep 3;
@ -232,15 +239,15 @@ if ($check_num <= 0) {
# now see if we can really talk to the database, up to a minute
$wait = 60;
while ($wait > 0) {
sleep 10;
$wait = $wait -10;
xCAT::Utils->runcmd("$::XCATROOT/sbin/tabdump site",-1);
if ($::RUNCMD_RC == 0) {
$wait=0;
}
sleep 10;
$wait = $wait - 10;
xCAT::Utils->runcmd("$::XCATROOT/sbin/tabdump site", -1);
if ($::RUNCMD_RC == 0) {
$wait = 0;
}
}
if ($::VERBOSE) {
xCAT::MsgUtils->message("I", "Started the xcatd subsystem.\n");
xCAT::MsgUtils->message("I", "Started the xcatd subsystem.\n");
}
exit 0;
@ -282,12 +289,12 @@ sub parse_args
}
if ($::RELOAD)
{
$ENV{XCATRELOAD} = "yes";
$ENV{XCATRELOAD} = "yes";
}
if ($::VERSION)
{
my $version = xCAT::Utils->Version();
$version .="\n";
$version .= "\n";
xCAT::MsgUtils->message("I", $version);
exit 0;
}

View File

@ -20,24 +20,24 @@ my $help;
my $verbose;
if (!GetOptions(
'l|loginname=s' => \$username,
'p|password=s' => \$passwd,
't|telnet' => \$telnet, #use telnet, otherwise ssh
'h|help' => \$help,
'v|verbose'=> \$verbose,
) || $help || scalar(@ARGV)<2 ) {
print "Usage: rshell_api [-v] [-t] [-l <user>] [-p <passwrd>] <node> <command>\n";
exit;
'l|loginname=s' => \$username,
'p|password=s' => \$passwd,
't|telnet' => \$telnet, #use telnet, otherwise ssh
'h|help' => \$help,
'v|verbose' => \$verbose,
) || $help || scalar(@ARGV) < 2) {
print "Usage: rshell_api [-v] [-t] [-l <user>] [-p <passwrd>] <node> <command>\n";
exit;
}
my $node = $ARGV[0];
my $output =xCAT::RShellAPI::run_remote_shell_api($node, $username, $passwd, $telnet, $verbose, @ARGV[1 .. $#ARGV]);
my $rc=0;
my $output = xCAT::RShellAPI::run_remote_shell_api($node, $username, $passwd, $telnet, $verbose, @ARGV[ 1 .. $#ARGV ]);
my $rc = 0;
my $data;
if ($output && (@$output > 1)) {
$rc=$output->[0];
$data=$output->[1];
$rc = $output->[0];
$data = $output->[1];
}
print "$data";

View File

@ -37,25 +37,26 @@ use strict;
$::progname = "runsqlcmd";
Getopt::Long::Configure("bundling");
$Getopt::Long::ignorecase = 0;
my ($directory, $help, $version,$verbose, $filelist);
my ($directory, $help, $version, $verbose, $filelist);
# parse the options
if (
!GetOptions(
'd|dir=s' => \$directory,
'f|files=s' => \$filelist,
'h|help' => \$help,
'v|version' => \$version,
'V|verbose' => \$verbose,
'd|dir=s' => \$directory,
'f|files=s' => \$filelist,
'h|help' => \$help,
'v|version' => \$version,
'V|verbose' => \$verbose,
)
)
{
&usage;
exit(1);
}
# see if they entered a command
my $args = join ' ', @ARGV;
my $command = $args;
my $command = $args;
# display the usage if -h or --help is specified
if ($help)
@ -63,6 +64,7 @@ if ($help)
&usage;
exit(0);
}
# display the version statement if -v or --version is specified
if ($version)
{
@ -72,39 +74,40 @@ if ($version)
}
if (($filelist) && ($directory))
{
xCAT::MsgUtils->message("E","Cannot enter both the -f and -d flags.");
xCAT::MsgUtils->message("E", "Cannot enter both the -f and -d flags.");
exit 1;
}
if (($command) && (($directory) || ($filelist)))
{
xCAT::MsgUtils->message("E","Cannot enter both a command and the -d or -f flag.");
xCAT::MsgUtils->message("E", "Cannot enter both a command and the -d or -f flag.");
exit 1;
}
my $tempfile;
if ($command) { # command on command line
$tempfile="/tmp/runcmdfile.$$";
my $cmd = "echo \"$command\" > $tempfile";
xCAT::Utils->runcmd($cmd,0);
if ($::RUNCMD_RC != 0)
{ # error
xCAT::MsgUtils->message("E", "$cmd failed");
exit 1;
if ($command) { # command on command line
$tempfile = "/tmp/runcmdfile.$$";
my $cmd = "echo \"$command\" > $tempfile";
xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{ # error
xCAT::MsgUtils->message("E", "$cmd failed");
exit 1;
}
# put on filelist
$filelist=$tempfile;
} else { # commands in a file
}
if (!($filelist)) { # if no file list and no directory set default
if (!($directory)) {
$directory = "$::XCATROOT/lib/perl/xCAT_schema";
}
}
# put on filelist
$filelist = $tempfile;
} else { # commands in a file
if (!($filelist)) { # if no file list and no directory set default
if (!($directory)) {
$directory = "$::XCATROOT/lib/perl/xCAT_schema";
}
}
}
my @filearray;
if ($filelist)
{ # use filelist
{ # use filelist
$directory = ""; #Get rid of the default
@filearray = &process_file_list($filelist);
}
@ -114,55 +117,56 @@ else
if (!(-e $directory))
{
xCAT::MsgUtils->message("E",
"The $directory directory does not exist.");
"The $directory directory does not exist.");
exit 1;
}
}
my @sqlfilelist = xCAT::Table->get_filelist($directory, \@filearray, "sql");
if (@sqlfilelist) { # if anything to do
#determine database
my $xcatcfg = xCAT::Table->get_xcatcfg();
foreach my $file (@sqlfilelist)
{
if ($xcatcfg =~ /^DB2:/)
if (@sqlfilelist) { # if anything to do
#determine database
my $xcatcfg = xCAT::Table->get_xcatcfg();
foreach my $file (@sqlfilelist)
{
&rundb2cmd($file);
}
if ($xcatcfg =~ /^mysql:/)
{
&runmysqlcmd($file, $xcatcfg);
}
if ($xcatcfg =~ /^Pg:/)
{
&runpgsqlcmd($file, $xcatcfg);
}
if ($xcatcfg =~ /^SQLite:/)
{
# not supported but will leave routine in case we change our mind
if ($verbose) {
xCAT::MsgUtils->message("SE", "The runsqlcmd does not support the SQLite database.");
if ($xcatcfg =~ /^DB2:/)
{
&rundb2cmd($file);
}
#&runsqlitecmd($file,$xcatcfg);
exit 1;
}
if ($xcatcfg =~ /^mysql:/)
{
&runmysqlcmd($file, $xcatcfg);
}
if ($xcatcfg =~ /^Pg:/)
{
&runpgsqlcmd($file, $xcatcfg);
}
if ($xcatcfg =~ /^SQLite:/)
{
# not supported but will leave routine in case we change our mind
if ($verbose) {
xCAT::MsgUtils->message("SE", "The runsqlcmd does not support the SQLite database.");
}
}
#&runsqlitecmd($file,$xcatcfg);
exit 1;
}
}
} else {
if ($verbose) {
if ($verbose) {
xCAT::MsgUtils->message("SI", "The runsqlcmd has no files to process in $directory .");
}
}
}
if ($tempfile) {
my $cmd = "rm $tempfile";
xCAT::Utils->runcmd($cmd,0);
if ($::RUNCMD_RC != 0)
{ # error
xCAT::MsgUtils->message("E", "$cmd failed");
exit 1;
my $cmd = "rm $tempfile";
xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{ # error
xCAT::MsgUtils->message("E", "$cmd failed");
exit 1;
}
}
}
}
exit 0;
#####################################
@ -183,10 +187,10 @@ sub usage
{
xCAT::MsgUtils->message(
'I',
"Usage:\nRuns the sql commands in files located in /opt/xcat/lib/perl/xCAT_schema by default, or the directory input with -d, or the list of files input with the -f flag, or the command input on the command line. Supports DB2,PostgreSQL,MySQL."
);
"Usage:\nRuns the sql commands in files located in /opt/xcat/lib/perl/xCAT_schema by default, or the directory input with -d, or the list of files input with the -f flag, or the command input on the command line. Supports DB2,PostgreSQL,MySQL."
);
my $msg =
"runsqlcmd <-h|--help>\n <-v|--version>\n <-V|--verbose>\n <-d|--dir>\n <-f|--files> \n <sql command>";
"runsqlcmd <-h|--help>\n <-v|--version>\n <-V|--verbose>\n <-d|--dir>\n <-f|--files> \n <sql command>";
xCAT::MsgUtils->message('I', "$msg");
}
@ -205,9 +209,9 @@ sub usage
sub rundb2cmd
{
use File::Basename;
my $file = shift;
my $rc = 0;
if (!(-e $file)) { # file does not exist
my $file = shift;
my $rc = 0;
if (!(-e $file)) { # file does not exist
xCAT::MsgUtils->message("SE",
"The file:$file does not exist. ");
return;
@ -245,7 +249,7 @@ sub rundb2cmd
{
$rc = $? >> 8;
xCAT::MsgUtils->message("SE",
"The command $cmd had errors. Return=$rc");
"The command $cmd had errors. Return=$rc");
}
$cmd = "rm $tmpfile";
@output = xCAT::Utils->runcmd($cmd, 0);
@ -276,32 +280,35 @@ sub runmysqlcmd
my ($prefix, $dbname) = split('=', $front);
my ($host, $admin, $passwd) = split('\|', $back);
my ($hostind, $hostname) = split('=', $host);
my $rc = 0;
if (!(-e $file)) { # file does not exist
my $rc = 0;
if (!(-e $file)) { # file does not exist
xCAT::MsgUtils->message("SE",
"The file:$file does not exist. ");
return;
}
# set correct path to the mysql cmd
my $mysql;
if (xCAT::Utils->isAIX()) {
$mysql="/usr/local/mysql/bin/mysql";
$mysql = "/usr/local/mysql/bin/mysql";
} else {
$mysql="/usr/bin/mysql";
$mysql = "/usr/bin/mysql";
}
my $cmd =
"$mysql --user=$admin --password=$passwd --host=$hostname $dbname \< $file ";
"$mysql --user=$admin --password=$passwd --host=$hostname $dbname \< $file ";
#xCAT::MsgUtils->message("SI", "Running mysql --user=$admin --host=$hostname $dbname $file ");
system("$cmd");
if ($? > 0) # error
{
$rc = $? >> 8;
# secure password
$cmd = "$mysql --user=$admin --password=xxxxxx --host=$hostname $dbname \< $file ";
xCAT::MsgUtils->message("SE",
"The command $cmd had errors. Return=$rc");
"The command $cmd had errors. Return=$rc");
}
return;
}
@ -326,21 +333,23 @@ sub runpgsqlcmd
my ($host, $admin, $passwd) = split('\|', $back);
my ($hostind, $hostname) = split('=', $host);
my $rc = 0;
if (!(-e $file)) { # file does not exist
my $rc = 0;
if (!(-e $file)) { # file does not exist
xCAT::MsgUtils->message("SE",
"The file:$file does not exist. ");
return;
}
# set correct path to the psql cmd
my $psql;
if (xCAT::Utils->isAIX()) {
$psql="/var/lib/pgsql/bin/psql";
$psql = "/var/lib/pgsql/bin/psql";
} else {
$psql="/usr/bin/psql";
$psql = "/usr/bin/psql";
}
my $cmd =
"PGPASSWORD=$passwd $psql -d $dbname -h $hostname -U $admin -f $file ";
#xCAT::MsgUtils->message("SI", "Running psql -d $dbname -h $hostname -U $admin -f $file ");
system("$cmd");
@ -348,7 +357,7 @@ sub runpgsqlcmd
{
$rc = $? >> 8;
xCAT::MsgUtils->message("SE",
"The command $cmd had errors. Return=$rc");
"The command $cmd had errors. Return=$rc");
}
return;
}

View File

@ -7,9 +7,9 @@
BEGIN
{
$::XCATROOT =
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
}
use lib "$::XCATROOT/lib/perl";
use Getopt::Long;
@ -71,35 +71,35 @@ sub parse_args
)
)
{
{
if ($cmd eq "xcatstart") {
$usagemsg = "$cmd [-h|-v|-r]\n";
xCAT::MsgUtils->message("E", $usagemsg);
} else { #xcatstop
$usagemsg = "$cmd [-h|-v]\n";
xCAT::MsgUtils->message("E", $usagemsg);
}
$usagemsg = "$cmd [-h|-v|-r]\n";
xCAT::MsgUtils->message("E", $usagemsg);
} else { #xcatstop
$usagemsg = "$cmd [-h|-v]\n";
xCAT::MsgUtils->message("E", $usagemsg);
}
exit 1;
}
if ($::HELP)
{
if ($cmd eq "xcatstart") {
$usagemsg = "$cmd [-h|-v|-r]\n";
xCAT::MsgUtils->message("I", $usagemsg);
} else { #xcatstop
$usagemsg = "$cmd [-h|-v]\n";
xCAT::MsgUtils->message("I", $usagemsg);
}
$usagemsg = "$cmd [-h|-v|-r]\n";
xCAT::MsgUtils->message("I", $usagemsg);
} else { #xcatstop
$usagemsg = "$cmd [-h|-v]\n";
xCAT::MsgUtils->message("I", $usagemsg);
}
exit 0;
}
if ($::RELOAD)
{
$ENV{XCATRELOAD} = "yes";
$ENV{XCATRELOAD} = "yes";
}
if ($::VERSION)
{
my $version = xCAT::Utils->Version();
$version .="\n";
$version .= "\n";
xCAT::MsgUtils->message("I", $version);
exit 0;
}

View File

@ -7,9 +7,9 @@
BEGIN
{
$::XCATROOT =
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
}
use lib "$::XCATROOT/lib/perl";
use File::Basename;
@ -77,7 +77,7 @@ else
# if not make them
if ($thostname eq "local")
{ # local host
{ # local host
$cmd = "ls $path/etc/xcat/ca";
}
else
@ -88,7 +88,7 @@ my @output = xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0)
{
if ($thostname eq "local")
{ # local host
{ # local host
$cmd = "mkdir $path/etc/xcat/ca";
}
else
@ -343,7 +343,7 @@ sub create_fstab
{
my ($path) = @_;
my $cmd;
my $file = "$path/etc/fstab";
my $file = "$path/etc/fstab";
my $file2 = "$path/etc/fstab.ORIG";
if (!(-e $file2))
{ # if not already done

View File

@ -2,7 +2,7 @@
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use Sys::Syslog;
@ -14,20 +14,23 @@ use xCAT_plugin::ipmi;
use xCAT_monitoring::monitorctrl;
use Socket;
use Data::Dumper;
#use strict;
#-------------------------------------------------------------------------------
=head1 xcat_traphandler
=head2 Description
Script for SNMP trap handling.
=cut
#-------------------------------------------------------------------------------
# admin needs to create a mail aliase called alerts
# put "alerts: emailadd,emailaddr.." to /etc/aliases file
# then run newaliases command
my $MAILTO="alerts";
my $MAILTO = "alerts";
my $message;
my $briefmsg;
@ -41,316 +44,326 @@ my $message1;
my $errsrc;
#get settings
my $EMAIL=0;
my $LOG=0;
my $IGNORE=0;
my $DB=0;
my %hashI=();
my %hashE=();
my %hashL=();
my %hashR=();
my %hashD=();
my %hashRUN=();
my %settings=xCAT_monitoring::monitorctrl->getPluginSettings("snmpmon");
my $i=$settings{'ignore'};
if ($i) { %hashI =parseSettings($i); }
my $e=$settings{'email'};
if ($e) { %hashE=parseSettings($e); }
my $l=$settings{'log'};
if ($l) { %hashL=parseSettings($l); }
my $d=$settings{'db'};
if ($d) { %hashD=parseSettings($d); }
my $EMAIL = 0;
my $LOG = 0;
my $IGNORE = 0;
my $DB = 0;
my %hashI = ();
my %hashE = ();
my %hashL = ();
my %hashR = ();
my %hashD = ();
my %hashRUN = ();
my %settings = xCAT_monitoring::monitorctrl->getPluginSettings("snmpmon");
my $i = $settings{'ignore'};
if ($i) { %hashI = parseSettings($i); }
my $e = $settings{'email'};
if ($e) { %hashE = parseSettings($e); }
my $l = $settings{'log'};
if ($l) { %hashL = parseSettings($l); }
my $d = $settings{'db'};
if ($d) { %hashD = parseSettings($d); }
foreach my $k (keys %settings) {
if ($k =~ /runcmd(\d*)/) {
my $r=$settings{$k};
my %hashTemp=parseSettings($r);
$hashR{$k}=\%hashTemp;
$hashRUN{$k}=0;
if ($k =~ /runcmd(\d*)/) {
my $r = $settings{$k};
my %hashTemp = parseSettings($r);
$hashR{$k} = \%hashTemp;
$hashRUN{$k} = 0;
}
}
# read host name
my $host=<STDIN>;
my $host = <STDIN>;
chomp($host);
# read the host ip
my $ip=<STDIN>;
my $ip = <STDIN>;
chomp($ip);
# read uptime
my $uptimeline=<STDIN>;
my $uptimeline = <STDIN>;
chomp($uptimeline);
my @a=split(/ /, $uptimeline);
my $oid=shift @a;
my $value=join(' ', @a);
my @a = split(/ /, $uptimeline);
my $oid = shift @a;
my $value = join(' ', @a);
$message .= " $oid=$value\n";
# read trapid
my $trapidline=<STDIN>;
# read trapid
my $trapidline = <STDIN>;
chomp($trapidline);
@a=split(/ /, $trapidline);
$oid=shift @a;
$value=join(' ', @a);
@a = split(/ /, $trapidline);
$oid = shift @a;
$value = join(' ', @a);
$message .= " $oid=$value\n";
checkWithOid($oid, $value);
#print "I=$IGNORE,E=$EMAIL, L=$LOG, R=$RUNCMD D=$DB\n";
if ($IGNORE) { exit 0;}
if ($IGNORE) { exit 0; }
#for ipmi traps, the values is: SNMPv2-SMI::enterprises.3183.1.1.0.x or
# RFC1155-SMI::enterprises.3183.1.1.0.x, where x is the ipmi trap id.
my $trapid;
if ($value =~ /enterprises\.3183\.1\.1\.0\.(.*)/) { $trapid=$1; }
my $trapid;
if ($value =~ /enterprises\.3183\.1\.1\.0\.(.*)/) { $trapid = $1; }
#print "trapid=$trapid\n";
my $holder;
my $begin=1;
my $begin = 1;
my $pair;
my $temp;
while ($temp=<STDIN>) {
chomp($temp);
my $temp1=$temp; #save the one with quotes
$temp1 =~ s/\"//g;
my $c1=length($temp);
my $c2=length($temp1);
if (($c1-$c2)%2 == 0) {
if ($begin==1) { # single line
$pair=$temp;
}
else { # middle multi-line
$pair .= " $temp";
next;
}
} else { # multi line
if ($begin==1) {
$pair=$temp; #start of multi-line
$begin=0;
next;
} else {
$pair .= " $temp"; #end of multi-line
$begin=1;
}
}
@a=split(/ /, $pair);
$oid=shift @a;
$value=join(' ', @a);
$value =~ s/^"//;
$value =~ s/"$//;
#for BladeCenter MM traps and RSA II traps, creat a brief message
if ($oid =~ /BLADESPPALT-MIB::spTrapAppId|RSASPPALT-MIB::ibmSpTrapAppId/) {
$briefmsg .= " App ID: $value\n";
$appname=$value;
}
elsif ($oid =~ /BLADESPPALT-MIB::spTrapAppType|RSASPPALT-MIB::ibmSpTrapAppType/) {
$briefmsg .= " App Alert Type: $value\n";
$id=$value;
}
elsif ($oid =~ /BLADESPPALT-MIB::spTrapMsgText|RSASPPALT-MIB::ibmSpTrapMsgText/) {
$briefmsg .= " Message: $value\n";
$message1=$value;
}
elsif ($oid =~ /BLADESPPALT-MIB::spTrapBladeName/) {
my $temp="$value";
$temp =~ /^\"(.*)\"/;
if ($1) {
$briefmsg .= " Blade Name: $value\n";
$node1=$1;
}
}
elsif (($oid =~ /BLADESPPALT-MIB::spTrapSourceId/)) {
$briefmsg .= " Error Source=$value\n";
$errsrc=$value;
}
elsif ($oid =~ /BLADESPPALT-MIB::spTrapPriority|RSASPPALT-MIB::ibmSpTrapPriority/) {
# Critical Alert(0), Major(1), Non-Critical Alert(2), System Alert(4),
# Recovery Alert(8), Informational Only Alert(255)
if ($value==0) {
$severity="Critical Alert";
$severity_type="Critical";
} elsif ($value==1) {
$severity="Major Alert";
$severity_type="Critical";
} elsif ($value==2) {
$severity="Non-Critical Alert";
$severity_type="Warning";
} elsif ($value==4) {
$severity="System Alert";
$severity_type="Warning";
} elsif ($value==8) {
$severity="Recovery Alert";
$severity_type="Informational";
} elsif ($value==255) {
$severity="Informational Alert";
$severity_type="Informational";
}
}
elsif ($oid =~ /enterprises\.3183\.1\.1\.1/) { #IPMI PRTs (traps)
$node1=$host;
#$node1 =~ s/(-(eth|man)\d+)?(\..*)?$//;
my $ip1=$ip;
$ip1 =~ /(\d+\.\d+\.\d+\.\d+)/;
$ip1=$1;
# get the host name if it is unknown
if ($node1 =~/<UNKNOWN>/) {
my $name = xCAT::NetworkUtils->gethostname($ip1);
if ($name) {
$node1=$name;
$host=$name;
my @shorthost = split(/\./, $node1);
$node1=$shorthost[0];
}
}
#print "node1=$node1\n";
#node1 is the bmc name, we need the node that bmc connects to to call xCAT
my $realnode;
my $ipmitab = xCAT::Table->new('ipmi');
if (defined($ipmitab)) {
my @tmp1=$ipmitab->getAllNodeAttribs(['node','bmc']);
if (@tmp1 && (@tmp1 > 0)) {
foreach(@tmp1) {
if ($_->{bmc} eq $node1) { $realnode=$_->{node}; last;}
}
}
$ipmitab->close();
}
if ($realnode) {$node1=$realnode;}
#print "node1=$node1\n";
while ($temp = <STDIN>) {
chomp($temp);
my $temp1 = $temp; #save the one with quotes
$temp1 =~ s/\"//g;
my $c1 = length($temp);
my $c2 = length($temp1);
# make the vlaue into a hex array for decoding
if (($c1 - $c2) % 2 == 0) {
if ($begin == 1) { # single line
$pair = $temp;
}
else { # middle multi-line
$pair .= " $temp";
next;
}
} else { # multi line
if ($begin == 1) {
$pair = $temp; #start of multi-line
$begin = 0;
next;
} else {
$pair .= " $temp"; #end of multi-line
$begin = 1;
}
}
@a = split(/ /, $pair);
$oid = shift @a;
$value = join(' ', @a);
$value =~ s/^"//;
$value =~ s/"$//;
#for BladeCenter MM traps and RSA II traps, creat a brief message
if ($oid =~ /BLADESPPALT-MIB::spTrapAppId|RSASPPALT-MIB::ibmSpTrapAppId/) {
$briefmsg .= " App ID: $value\n";
$appname = $value;
}
elsif ($oid =~ /BLADESPPALT-MIB::spTrapAppType|RSASPPALT-MIB::ibmSpTrapAppType/) {
$briefmsg .= " App Alert Type: $value\n";
$id = $value;
}
elsif ($oid =~ /BLADESPPALT-MIB::spTrapMsgText|RSASPPALT-MIB::ibmSpTrapMsgText/) {
$briefmsg .= " Message: $value\n";
$message1 = $value;
}
elsif ($oid =~ /BLADESPPALT-MIB::spTrapBladeName/) {
my $temp = "$value";
$temp =~ /^\"(.*)\"/;
if ($1) {
$briefmsg .= " Blade Name: $value\n";
$node1 = $1;
}
}
elsif (($oid =~ /BLADESPPALT-MIB::spTrapSourceId/)) {
$briefmsg .= " Error Source=$value\n";
$errsrc = $value;
}
elsif ($oid =~ /BLADESPPALT-MIB::spTrapPriority|RSASPPALT-MIB::ibmSpTrapPriority/) {
# Critical Alert(0), Major(1), Non-Critical Alert(2), System Alert(4),
# Recovery Alert(8), Informational Only Alert(255)
if ($value == 0) {
$severity = "Critical Alert";
$severity_type = "Critical";
} elsif ($value == 1) {
$severity = "Major Alert";
$severity_type = "Critical";
} elsif ($value == 2) {
$severity = "Non-Critical Alert";
$severity_type = "Warning";
} elsif ($value == 4) {
$severity = "System Alert";
$severity_type = "Warning";
} elsif ($value == 8) {
$severity = "Recovery Alert";
$severity_type = "Informational";
} elsif ($value == 255) {
$severity = "Informational Alert";
$severity_type = "Informational";
}
}
elsif ($oid =~ /enterprises\.3183\.1\.1\.1/) { #IPMI PRTs (traps)
$node1 = $host;
#$node1 =~ s/(-(eth|man)\d+)?(\..*)?$//;
my $ip1 = $ip;
$ip1 =~ /(\d+\.\d+\.\d+\.\d+)/;
$ip1 = $1;
# get the host name if it is unknown
if ($node1 =~ /<UNKNOWN>/) {
my $name = xCAT::NetworkUtils->gethostname($ip1);
if ($name) {
$node1 = $name;
$host = $name;
my @shorthost = split(/\./, $node1);
$node1 = $shorthost[0];
}
}
#print "node1=$node1\n";
#node1 is the bmc name, we need the node that bmc connects to to call xCAT
my $realnode;
my $ipmitab = xCAT::Table->new('ipmi');
if (defined($ipmitab)) {
my @tmp1 = $ipmitab->getAllNodeAttribs([ 'node', 'bmc' ]);
if (@tmp1 && (@tmp1 > 0)) {
foreach (@tmp1) {
if ($_->{bmc} eq $node1) { $realnode = $_->{node}; last; }
}
}
$ipmitab->close();
}
if ($realnode) { $node1 = $realnode; }
#print "node1=$node1\n";
# make the vlaue into a hex array for decoding
$value =~ s/\"//g;
my @varray = split(/\s+/, $value);
#print "varray=@varray\n";
foreach (@varray) { $_ = hex($_); }
my $error = xCAT_plugin::ipmi->decodealert($trapid, $node1, @varray);
$briefmsg .= $error;
$message .= " decodedipmialert=$error\n";
#severity value from decodealert are:
#LOG,INFORMATION,OK,CRITICAL,NON-RECOVERABLE,MONITOR and UNKNOWN-SEVERITY
$severity_type = "Warning";
if ($error) {
my @tempArray = split(/\:/, $error);
$severity = $tempArray[0];
if ($severity eq "LOG") { #in fact this is called "unspecifiled"
$severity_type = "Warning";
}
elsif ($severity eq "INFORMATION") {
$severity_type = "Informational";
}
elsif ($severity eq "OK") {
$severity_type = "Informational";
}
elsif ($severity eq "CRITICAL") {
$severity_type = "Critical";
}
elsif ($severity eq "NON-RECOVERABLE") {
$severity_type = "Critical";
}
}
}
$message .= " $oid=$value\n";
#check agains the settings
$value =~ s/\"//g;
my @varray=split(/\s+/, $value);
#print "varray=@varray\n";
foreach (@varray) { $_=hex($_); }
my $error = xCAT_plugin::ipmi->decodealert($trapid, $node1, @varray);
$briefmsg .= $error;
$message .= " decodedipmialert=$error\n";
checkWithOid($oid, $value);
#severity value from decodealert are:
#LOG,INFORMATION,OK,CRITICAL,NON-RECOVERABLE,MONITOR and UNKNOWN-SEVERITY
$severity_type="Warning";
if ($error) {
my @tempArray=split(/\:/, $error);
$severity=$tempArray[0];
if ($severity eq "LOG") {#in fact this is called "unspecifiled"
$severity_type="Warning";
}
elsif($severity eq "INFORMATION") {
$severity_type="Informational";
}
elsif($severity eq "OK") {
$severity_type="Informational";
}
elsif($severity eq "CRITICAL") {
$severity_type="Critical";
}
elsif($severity eq "NON-RECOVERABLE") {
$severity_type="Critical";
}
}
}
$message .= " $oid=$value\n";
#check agains the settings
$value =~ s/\"//g;
checkWithOid($oid, $value);
#print "I=$IGNORE,E=$EMAIL, L=$LOG, R=$RUNCMD, D=$DB\n";
if ($IGNORE) { exit 0;}
#print "I=$IGNORE,E=$EMAIL, L=$LOG, R=$RUNCMD, D=$DB\n";
if ($IGNORE) { exit 0; }
}
if (!$severity_type) { $severity_type="Warning"; }
if ((!$IGNORE) && exists($hashI{$severity_type})) {
#print "ignore, exit\n";
exit 0;
if (!$severity_type) { $severity_type = "Warning"; }
if ((!$IGNORE) && exists($hashI{$severity_type})) {
#print "ignore, exit\n";
exit 0;
}
if ((!$EMAIL) && exists($hashE{$severity_type})) { $EMAIL=1; }
if ((!$LOG) && exists($hashL{$severity_type})) { $LOG=1; }
if ((!$DB) && exists($hashD{$severity_type})) { $DB=1; }
if ((!$EMAIL) && exists($hashE{$severity_type})) { $EMAIL = 1; }
if ((!$LOG) && exists($hashL{$severity_type})) { $LOG = 1; }
if ((!$DB) && exists($hashD{$severity_type})) { $DB = 1; }
foreach my $k (keys %hashRUN) {
if (($hashRUN{$k} == 0) && exists($hashR{$k}->{$severity_type})) { $hashRUN{$k} = 1; }
}
#print "I=$IGNORE,E=$EMAIL, L=$LOG, R=$RUNCMD, D=$DB\n";
#email 'alerts' aliase
if ($EMAIL || ((keys(%hashE)==0) && ($severity_type =~/Critical|Warning/))) {
#($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
#$datetime=sprintf "%2d-%02d-%04d %02d:%02d:%02d", $mon+1,$mday,$year+1900,$hour,$min,$sec;
#my $head="SNMP $severity received from $host($ip) on $datetime\n$briefmsg\n";
my $head="SNMP $severity received from $host($ip)\n$briefmsg\n";
if ($node1) { $info= getMoreInfo($node1);}
my $middle="Trap details:\n$message\n";
if ($EMAIL || ((keys(%hashE) == 0) && ($severity_type =~ /Critical|Warning/))) {
#email the full message to the alerts aliase
my $cmd="echo \'$info$head\n$middle\' \| mail -s \"$severity_type: Cluster SNMP Alert\!\" $MAILTO";
$ENV{'XCATCFG'}="";
`$cmd`;
#($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
#$datetime=sprintf "%2d-%02d-%04d %02d:%02d:%02d", $mon+1,$mday,$year+1900,$hour,$min,$sec;
#my $head="SNMP $severity received from $host($ip) on $datetime\n$briefmsg\n";
my $head = "SNMP $severity received from $host($ip)\n$briefmsg\n";
if ($node1) { $info = getMoreInfo($node1); }
my $middle = "Trap details:\n$message\n";
#email the full message to the alerts aliase
my $cmd = "echo \'$info$head\n$middle\' \| mail -s \"$severity_type: Cluster SNMP Alert\!\" $MAILTO";
$ENV{'XCATCFG'} = "";
`$cmd`;
}
#log to syslog if needed. default is log all
$ENV{'XCATCFG'}="";
if ($LOG || (keys(%hashL)==0)) {
my $head="SNMP $severity received from $host($ip).";
my $body;
if ($briefmsg) { $body=$briefmsg;}
else { $body=$message; }
$ENV{'XCATCFG'} = "";
if ($LOG || (keys(%hashL) == 0)) {
my $head = "SNMP $severity received from $host($ip).";
my $body;
if ($briefmsg) { $body = $briefmsg; }
else { $body = $message; }
openlog("xcat","","local4");
if ($severity_type eq "Informational") {
syslog("local4|info", "$head\n$body\n");
} else {
syslog("local4|err", "$head\n$body\n");
}
closelog();
openlog("xcat", "", "local4");
if ($severity_type eq "Informational") {
syslog("local4|info", "$head\n$body\n");
} else {
syslog("local4|err", "$head\n$body\n");
}
closelog();
}
#save to eventlog table in xCAT database
if ($DB) {
my $head="SNMP $severity received from $host($ip)\n$briefmsg\n";
if (($node1)&& (!$info)) { $info= getMoreInfo($node1);}
my $middle="Trap details:\n$message\n";
my $event={
eventtype => 'event',
monitor => 'snmpmon',
monnode => $host,
node => $node1? $node1:"",
my $head = "SNMP $severity received from $host($ip)\n$briefmsg\n";
if (($node1) && (!$info)) { $info = getMoreInfo($node1); }
my $middle = "Trap details:\n$message\n";
my $event = {
eventtype => 'event',
monitor => 'snmpmon',
monnode => $host,
node => $node1 ? $node1 : "",
application => $appname,
component => $errsrc ,
id =>$id,
severity => $severity_type,
message => $message1,
rawdata => "$info$head\n$middle",
component => $errsrc,
id => $id,
severity => $severity_type,
message => $message1,
rawdata => "$info$head\n$middle",
};
my @a=();
push(@a, $event);
xCAT::TableUtils->logEventsToDatabase(\@a);
my @a = ();
push(@a, $event);
xCAT::TableUtils->logEventsToDatabase(\@a);
}
#run user defined commands if needed.
foreach my $k (keys %hashRUN) {
if ($hashRUN{$k} == 1) {
$k =~ /runcmd(\d*)/;
my $scripts=$settings{"cmds$1"};
while ($scripts =~ s/^([^,]+)(,)*//) {
my $cmd="echo \'host=$host\nip=$ip\n$message\n\' \| $1";
`$cmd`;
}
$k =~ /runcmd(\d*)/;
my $scripts = $settings{"cmds$1"};
while ($scripts =~ s/^([^,]+)(,)*//) {
my $cmd = "echo \'host=$host\nip=$ip\n$message\n\' \| $1";
`$cmd`;
}
}
}
#--------------------------------------------------------------------------------
=head3 getMoreInfo
This function returns the node module/type, serial number, position etc.
Arguments:
@ -358,71 +371,73 @@ foreach my $k (keys %hashRUN) {
Returns:
A string with node info ready to display.
=cut
#--------------------------------------------------------------------------------
sub getMoreInfo {
my $node=shift;
my $pos;
my $vpd;
# get module name and serial number from the xCAT DB.
my $ref;
my $table=xCAT::Table->new("vpd", -create =>1);
if ($table) {
my $ref = $table->getNodeAttribs($node, ['serial', 'mtm']);
if ($ref) {
$vpd .= " Type/Mudule: ";
if ($ref->{mtm}) { $vpd .= $ref->{mtm};}
$vpd .= "\n";
$vpd .= " Serial Number: ";
if ($ref->{serial}) { $vpd .= $ref->{serial};}
$vpd .= "\n";
}
$table->close();
}
my $node = shift;
my $pos;
my $vpd;
# get the info from rinv command if nothing in the vpd table
if (!$vpd) {
my $result=`XCATBYPASS=Y $::XCATROOT/bin/rinv $node all 2>&1 | egrep -i '(model|serial)' | grep -v Univ`;
if ($? == 0) {#success
chomp($result);
my @b=split(/\n/, $result);
foreach (@b) {
s/^(.*)\:(.*)\:(.*)$/$2: $3/;
$vpd .= " $_\n";
# get module name and serial number from the xCAT DB.
my $ref;
my $table = xCAT::Table->new("vpd", -create => 1);
if ($table) {
my $ref = $table->getNodeAttribs($node, [ 'serial', 'mtm' ]);
if ($ref) {
$vpd .= " Type/Mudule: ";
if ($ref->{mtm}) { $vpd .= $ref->{mtm}; }
$vpd .= "\n";
$vpd .= " Serial Number: ";
if ($ref->{serial}) { $vpd .= $ref->{serial}; }
$vpd .= "\n";
}
}
}
if (!$vpd) {
$vpd .= " Type/Mudule: \n";
$vpd .= " Serial Number: \n";
}
$table->close();
}
#get the position
my $table1=xCAT::Table->new("nodepos", -create =>1);
if ($table1) {
my $ref1 = $table1->getNodeAttribs($node, ['rack', 'u', 'chassis', 'slot', 'room', 'comments']);
if (($ref1) && ($ref1->{room})) { $pos .= " Room: " . $ref1->{room}. "\n"; }
if(($ref1) && ($ref1->{rack})) { $pos .= " Rack: ". $ref1->{rack}. "\n";}
if(($ref1) && ($ref1->{u})) { $pos .= " Unit: " . $ref1->{u} . "\n"; }
if(($ref1) && ($ref1->{chassis})) { $pos .= " Chassis: " . $ref1->{chassis} . "\n";}
if(($ref1) && ($ref1->{slot})) { $pos .= " Slot: " . $ref1->{slot} . "\n";}
if(($ref1) && ($ref1->{comments})) { $pos .= " Comments: " . $ref1->{comments} . "\n";}
# get the info from rinv command if nothing in the vpd table
if (!$vpd) {
my $result = `XCATBYPASS=Y $::XCATROOT/bin/rinv $node all 2>&1 | egrep -i '(model|serial)' | grep -v Univ`;
if ($? == 0) { #success
chomp($result);
my @b = split(/\n/, $result);
foreach (@b) {
s/^(.*)\:(.*)\:(.*)$/$2: $3/;
$vpd .= " $_\n";
}
}
}
if (!$vpd) {
$vpd .= " Type/Mudule: \n";
$vpd .= " Serial Number: \n";
}
$pos .= "\n";
$table1->close();
}
#get the position
my $table1 = xCAT::Table->new("nodepos", -create => 1);
if ($table1) {
my $ref1 = $table1->getNodeAttribs($node, [ 'rack', 'u', 'chassis', 'slot', 'room', 'comments' ]);
if (($ref1) && ($ref1->{room})) { $pos .= " Room: " . $ref1->{room} . "\n"; }
if (($ref1) && ($ref1->{rack})) { $pos .= " Rack: " . $ref1->{rack} . "\n"; }
if (($ref1) && ($ref1->{u})) { $pos .= " Unit: " . $ref1->{u} . "\n"; }
if (($ref1) && ($ref1->{chassis})) { $pos .= " Chassis: " . $ref1->{chassis} . "\n"; }
if (($ref1) && ($ref1->{slot})) { $pos .= " Slot: " . $ref1->{slot} . "\n"; }
if (($ref1) && ($ref1->{comments})) { $pos .= " Comments: " . $ref1->{comments} . "\n"; }
if (($pos) || ($vpd)) {
return " Node: $node\n$vpd$pos\n";
}
return "";
$pos .= "\n";
$table1->close();
}
if (($pos) || ($vpd)) {
return " Node: $node\n$vpd$pos\n";
}
return "";
}
#--------------------------------------------------------------------------------
=head3 parseSettings
This function takes a setting string which looks like "key1=value1,key2=value2..."
and returns a hash (key1=>value1, key2=>value2...).
@ -431,31 +446,33 @@ sub getMoreInfo {
Returns:
A hash.
=cut
#--------------------------------------------------------------------------------
sub parseSettings {
my $settings=shift;
my %ret=();
while (($settings =~ s/^(Informational|Warning|Critical|All|None)()()(,)*//) ||
($settings =~ s/^([^\=]+)(=~)(\"[^\"]+\")(,)*//) ||
($settings =~ s/^([^\=]+)(=~)([^\"\,]+)(,)*//) ||
($settings =~ s/^([^\=]+)(=)(\"[^\"]+\")(,)*//) ||
($settings =~ s/^([^\=]+)(=)([^\"\,]+)(,)*//)) {
my $val='eq';
if ($2 eq "=~") { $val='=~';}
if (exists($ret{$1}{$val})) {
my $pa=$ret{$1}{$val};
push(@$pa, $3);
my $settings = shift;
my %ret = ();
while (($settings =~ s/^(Informational|Warning|Critical|All|None)()()(,)*//) ||
($settings =~ s/^([^\=]+)(=~)(\"[^\"]+\")(,)*//) ||
($settings =~ s/^([^\=]+)(=~)([^\"\,]+)(,)*//) ||
($settings =~ s/^([^\=]+)(=)(\"[^\"]+\")(,)*//) ||
($settings =~ s/^([^\=]+)(=)([^\"\,]+)(,)*//)) {
my $val = 'eq';
if ($2 eq "=~") { $val = '=~'; }
if (exists($ret{$1}{$val})) {
my $pa = $ret{$1}{$val};
push(@$pa, $3);
}
else {
$ret{$1}{$val} = [$3];
}
}
else {
$ret{$1}{$val}=[$3];
}
}
#print Dumper(%ret);
return %ret;
#print Dumper(%ret);
return %ret;
}
#--------------------------------------------------------------------------------
=head3 checkWithOid
This function checks the input strings with the setting to see what
actions need to be done for this event.
@ -465,77 +482,79 @@ sub parseSettings {
Returns:
none. The variables $EMAIL, $LOG, $IGNORE and $RUNCMD may be changed.
=cut
#--------------------------------------------------------------------------------
sub checkWithOid {
my $o=shift;
my $v=shift;
my $o = shift;
my $v = shift;
sub checking {
my $hashX=shift;
my $o=shift;
my $v=shift;
if (exists($hashX->{'All'})) { return 1; }
if (exists($hashX->{'None'})) { return 0; }
my @a_oid=split('::', $o);
my $new_o=$o;
if (@a_oid == 2) { $new_o=$a_oid[1]; }
#print "o=$o, new_o=$new_o v=$v\n";
sub checking {
my $hashX = shift;
my $o = shift;
my $v = shift;
#check for 'contains'
if (exists($hashX->{$o})) {
my $pa= $hashX->{$o}{'=~'};
foreach(@$pa) {
if ($v =~ /$_/) {return 1; }
}
}
if (exists($hashX->{$new_o})) {
my $pa= $hashX->{$new_o}{'=~'};
foreach(@$pa) {
if ($v =~ /$_/) {return 1; }
}
if (exists($hashX->{'All'})) { return 1; }
if (exists($hashX->{'None'})) { return 0; }
my @a_oid = split('::', $o);
my $new_o = $o;
if (@a_oid == 2) { $new_o = $a_oid[1]; }
#print "o=$o, new_o=$new_o v=$v\n";
#check for 'contains'
if (exists($hashX->{$o})) {
my $pa = $hashX->{$o}{'=~'};
foreach (@$pa) {
if ($v =~ /$_/) { return 1; }
}
}
if (exists($hashX->{$new_o})) {
my $pa = $hashX->{$new_o}{'=~'};
foreach (@$pa) {
if ($v =~ /$_/) { return 1; }
}
}
#check for 'equals'
if (exists($hashX->{$o})) {
my $pa = $hashX->{$o}{'eq'};
foreach (@$pa) {
if ($_ eq $v) { return 1; }
}
}
if (exists($hashX->{$new_o})) {
my $pa = $hashX->{$new_o}{'eq'};
foreach (@$pa) {
if ($_ eq $v) { return 1; }
}
}
return 0;
}
#check for 'equals'
if (exists($hashX->{$o})) {
my $pa= $hashX->{$o}{'eq'};
foreach(@$pa) {
if ($_ eq $v) { return 1; }
}
}
if (exists($hashX->{$new_o})) {
my $pa= $hashX->{$new_o}{'eq'};
foreach(@$pa) {
if ($_ eq $v) { return 1; }
}
if ((!$IGNORE) && (keys(%hashI) > 0)) {
$IGNORE = checking(\%hashI, $o, $v);
if ($IGNORE) { return; }
}
return 0;
}
if ((!$IGNORE) && (keys(%hashI)>0)) {
$IGNORE=checking(\%hashI, $o, $v);
if ($IGNORE) { return;}
}
if ((!$EMAIL) && (keys(%hashE) > 0)) {
$EMAIL = checking(\%hashE, $o, $v);
}
if ((!$EMAIL) && (keys(%hashE)>0)) {
$EMAIL=checking(\%hashE, $o, $v);
}
if ((!$LOG) && (keys(%hashL) > 0)) {
$LOG = checking(\%hashL, $o, $v);
}
if ((!$LOG) && (keys(%hashL)>0)) {
$LOG=checking(\%hashL, $o, $v);
}
if ((!$DB) && (keys(%hashD) > 0)) {
$DB = checking(\%hashD, $o, $v);
}
if ((!$DB) && (keys(%hashD)>0)) {
$DB=checking(\%hashD, $o, $v);
}
foreach my $k (keys %hashRUN) {
if ($hashRUN{$k} == 0) { $hashRUN{$k} = checking($hashR{$k}, $o, $v); }
}
foreach my $k (keys %hashRUN) {
if ($hashRUN{$k} == 0) { $hashRUN{$k} = checking($hashR{$k}, $o, $v); }
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
# This command can be used to
# This command can be used to
# 1. Enable/Disbale the subroutine calling trace.
# 2. Enable the commented trace log inside a subroutine.
@ -12,7 +12,7 @@
# xCAT::Utils(isMN,Version)
# xCAT_plugin::DBobjectdefs(defls,process_request)
#
# Following three lines need to be added to enable the capability of commented trace
# Following three lines need to be added to enable the capability of commented trace
#if (defined $ENV{ENABLE_TRACE_CODE}) {
# use xCAT::Enabletrace qw(loadtrace filter);
# loadtrace();
@ -41,77 +41,79 @@ my $usage = "xcatdebug { [-f enable|disable [-c configuration file | subroutine
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("no_pass_through");
if (
!GetOptions(
'f=s' => \$::FUNC,
'c=s' => \$::CONFIG,
'd=s' => \$::DEBUG,)) {
!GetOptions(
'f=s' => \$::FUNC,
'c=s' => \$::CONFIG,
'd=s' => \$::DEBUG,)) {
print "$usage";
exit 1;
}
if ($^O !~ /^linux/i) {
print "xcatdebug command only supports Linux Operating System.\n";
exit 1;
print "xcatdebug command only supports Linux Operating System.\n";
exit 1;
}
if (!($::FUNC || $::DEBUG)) {
print "$usage";
exit 1;
print "$usage";
exit 1;
}
# The action that enable the commented debug log should be done firstly
# In this case the xcatd need to be restart
if (defined($::DEBUG)) {
if ($::DEBUG eq "enable") {
`XCATRELOAD=yes ENABLE_TRACE_CODE=1 xcatd -p /var/run/xcatd.pid`;
print "Enabled the commented trace log.\n";
} elsif ($::DEBUG eq "disable") {
`XCATRELOAD=yes xcatd -p /var/run/xcatd.pid`;
print "Disabled the commented trace log.\n";
} else {
print "$usage";
exit 1;
}
if ($::DEBUG eq "enable") {
`XCATRELOAD=yes ENABLE_TRACE_CODE=1 xcatd -p /var/run/xcatd.pid`;
print "Enabled the commented trace log.\n";
} elsif ($::DEBUG eq "disable") {
`XCATRELOAD=yes xcatd -p /var/run/xcatd.pid`;
print "Disabled the commented trace log.\n";
} else {
print "$usage";
exit 1;
}
}
if (defined($::FUNC)) {
# Get the pid of xcatd
my $pid;
if (-e "/var/run/xcatd.pid") {
open (PID, "</var/run/xcatd.pid") or die "Cannot open /var/run/xcatd.pid\n";
$pid = <PID>;
close (PID);
} elsif ($pid = `ps -ef | grep 'xcatd: SSL listener' | grep -v 'grep' | awk '{print \$2}'`) {
} else {
die "Cannot find the pid in the /var/run/xcatd.pid\n";
}
if ($::FUNC eq "enable") {
# Enable the function trace
if (defined $::CONFIG) {
open(CFG, ">/tmp/xcatcallingtrace.cfg") or die "Cannot open /tmp/xcatcallingtrace.cfg\n";
print CFG $::CONFIG;
close (CFG);
# Get the pid of xcatd
my $pid;
if (-e "/var/run/xcatd.pid") {
open(PID, "</var/run/xcatd.pid") or die "Cannot open /var/run/xcatd.pid\n";
$pid = <PID>;
close(PID);
} elsif ($pid = `ps -ef | grep 'xcatd: SSL listener' | grep -v 'grep' | awk '{print \$2}'`) {
} else {
unlink "/tmp/xcatcallingtrace.cfg";
die "Cannot find the pid in the /var/run/xcatd.pid\n";
}
open(TRACEFLAG, ">/tmp/xcatcallingtrace.flag") or die "Cannot open file to write in /tmp\n";
print TRACEFLAG 1;
close (TRACEFLAG);
kill SIGTRAP, $pid;
print "Enabled the subroutine calling trace.\n";
} elsif ($::FUNC eq "disable") {
open(TRACEFLAG, ">/tmp/xcatcallingtrace.flag") or die "Cannot open file to write in /tmp\n";
print TRACEFLAG 0;
close (TRACEFLAG);
kill SIGTRAP, $pid;
unlink "/tmp/xcatcallingtrace.cfg";
print "Disabled the subroutine calling trace.\n";
} else {
print "$usage";
exit 1;
}
print " Get the trace log from the /var/log/xcat/subcallingtrace\n";
if ($::FUNC eq "enable") {
# Enable the function trace
if (defined $::CONFIG) {
open(CFG, ">/tmp/xcatcallingtrace.cfg") or die "Cannot open /tmp/xcatcallingtrace.cfg\n";
print CFG $::CONFIG;
close(CFG);
} else {
unlink "/tmp/xcatcallingtrace.cfg";
}
open(TRACEFLAG, ">/tmp/xcatcallingtrace.flag") or die "Cannot open file to write in /tmp\n";
print TRACEFLAG 1;
close(TRACEFLAG);
kill SIGTRAP, $pid;
print "Enabled the subroutine calling trace.\n";
} elsif ($::FUNC eq "disable") {
open(TRACEFLAG, ">/tmp/xcatcallingtrace.flag") or die "Cannot open file to write in /tmp\n";
print TRACEFLAG 0;
close(TRACEFLAG);
kill SIGTRAP, $pid;
unlink "/tmp/xcatcallingtrace.cfg";
print "Disabled the subroutine calling trace.\n";
} else {
print "$usage";
exit 1;
}
print " Get the trace log from the /var/log/xcat/subcallingtrace\n";
}

View File

@ -13,53 +13,55 @@ use xCAT_monitoring::xcatmon;
# This script is used as a cron job by the xCAT monitoring plug-in
# to monitor the node status. To activate it, simply do
# chtab pname=xCAT monitoring.nodestatmon=Y
##################################################################
##################################################################
#($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
#printf "%2d-%02d-%04d %02d:%02d:%02d: xcatnodemon started.\n", $mon+1,$mday,$year+1900,$hour,$min,$sec;
#get saved node status from the nodelist table
my %nodes_status_old=xCAT_monitoring::xcatmon::getMonNodesStatus();
#get saved node status from the nodelist table
my %nodes_status_old = xCAT_monitoring::xcatmon::getMonNodesStatus();
#get a list of nodes
my $tmp_node_active=$nodes_status_old{$::STATUS_ACTIVE};
my $tmp_node_inactive=$nodes_status_old{$::STATUS_INACTIVE};
my $tmp_node_unknown=$nodes_status_old{unknown};
my $tmp_node_active = $nodes_status_old{$::STATUS_ACTIVE};
my $tmp_node_inactive = $nodes_status_old{$::STATUS_INACTIVE};
my $tmp_node_unknown = $nodes_status_old{unknown};
#print "active nodes: @$tmp_node_active\n";
#print "inactive nodes: @$tmp_node_inactive\n";
#print "unknown nodes: @$tmp_node_unknown\n";
#get current node status
my %nodes_status_new1=();
if ($tmp_node_active) { %nodes_status_new1=xCAT::NetworkUtils->pingNodeStatus(@$tmp_node_active);}
my %nodes_status_new2=();
if ($tmp_node_inactive) {%nodes_status_new2=xCAT::NetworkUtils->pingNodeStatus(@$tmp_node_inactive);}
my %nodes_status_new3=();
if ($tmp_node_unknown) { %nodes_status_new3=xCAT::NetworkUtils->pingNodeStatus(@$tmp_node_unknown);}
my %nodes_status_new1 = ();
if ($tmp_node_active) { %nodes_status_new1 = xCAT::NetworkUtils->pingNodeStatus(@$tmp_node_active); }
my %nodes_status_new2 = ();
if ($tmp_node_inactive) { %nodes_status_new2 = xCAT::NetworkUtils->pingNodeStatus(@$tmp_node_inactive); }
my %nodes_status_new3 = ();
if ($tmp_node_unknown) { %nodes_status_new3 = xCAT::NetworkUtils->pingNodeStatus(@$tmp_node_unknown); }
my $changed1=$nodes_status_new1{$::STATUS_INACTIVE};
my $changed2=$nodes_status_new2{$::STATUS_ACTIVE};
my $changed3=$nodes_status_new3{$::STATUS_INACTIVE};
my $changed4=$nodes_status_new3{$::STATUS_ACTIVE};
my @changed_active=(@$changed2, @$changed4);
my @changed_inactive=(@$changed1, @$changed3);
my $changed1 = $nodes_status_new1{$::STATUS_INACTIVE};
my $changed2 = $nodes_status_new2{$::STATUS_ACTIVE};
my $changed3 = $nodes_status_new3{$::STATUS_INACTIVE};
my $changed4 = $nodes_status_new3{$::STATUS_ACTIVE};
my @changed_active = (@$changed2, @$changed4);
my @changed_inactive = (@$changed1, @$changed3);
#print " switch to active: @changed_active\n";
#print " switch to inactive: @changed_inactive\n";
my %node_status=();
if (@changed_active>0) {
$node_status{$::STATUS_ACTIVE}=\@changed_active;
}
if (@changed_inactive>0) {
$node_status{$::STATUS_INACTIVE}=\@changed_inactive;
my %node_status = ();
if (@changed_active > 0) {
$node_status{$::STATUS_ACTIVE} = \@changed_active;
}
if (@changed_inactive > 0) {
$node_status{$::STATUS_INACTIVE} = \@changed_inactive;
}
#only set the node status for the changed ones
if (keys(%node_status) > 0) {
#the second parameter means ignore checking. This is because the check is
#done getMonNodesStatus() call
xCAT_monitoring::xcatmon::setNodeStatusAttributes(\%node_status, 1);
#the second parameter means ignore checking. This is because the check is
#done getMonNodesStatus() call
xCAT_monitoring::xcatmon::setNodeStatusAttributes(\%node_status, 1);
}
#($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);

View File

@ -42,9 +42,9 @@
BEGIN
{
$::XCATROOT =
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
}
use lib "$::XCATROOT/lib/perl";
use File::Spec;
@ -56,7 +56,7 @@ my @Commands_array;
my $Command_name;
my $Command;
my $currentDirectory;
my $logDirectory="/tmp/xcatsnap";
my $logDirectory = "/tmp/xcatsnap";
my $output_dir;
my @files_array;
my @file_list;
@ -82,7 +82,7 @@ sub usage {
sub valid_dir {
$logDirectory = File::Spec->rel2abs($logDirectory);
my $Dir_last_char = substr $logDirectory, -1, 1;
if ( $Dir_last_char eq "/" ) {
if ($Dir_last_char eq "/") {
chop($logDirectory);
}
@ -92,12 +92,12 @@ sub valid_dir {
sub run_cmd {
my @output;
$Command_name = $Command;#Constructing the output file name from the command
$Command_name = $Command; #Constructing the output file name from the command
$Command_name =~ s/ /_/g;
$Command_name =~ s/-//g;
$Command_name =~ s/tabdump_//g;
$Command_name =~ s/\//_/g;
print "$Command -> $Command_name.out";
print "\n\tExecuting: $Command \n";
eval {
@ -110,33 +110,33 @@ sub run_cmd {
print "\t$Command timed out.\n";
@output = "$Command timed out.\n";
}
print "\tExecution Complete :$Command.\n"; #Writing command output into a file
my $outfile = $output_dir . $Command_name . ".out";
open( MYFILE, ">", $outfile );
print MYFILE @output;
close(MYFILE);
print "\tExecution Complete :$Command.\n"; #Writing command output into a file
my $outfile = $output_dir . $Command_name . ".out";
open(MYFILE, ">", $outfile);
print MYFILE @output;
close(MYFILE);
}
######################## Tar it: Tars files and folders #############################
sub Tar_it {
my $file= shift;
my $file = shift;
print "\n Processing $file ..\n";
my $last = substr $file, -1, 1;
if ( $last eq "*" ) {
if ($last eq "*") {
@file_list = `ls $file 2>/dev/null`;
foreach my $i (@file_list) {
print "\tProcessing $i";
}
}
if ( -l $file ) {
if (-l $file) {
check_symbolic_link($file); # Checking Symbolic links
}
if ( $circular != 1 ) {
if ( -e $TarFile ) {
if ($circular != 1) {
if (-e $TarFile) {
`cd /; tar -uf $TarFile .$file 2>/dev/null`;
}
else {
@ -151,14 +151,14 @@ sub Tar_it {
sub check_symbolic_link {
my $file= shift;
my $file = shift;
my $max_link_count = 32;
my $i = 0;
while ( defined( my $link = readlink $file ) && $i <= $max_link_count ) {
while (defined(my $link = readlink $file) && $i <= $max_link_count) {
$file = $link;
$i++;
}
if ( $i >= $max_link_count ) {
if ($i >= $max_link_count) {
$circular = 1;
print
"Either the link is circular or the symbolic link count exceeds max_link_count";
@ -168,7 +168,7 @@ sub check_symbolic_link {
############## make_output_dir: Creates output directory #######################
sub make_output_dir {
if ( -d $output_dir ) {
if (-d $output_dir) {
`rm -rf $output_dir`;
}
`mkdir $output_dir`;
@ -178,67 +178,68 @@ sub make_output_dir {
sub snap_it {
print "Collecting files ...\n";
chop( $INSTALLDIR =
`tabdump site | grep installdir | cut -f2 -d ,` );
chop($INSTALLDIR =
`tabdump site | grep installdir | cut -f2 -d ,`);
$INSTALLDIR =~ s/"//g;
# make a list of all files in /tftpboot
# need to limit what we get due to size
`ls -lR /tftpboot > /tftpboot/tftpboot.list`;
if ( $OSname eq "AIX" ) {
if ($OSname eq "AIX") {
@files_array = (
"/etc/xcat/*","$::ROOTHOME/.xcat/*", "$INSTALLDIR/autoinst/*",
"/etc/xcat/*", "$::ROOTHOME/.xcat/*", "$INSTALLDIR/autoinst/*",
"$INSTALLDIR/postscripts/*", "$INSTALLDIR/prescripts/*",
"/tftpboot/*", "/var/log/consoles/*",
"/tmp/spot.out.*", "/var/lib/dhcpd/dhcpd.leases",
"/etc/hosts", "/etc/conserver.cf",
"/var/log/conserver", "/etc/db_file.cr",
"/etc/dhcpsd.cnf", "/var/adm/ras/nimlog",
"/etc/resolv.conf", "/etc/named.conf", "/var/log/messages", "/var/log/xcat/*");
"/etc/resolv.conf", "/etc/named.conf", "/var/log/messages", "/var/log/xcat/*");
}
elsif ( $OSname eq "Linux" ) {
elsif ($OSname eq "Linux") {
@files_array = (
"/etc/xcat/*","$::ROOTHOME/.xcat/*", "$INSTALLDIR/autoinst/*",
"$INSTALLDIR/postscripts/*", "$INSTALLDIR/prescripts/*", "$INSTALLDIR/custom/*",
"/tftpboot/*", "/var/log/consoles/*",
"/etc/*-release", "/etc/dhcpd.conf",
"/etc/xcat/*", "$::ROOTHOME/.xcat/*", "$INSTALLDIR/autoinst/*",
"$INSTALLDIR/postscripts/*", "$INSTALLDIR/prescripts/*", "$INSTALLDIR/custom/*",
"/tftpboot/*", "/var/log/consoles/*",
"/etc/*-release", "/etc/dhcpd.conf",
"/var/lib/dhcpd/dhcpd.leases", "/etc/hosts", "/etc/resolv.conf",
"/etc/named.conf", "/etc/conserver.cf", "/var/log/conserver",
"/etc/nsswitch.conf", "/var/log/messages", "/var/log/xcat/*");
"/etc/named.conf", "/etc/conserver.cf", "/var/log/conserver",
"/etc/nsswitch.conf", "/var/log/messages", "/var/log/xcat/*");
print("@files_array \n");
}
foreach my $item (@files_array) {
my $file = $item;
Tar_it($file);
}
foreach my $item (@files_array) {
my $file = $item;
Tar_it($file);
}
print "Done collecting files ...\n\n";
print "Gathering system configuration...\n\n";
$output_dir = "$logDirectory/commands_output/";
my $xcatroot=$ENV{'XCATROOT'};
my $xcatroot = $ENV{'XCATROOT'};
my $installdir;
chop( $installdir =
`tabdump site | grep installdir | cut -f2 -d ,` );
chop($installdir =
`tabdump site | grep installdir | cut -f2 -d ,`);
make_output_dir();
if ( $OSname eq "AIX" ) {
if ($OSname eq "AIX") {
@Commands_array = (
"uname -a","ifconfig -a","netstat -in","netstat -rn","env",
"reventlog -a","lsmod","/sbin/lspci","lssrc -a","rpm -qa",
"ls $installdir","/bin/crontab -l",
"find /tftpboot -size -32k","ls -lR $xcatroot",
"arp -a","ps -edlf","ps -aux","ulimit -a","df -k","oslevel",
"netstat -A","errpt -a","/usr/sbin/instfix -i",
"/usr/sbin/lsnim -l","lssrc -l -s dhcpsd","lslpp -hac","lsxcatd -a");
"uname -a", "ifconfig -a", "netstat -in", "netstat -rn", "env",
"reventlog -a", "lsmod", "/sbin/lspci", "lssrc -a", "rpm -qa",
"ls $installdir", "/bin/crontab -l",
"find /tftpboot -size -32k", "ls -lR $xcatroot",
"arp -a", "ps -edlf", "ps -aux", "ulimit -a", "df -k", "oslevel",
"netstat -A", "errpt -a", "/usr/sbin/instfix -i",
"/usr/sbin/lsnim -l", "lssrc -l -s dhcpsd", "lslpp -hac", "lsxcatd -a");
}
elsif ( $OSname eq "Linux" ) {
elsif ($OSname eq "Linux") {
@Commands_array = (
"uname -a","ifconfig -a","netstat -in","netstat -rn","env",
"reventlog -a","lsmod","/sbin/lspci","lssrc -a","rpm -qa",
"ls $installdir","/usr/bin/crontab -l",
"find /tftpboot -size -32k","ls -lR $xcatroot",
"arp -a","ps -edlf","ps -aux","ulimit -a","df -k",
"cat /etc/issue","lsxcatd -a","cat /proc/meminfo", "cat /proc/cpuinfo");
"uname -a", "ifconfig -a", "netstat -in", "netstat -rn", "env",
"reventlog -a", "lsmod", "/sbin/lspci", "lssrc -a", "rpm -qa",
"ls $installdir", "/usr/bin/crontab -l",
"find /tftpboot -size -32k", "ls -lR $xcatroot",
"arp -a", "ps -edlf", "ps -aux", "ulimit -a", "df -k",
"cat /etc/issue", "lsxcatd -a", "cat /proc/meminfo", "cat /proc/cpuinfo");
}
foreach my $item (@Commands_array) {
$Command = $item;
@ -246,13 +247,13 @@ sub snap_it {
}
print "Done gathering system configuration...\n\n";
if ( -d "/opt/xcat/" ) {
if (-d "/opt/xcat/") {
print "Capturing xCAT specific information...\n\n";
print "Gathering management node configurations...\n";
@Commands_array = (
"lsdef -t site -l","lsdef -t group -l","lsdef -t osimage -l",
"nodels","lsdef -t node -l","rpower all stat","nodestat all",
"nodels all groups","monls -a","lsvm all","rinv all all",
"lsdef -t site -l", "lsdef -t group -l", "lsdef -t osimage -l",
"nodels", "lsdef -t node -l", "rpower all stat", "nodestat all",
"nodels all groups", "monls -a", "lsvm all", "rinv all all",
"rvitals all all");
foreach my $item (@Commands_array) {
$Command = $item;
@ -262,24 +263,29 @@ sub snap_it {
print "Retrieving xCAT database...\n";
$output_dir = "$logDirectory/xcat-database/";
make_output_dir();
# do not snap the ISNM tables, too big
my $cmd;
$cmd="XCAT_SKIPTABLES=isnm_perf,isnm_perf_dlink,isnm_perf_dlink_sum,isnm_perf_hfi,isnm_perf_hfi_sum,isnm_perf_isr,isnm_perf_isr_sum,isnm_perf_lllink,isnm_perf_lllink_sum,isnm_perf_lrlink,isnm_perf_lrlink_sum,isnm_perf_sum";
$cmd .= " dumpxCATdb -p $output_dir";
$cmd = "XCAT_SKIPTABLES=isnm_perf,isnm_perf_dlink,isnm_perf_dlink_sum,isnm_perf_hfi,isnm_perf_hfi_sum,isnm_perf_isr,isnm_perf_isr_sum,isnm_perf_lllink,isnm_perf_lllink_sum,isnm_perf_lrlink,isnm_perf_lrlink_sum,isnm_perf_sum";
$cmd .= " dumpxCATdb -p $output_dir";
`$cmd`;
# now get auditlog and eventlog, last two days
# get number of seconds in the day count
my $numberdays=2;
my $numbersecs=($numberdays * 86400);
# get number of seconds in the day count
my $numberdays = 2;
my $numbersecs = ($numberdays * 86400);
# get time now
my $timenow=time;
my $secsdaysago=$timenow - $numbersecs;
# Format like the database table timestamp record
my $timenow = time;
my $secsdaysago = $timenow - $numbersecs;
# Format like the database table timestamp record
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
localtime($secsdaysago);
my $daysago = sprintf("%04d-%02d-%02d %02d:%02d:%02d",
$year + 1900, $mon + 1, $mday,
$hour, $min, $sec);
localtime($secsdaysago);
my $daysago = sprintf("%04d-%02d-%02d %02d:%02d:%02d",
$year + 1900, $mon + 1, $mday,
$hour, $min, $sec);
# now tabdump days gt 2 days ago
$cmd = "tabdump -w \"audittime>$daysago\" auditlog > $output_dir/auditlog.csv";
@ -287,34 +293,34 @@ sub snap_it {
$cmd = "tabdump -w \"eventtime>$daysago\" eventlog > $output_dir/eventlog.csv";
`$cmd`;
print "xCAT database retrieved.\n";
}
`rm /tftpboot/tftpboot.list`; # remove temp list
}
`rm /tftpboot/tftpboot.list`; # remove temp list
}
##################### getHomeDirectory ###########################
# input userid output homedir
#####################################################################
sub getHomeDir
{
my @user;
my $homedir;
@user = getpwuid($>);
my $username=$user[0];
my @user;
my $homedir;
@user = getpwuid($>);
my $username = $user[0];
if ($user[7]) { # if homedir
$homedir= $user[7];
} else { # no home
$homedir=`su - $username -c pwd`;
chop $homedir;
}
return $homedir;
if ($user[7]) { # if homedir
$homedir = $user[7];
} else { # no home
$homedir = `su - $username -c pwd`;
chop $homedir;
}
return $homedir;
}
############################# Main Section ####################################
my $userid = `id -ru`; #Checking if the user is root
if ( $userid != 0 ) {
my $userid = `id -ru`; #Checking if the user is root
if ($userid != 0) {
print "You must be root to run the xcatsnap tool";
exit 1;
}
@ -325,68 +331,69 @@ if ( $userid != 0 ) {
if (
!GetOptions(
'd|dir=s' => \$::DIRECTORY,
'B|bypass' => \$::BYPASS,
'h|help' => \$::HELP,
'v|version' => \$::VERSION,
'd|dir=s' => \$::DIRECTORY,
'B|bypass' => \$::BYPASS,
'h|help' => \$::HELP,
'v|version' => \$::VERSION,
)
)
{
&usage;
exit(1);
}
if ($::HELP ) {
if ($::HELP) {
usage();
exit 0;
}
if ($::VERSION) {
my $version = xCAT::Utils->Version();
$version .= "\n";
xCAT::MsgUtils->message("N", $version);
exit 0;
my $version = xCAT::Utils->Version();
$version .= "\n";
xCAT::MsgUtils->message("N", $version);
exit 0;
exit 0;
}
if ($::BYPASS)
{
$ENV{XCATBYPASS} = "yes"; # bypass xcatd
$ENV{XCATBYPASS} = "yes"; # bypass xcatd
}
if (!($::DIRECTORY)) {
print " Log Directory will be /tmp/xcatsnap/\n";
}
else {
$logDirectory = $::DIRECTORY ;
else {
$logDirectory = $::DIRECTORY;
valid_dir();
}
unless ( -d $logDirectory ) { #Create the output directory if it doesn't exist
unless (-d $logDirectory) { #Create the output directory if it doesn't exist
`mkdir -p $logDirectory`;
if ($?!=0) {
print " Could not create $logDirectory\n";
exit 1;
}
if ($? != 0) {
print " Could not create $logDirectory\n";
exit 1;
}
valid_dir();
}
my $hostname;
chop( $OSname = `uname` );
chop( $hostname = `hostname -s` );
my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
chop($OSname = `uname`);
chop($hostname = `hostname -s`);
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
localtime(time);
$mon = $mon + 1;
my @date_array = ( $mon, $mday, $hour, $min );
my @date_array = ($mon, $mday, $hour, $min);
foreach my $item (@date_array) {
$item =
sprintf( "%2d", $item ); #Formatting the date for dispaly in file name
sprintf("%2d", $item); #Formatting the date for dispaly in file name
$item =~ tr/ /0/;
}
my $logdate = $date_array[0] . $date_array[1] . $date_array[2] . $date_array[3];
$LogFile = $logDirectory . "/xcatsnap." . $hostname . "." . $logdate . ".log";
$TarFile = $logDirectory . "/xcatsnap." . $hostname . "." . $logdate . ".tar";
open( STDOUT, "| tee $LogFile" );
open(STDOUT, "| tee $LogFile");
print "Time Stamp:" . `date`;
print "Log Directory: $logDirectory \n";
print "Preparation Complete...\n";
@ -401,32 +408,32 @@ print "Compiling Information...\n";
print "Information compiled...\n";
`chmod 400 $LogFile`; # Processing the log file
print "Send $LogFile to IBM Support.\n";
my $donotdelete=0;
if ( `which gunzip` == 0 ) { # Compressing the tar file
my $donotdelete = 0;
if (`which gunzip` == 0) { # Compressing the tar file
`gzip -f $TarFile`;
}
elsif ( `which compress` == 0 ) {
elsif (`which compress` == 0) {
`compress -f $TarFile`;
}
else {
print
"gzip and compress are not available. The tar file $TarFile will not be compressed";
$donotdelete=1;
$donotdelete = 1;
}
if (-e $TarFile && $donotdelete == 0){ # Don't remove if only file to send
if (-e $TarFile && $donotdelete == 0) { # Don't remove if only file to send
`rm $TarFile`;
}
if ( -e $TarFile . ".gz" ) {
if (-e $TarFile . ".gz") {
`chmod 400 $TarFile".gz"`;
print "Send $TarFile.gz to IBM Support.\n";
}
elsif ( -e $TarFile . ".z" ) {
elsif (-e $TarFile . ".z") {
`chmod 400 $TarFile".z"`;
print "Send $TarFile.z to IBM Support.\n";
}
elsif ( -e $TarFile ) {
elsif (-e $TarFile) {
`chmod 400 $TarFile`;
print "Send $TarFile to IBM Support.\n";
}

View File

@ -1,20 +1,21 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
use Fcntl qw(:DEFAULT :flock);
sub get_lock {
unless (flock(LOCKHANDLE,LOCK_EX|LOCK_NB)) {
unless (flock(LOCKHANDLE, LOCK_EX | LOCK_NB)) {
$| = 1;
print "Acquiring startup lock...";
flock(LOCKHANDLE,LOCK_EX) or die "Error trying to secure a startup lock";
flock(LOCKHANDLE, LOCK_EX) or die "Error trying to secure a startup lock";
print "done\n";
}
truncate(LOCKHANDLE,0);
print LOCKHANDLE $$."\n";
truncate(LOCKHANDLE, 0);
print LOCKHANDLE $$ . "\n";
}
sub release_lock {
truncate(LOCKHANDLE,0);
flock(LOCKHANDLE,LOCK_UN);
truncate(LOCKHANDLE, 0);
flock(LOCKHANDLE, LOCK_UN);
}
BEGIN
@ -25,17 +26,18 @@ BEGIN
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
umask 0077;
mkpath("/tmp/xcat/");
unless (sysopen(LOCKHANDLE,"/tmp/xcat/consolelock",O_WRONLY | O_CREAT)) {
unless (sysopen(LOCKHANDLE, "/tmp/xcat/consolelock", O_WRONLY | O_CREAT)) {
sleep 15;
print "Unable to open lock file";
exit 0;
}
get_lock();
#my $sleepint=int(rand(10)); #Stagger start to avoid overwhelming conserver/xCATd
#print "Opening console in ".(2+(0.5*$sleepint))." seconds...\n";
#sleep $sleepint;
}
my $sleepint=int(rand(10)); #Stagger start to avoid overwhelming conserver/xCATd
my $sleepint = int(rand(10)); #Stagger start to avoid overwhelming conserver/xCATd
use lib "$::XCATROOT/lib/perl";
require xCAT::Client;
@ -47,16 +49,17 @@ my $scriptname = $0;
#$mptab = xCAT::Table->new('mp');
#unless ($mptab) {
#sleep 5; #Try not to overwhelm logfiles...
#sleep 5; #Try not to overwhelm logfiles...
# die "mp table must be configured";
#}
#$mpatab = xCAT::Table->new('mpa');
#$passtab = xCAT::Table->new('passwd');
my $username = "USERID";
my $username = "USERID";
my $passsword = "PASSW0RD";
my $mm;
my $slot;
#my $dba;
#if ($passtab) {
# ($dba) = $passtab->getAttribs({key=>blade},qw(username password));
@ -81,41 +84,42 @@ my $slot;
#xCAT::Utils::close_all_dbhs;
#sleep 5; #Slow start, I know, but with exec, can't return
sub getans {
my $rsp = shift;
my $rsp = shift;
if ($rsp->{node}) {
$mm = $rsp->{node}->[0]->{mm}->[0];
$mm = $rsp->{node}->[0]->{mm}->[0];
$username = $rsp->{node}->[0]->{username}->[0];
$slot = $rsp->{node}->[0]->{slot}->[0];
$slot =~ s/-.*//; #remove range info if multi-wide blade
$slot = $rsp->{node}->[0]->{slot}->[0];
$slot =~ s/-.*//; #remove range info if multi-wide blade
}
}
my $cmdref={
command=>["getbladecons"],
arg=>["text"],
noderange=>[$ARGV[0]]
my $cmdref = {
command => ["getbladecons"],
arg => ["text"],
noderange => [ $ARGV[0] ]
};
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
until ($mm and $username and $slot) {
release_lock(); #Let other clients have a go
$sleepint=10+int(rand(20)); #Stagger to minimize lock collisions, but no big deal when it does happen
release_lock(); #Let other clients have a go
$sleepint = 10 + int(rand(20)); #Stagger to minimize lock collisions, but no big deal when it does happen
print "Console not ready, retrying in $sleepint seconds (Hit Ctrl-E,c,o to skip delay)\n";
sleep $sleepint;
get_lock();
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
}
release_lock(); #done with xcatd, can run with near impunity
my $solchkcmd = "ssh -t $username"."@"."$mm sol -T blade[$slot]";
release_lock(); #done with xcatd, can run with near impunity
my $solchkcmd = "ssh -t $username" . "@" . "$mm sol -T blade[$slot]";
my $solstatus = `$solchkcmd`;
while ($solstatus !~ /SOL Session: Ready/ and $solstatus !~ /SOL Session: Active/) {
$sleepint=60+int(rand(30)); #Stagger sleep to take it easy on AMM/hosting server
$sleepint = 60 + int(rand(30)); #Stagger sleep to take it easy on AMM/hosting server
print "SOL unavailable, retrying in $sleepint seconds (hit Ctrl-E,c,o to skip)\n";
sleep $sleepint;
$solstatus = `$solchkcmd`;
}
exec "ssh -t $username"."@"."$mm console -o -T blade[$slot]";
exec "ssh -t $username" . "@" . "$mm console -o -T blade[$slot]";
#my $pathtochild= dirname($scriptname). "/";
#exec $pathtochild."blade.expect $mm $slot $username $password";
#SECURITY: In this case, the authentication is expected to be done using the script user's ssh keys. As such,
#this script does not receive any particularly sensitive data from the xCAT server.

View File

@ -1,20 +1,21 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
use Fcntl qw(:DEFAULT :flock);
sub get_lock {
unless (flock(LOCKHANDLE,LOCK_EX|LOCK_NB)) {
unless (flock(LOCKHANDLE, LOCK_EX | LOCK_NB)) {
$| = 1;
print "Acquiring startup lock...";
flock(LOCKHANDLE,LOCK_EX) or die "Error trying to secure a startup lock";
flock(LOCKHANDLE, LOCK_EX) or die "Error trying to secure a startup lock";
print "done\n";
}
truncate(LOCKHANDLE,0);
print LOCKHANDLE $$."\n";
truncate(LOCKHANDLE, 0);
print LOCKHANDLE $$ . "\n";
}
sub release_lock {
truncate(LOCKHANDLE,0);
flock(LOCKHANDLE,LOCK_UN);
truncate(LOCKHANDLE, 0);
flock(LOCKHANDLE, LOCK_UN);
}
BEGIN
@ -25,25 +26,28 @@ BEGIN
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
umask 0077;
mkpath("/tmp/xcat/");
unless (sysopen(LOCKHANDLE,"/tmp/xcat/consolelock",O_WRONLY | O_CREAT)) {
unless (sysopen(LOCKHANDLE, "/tmp/xcat/consolelock", O_WRONLY | O_CREAT)) {
sleep 15;
print "Unable to open lock file";
exit 0;
}
get_lock();
#my $sleepint=int(rand(10)); #Stagger start to avoid overwhelming conserver/xCATd
#print "Opening console in ".(2+(0.5*$sleepint))." seconds...\n";
#sleep $sleepint;
}
my $sleepint=int(rand(10));
my $sleepint = int(rand(10));
use lib "$::XCATROOT/lib/perl";
require xCAT::Client;
require xCAT::Utils;
use strict;
#use Getopt::Long;
#use xCAT::Table;
#use xCAT::PPCdb;
use Expect;
#use xCAT::DBobjUtils;
#use Data::Dumper;
require File::Basename;
@ -89,7 +93,7 @@ my $hwtype;
# if ( defined( $_[0] )) {
# print STDERR "$_[0]\n";
# }
# my @msg = (
# my @msg = (
# "$cmd -h|--help\n",
# "$cmd -v|--version\n",
# "$cmd singlenode [-V|-Verbose]\n" );
@ -162,12 +166,12 @@ my $hwtype;
##########################################################################
# Open remote console
# Open remote console
##########################################################################
sub invoke_cmd {
my $node = shift;
my $fsp_ip = shift;
my $id = shift;
my $node = shift;
my $fsp_ip = shift;
my $id = shift;
my $hwtype = shift;
my $machine;
if ($hwtype eq 'blade') {
@ -190,7 +194,7 @@ sub invoke_cmd {
# }
#}
##################################
# Get node power type
# Get node power type
##################################
#my $hwtype = __FILE__;
#$hwtype =~ s/.*([\w]{3})$/$1/;
@ -236,24 +240,26 @@ sub invoke_cmd {
#
#my $fsp_name = $att->{hcp};
#my $id = $att->{id};
#use xcatd to get the attribute $fsp_name and $id of the node.
#use xcatd to get the attribute $fsp_name and $id of the node.
#my $fsp_api ="/opt/xcat/sbin/fsp-api";
my $fsp_api = ($::XCATROOT) ? "$::XCATROOT/sbin/fsp-api" : "/opt/xcat/sbin/fsp-api";
my $fsp_api = ($::XCATROOT) ? "$::XCATROOT/sbin/fsp-api" : "/opt/xcat/sbin/fsp-api";
my $action = "console";
my $type = "0";
my $type = "0";
#my $fsp_ip = ();
my $Rc = 0;
#$fsp_ip = xCAT::NetworkUtils::getNodeIPaddress( $fsp_name );
#if(!defined($fsp_ip)) {
# return "Failed to get the $fsp_name\'s ip";
#}
my $power_state_cmd = "$fsp_api -a cec_state -t $type:$fsp_ip:$id:$node: 2>&1";
my $power_state_cmd = "$fsp_api -a cec_state -t $type:$fsp_ip:$id:$node: 2>&1";
my $res;
my $index = 0;
my $index = 0;
my $pre_state = undef;
#my $wait_interval =20;
my $ipl_num = 0;
while (1) {
@ -292,13 +298,14 @@ sub invoke_cmd {
}
} elsif ($res =~ /(IPL-in-process)$/) {
if (!$pre_state) {
$pre_state =$1;
$pre_state = $1;
sleep 10;
next;
} elsif ($pre_state and ($pre_state eq $1) and !$index) {
print "\nDestination $machine is POWERING ON, please wait.";
$index++;
} else {
#print "\r\n====>pre_state=$pre_state\n";
$ipl_num++;
$pre_state = $1;
@ -310,115 +317,118 @@ sub invoke_cmd {
sleep 5;
} else {
$pre_state = $res;
#print ".";
sleep 20;
}
#$wait_interval =20+int(rand(20));
#sleep $wait_interval;
}
my $cmd = "$fsp_api -a $action -t $type:$fsp_ip:$id:$node:\r";
#print "cmd: $cmd\n";
my $running_failed_code = "Reason code: 0x1000000";
my $fsp_standby_msg = "Reason code: 0x1300";
my $fsp_lock_msg = "Reason code: 0x1f00";
my $timeout = 30;
my $failed = 0;
my $exp = new Expect;
$exp->log_stdout( 1 );
$exp->spawn( $cmd ) or die "Can't spawn $cmd\r\n";
my @result = $exp->expect( $timeout,
[ "$running_failed_code",
sub {
$failed = 1;
} ],
[ "$fsp_standby_msg",
sub {
$failed = 2;
}],
["$fsp_lock_msg",
sub {
$failed = 3;
}]
);
if($failed == 1) {
$exp->hard_close();
return("Virtual terminal is already connected");
}
if($failed == 2) {
$exp->hard_close();
return("Failed to open the console. Please check the related FSP's status");
}
if ($failed == 3) {
my $link_cmd = "$fsp_api -a fsp_reconnect -t $type:$fsp_ip:$id:$node: 2>&1";
xCAT::Utils->runcmd($link_cmd, -1);
print "The connection is resetting, please wait.";
my $link_state = "";
my $rs_num = 0;
while (!$link_state or $link_state !~ /state=LINE UP/i) {
sleep 2;
$rs_num++;
$link_cmd = "$fsp_api -a query_connection -t $type:$fsp_ip:$id:$node: 2>&1";
$link_state = xCAT::Utils->runcmd($link_cmd, -1);
if ($rs_num == 5) {
print ".";
$rs_num = 0;
}
}
print "\n";
$exp->hard_close();
return (0);
}
my $fsp_standby_msg = "Reason code: 0x1300";
my $fsp_lock_msg = "Reason code: 0x1f00";
my $timeout = 30;
my $failed = 0;
my $exp = new Expect;
$exp->log_stdout(1);
$exp->spawn($cmd) or die "Can't spawn $cmd\r\n";
my @result = $exp->expect($timeout,
[ "$running_failed_code",
sub {
$failed = 1;
} ],
[ "$fsp_standby_msg",
sub {
$failed = 2;
} ],
[ "$fsp_lock_msg",
sub {
$failed = 3;
} ]
);
if ($failed == 1) {
$exp->hard_close();
return ("Virtual terminal is already connected");
}
if ($failed == 2) {
$exp->hard_close();
return ("Failed to open the console. Please check the related FSP's status");
}
if ($failed == 3) {
my $link_cmd = "$fsp_api -a fsp_reconnect -t $type:$fsp_ip:$id:$node: 2>&1";
xCAT::Utils->runcmd($link_cmd, -1);
print "The connection is resetting, please wait.";
my $link_state = "";
my $rs_num = 0;
while (!$link_state or $link_state !~ /state=LINE UP/i) {
sleep 2;
$rs_num++;
$link_cmd = "$fsp_api -a query_connection -t $type:$fsp_ip:$id:$node: 2>&1";
$link_state = xCAT::Utils->runcmd($link_cmd, -1);
if ($rs_num == 5) {
print ".";
$rs_num = 0;
}
}
print "\n";
$exp->hard_close();
return (0);
}
my $escape = "\030";
$exp->send( "\r" );
$exp->interact( \*STDIN, $escape );
$exp->hard_close();
return(0);
$exp->send("\r");
$exp->interact(\*STDIN, $escape);
$exp->hard_close();
return (0);
}
##############################################
# Start main body of code
# Start main body of code
##############################################
#if ( parse_args() ) {
# exit(1);
#}
sub getans {
my $rsp = shift;
my $rsp = shift;
if ($rsp->{node}) {
$ips = $rsp->{node}->[0]->{fsp_ip}->[0];
$id = $rsp->{node}->[0]->{id}->[0];
$ips = $rsp->{node}->[0]->{fsp_ip}->[0];
$id = $rsp->{node}->[0]->{id}->[0];
$hwtype = $rsp->{node}->[0]->{type}->[0];
}
}
my $cmdref={
command=>["getfspcon"],
arg=>["text"],
noderange=>[$ARGV[0]]
my $cmdref = {
command => ["getfspcon"],
arg => ["text"],
noderange => [ $ARGV[0] ]
};
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
until ($ips and $id) {
release_lock(); #Let other clients have a go
$sleepint=10+int(rand(20)); #Stagger to minimize lock collisions, but no big deal when it does happen
release_lock(); #Let other clients have a go
$sleepint = 10 + int(rand(20)); #Stagger to minimize lock collisions, but no big deal when it does happen
print "Console not ready, retrying in $sleepint seconds (Hit Ctrl-E,c,o to skip delay)\n";
sleep $sleepint;
get_lock();
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
}
release_lock(); #done with xcatd, can run with near impunity
release_lock(); #done with xcatd, can run with near impunity
$node = $ARGV[0];
my $result = invoke_cmd($node, $ips, $id, $hwtype);
if ( $result ne "0" ) {
if ($result ne "0") {
print STDERR "$node: $result\n";
exit(1);
}

View File

@ -1,21 +1,23 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
use Fcntl qw(:DEFAULT :flock);
sub get_lock {
unless (flock(LOCKHANDLE,LOCK_EX|LOCK_NB)) {
unless (flock(LOCKHANDLE, LOCK_EX | LOCK_NB)) {
$| = 1;
print "Acquiring startup lock...";
flock(LOCKHANDLE,LOCK_EX) or die "Error trying to secure a startup lock";
flock(LOCKHANDLE, LOCK_EX) or die "Error trying to secure a startup lock";
print "done\n";
}
truncate(LOCKHANDLE,0);
print LOCKHANDLE $$."\n";
truncate(LOCKHANDLE, 0);
print LOCKHANDLE $$ . "\n";
}
sub release_lock {
truncate(LOCKHANDLE,0);
flock(LOCKHANDLE,LOCK_UN);
truncate(LOCKHANDLE, 0);
flock(LOCKHANDLE, LOCK_UN);
}
BEGIN
{
use Time::HiRes qw(sleep);
@ -24,20 +26,22 @@ BEGIN
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
umask 0077;
mkpath("/tmp/xcat/");
unless (sysopen(LOCKHANDLE,"/tmp/xcat/consolelock",O_WRONLY | O_CREAT)) {
unless (sysopen(LOCKHANDLE, "/tmp/xcat/consolelock", O_WRONLY | O_CREAT)) {
sleep 15;
print "Unable to open lock file";
exit 0;
}
get_lock();
#my $sleepint=int(rand(10)); #Stagger start to avoid overwhelming conserver/xCATd
#print "Opening console in ".(2+(0.5*$sleepint))." seconds...\n";
#sleep $sleepint;
}
my $sleepint=int(rand(10));
my $sleepint = int(rand(10));
use lib "$::XCATROOT/lib/perl";
require xCAT::Client;
use strict;
#use Getopt::Long;
#use xCAT::Table;
#use xCAT::PPCdb;
@ -88,7 +92,7 @@ my $credencial;
# if ( defined( $_[0] )) {
# print STDERR "$_[0]\n";
# }
# my @msg = (
# my @msg = (
# "$cmd -h|--help\n",
# "$cmd -v|--version\n",
# "$cmd singlenode [-V|-Verbose]\n" );
@ -161,7 +165,7 @@ my $credencial;
##########################################################################
# Open remote console
# Open remote console
##########################################################################
sub invoke_cmd {
@ -179,7 +183,7 @@ sub invoke_cmd {
# }
#}
###################################
## Get node power type
## Get node power type
###################################
#my $hwtype = __FILE__;
#$hwtype =~ s/.*([\w]{3})$/$1/;
@ -243,15 +247,15 @@ sub invoke_cmd {
#my $host = $att->{hcp};
#my $lparid = $att->{id};
#$type = "lpar";
my $type = "lpar";
my $hwtype = "hmc";
my $type = "lpar";
my $hwtype = "hmc";
my %request = (
ppcretry => 1,
verbose => $verbose
);
#################################
# Get userid and password
# Get userid and password
#################################
#my @cred = xCAT::PPCdb::credentials( $host, $hwtype );
@cred = split(/,/, $credencial);
@ -259,57 +263,57 @@ sub invoke_cmd {
#################################
# Connect to the remote server
#################################
my @exp = xCAT::PPCcli::connect( \%request, $hwtype, $host );
if ( ref($exp[0]) ne "Expect" ) {
return( $exp[0] );
my @exp = xCAT::PPCcli::connect(\%request, $hwtype, $host);
if (ref($exp[0]) ne "Expect") {
return ($exp[0]);
}
#################################
# Open console connection
# Open console connection
#################################
my $result = xCAT::PPCcli::mkvterm( \@exp, $type, $lparid, $mtms );
my $result = xCAT::PPCcli::mkvterm(\@exp, $type, $lparid, $mtms);
my $Rc = shift(@$result);
if ( $Rc != SUCCESS ) {
return( @$result[0] );
if ($Rc != SUCCESS) {
return (@$result[0]);
}
return(0);
return (0);
}
##############################################
# Start main body of code
# Start main body of code
##############################################
#if ( parse_args() ) {
# exit(1);
#}
sub getans {
my $rsp = shift;
my $rsp = shift;
if ($rsp->{node}) {
$host = $rsp->{node}->[0]->{host}->[0];
$lparid = $rsp->{node}->[0]->{lparid}->[0];
$mtms = $rsp->{node}->[0]->{mtms}->[0];
$credencial = $rsp->{node}->[0]->{cred}->[0];
$host = $rsp->{node}->[0]->{host}->[0];
$lparid = $rsp->{node}->[0]->{lparid}->[0];
$mtms = $rsp->{node}->[0]->{mtms}->[0];
$credencial = $rsp->{node}->[0]->{cred}->[0];
}
}
my $cmdref={
command=>["gethmccon"],
arg=>["text"],
noderange=>[$ARGV[0]]
my $cmdref = {
command => ["gethmccon"],
arg => ["text"],
noderange => [ $ARGV[0] ]
};
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
until ($lparid and $host and $mtms) {
release_lock(); #Let other clients have a go
$sleepint=10+int(rand(20)); #Stagger to minimize lock collisions, but no big deal when it does happen
release_lock(); #Let other clients have a go
$sleepint = 10 + int(rand(20)); #Stagger to minimize lock collisions, but no big deal when it does happen
print "Console not ready, retrying in $sleepint seconds (Hit Ctrl-E,c,o to skip delay)\n";
sleep $sleepint;
get_lock();
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
}
release_lock(); #done with xcatd, can run with near impunity
release_lock(); #done with xcatd, can run with near impunity
$node = $ARGV[0];
my $result = invoke_cmd($host, $lparid, $mtms);
if ( $result ne "0" ) {
if ($result ne "0") {
print STDERR "$node: $result\n";
exit(1);
}

View File

@ -1,5 +1,5 @@
#!/usr/bin/env perl
#
#
# © Copyright 2009 Hewlett-Packard Development Company, L.P.
# EPL license http://www.eclipse.org/legal/epl-v10.html
#
@ -7,20 +7,21 @@
# August, 2009 blade adapted to generate hpblade
#
use Fcntl qw(:DEFAULT :flock);
sub get_lock {
unless (flock(LOCKHANDLE,LOCK_EX|LOCK_NB)) {
unless (flock(LOCKHANDLE, LOCK_EX | LOCK_NB)) {
$| = 1;
print "Acquiring startup lock...";
flock(LOCKHANDLE,LOCK_EX) or die "Error trying to secure a startup lock";
flock(LOCKHANDLE, LOCK_EX) or die "Error trying to secure a startup lock";
print "done\n";
}
truncate(LOCKHANDLE,0);
print LOCKHANDLE $$."\n";
truncate(LOCKHANDLE, 0);
print LOCKHANDLE $$ . "\n";
}
sub release_lock {
truncate(LOCKHANDLE,0);
flock(LOCKHANDLE,LOCK_UN);
truncate(LOCKHANDLE, 0);
flock(LOCKHANDLE, LOCK_UN);
}
BEGIN
@ -31,19 +32,20 @@ BEGIN
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
umask 0077;
mkpath("/tmp/xcat/");
unless (sysopen(LOCKHANDLE,"/tmp/xcat/consolelock",O_WRONLY | O_CREAT)) {
unless (sysopen(LOCKHANDLE, "/tmp/xcat/consolelock", O_WRONLY | O_CREAT)) {
sleep 15;
print "Unable to open lock file";
exit 0;
}
get_lock();
#my $sleepint=int(rand(10)); #Stagger start to avoid overwhelming conserver/xCATd
#print "Opening console in ".(2+(0.5*$sleepint))." seconds...\n";
#sleep $sleepint;
}
my $sleepint=int(rand(10)); #Stagger start to avoid overwhelming conserver/xCATd
my $sleepint = int(rand(10)); #Stagger start to avoid overwhelming conserver/xCATd
use lib "$::XCATROOT/lib/perl";
$ENV{HOME}='/root/';
$ENV{HOME} = '/root/';
require xCAT::Client;
require File::Basename;
@ -52,16 +54,17 @@ my $scriptname = $0;
#$mptab = xCAT::Table->new('mp');
#unless ($mptab) {
#sleep 5; #Try not to overwhelm logfiles...
#sleep 5; #Try not to overwhelm logfiles...
# die "mp table must be configured";
#}
#$mpatab = xCAT::Table->new('mpa');
#$passtab = xCAT::Table->new('passwd');
my $username = "admin";
my $username = "admin";
my $passsword = "PASSW0RD";
my $mm;
my $slot;
#my $dba;
#if ($passtab) {
# ($dba) = $passtab->getAttribs({key=>blade},qw(username password));
@ -86,33 +89,34 @@ my $slot;
#xCAT::Utils::close_all_dbhs;
#sleep 5; #Slow start, I know, but with exec, can't return
sub getans {
my $rsp = shift;
my $rsp = shift;
if ($rsp->{node}) {
$mm = $rsp->{node}->[0]->{mm}->[0];
$mm = $rsp->{node}->[0]->{mm}->[0];
$username = $rsp->{node}->[0]->{username}->[0];
$slot = $rsp->{node}->[0]->{slot}->[0];
$slot = $rsp->{node}->[0]->{slot}->[0];
}
}
my $cmdref={
command=>"gethpbladecons",
arg=>"text",
noderange=>$ARGV[0]
my $cmdref = {
command => "gethpbladecons",
arg => "text",
noderange => $ARGV[0]
};
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
until ($mm and $username and $slot) {
release_lock(); #Let other clients have a go
$sleepint=10+int(rand(20)); #Stagger to minimize lock collisions, but no big deal when it does happen
release_lock(); #Let other clients have a go
$sleepint = 10 + int(rand(20)); #Stagger to minimize lock collisions, but no big deal when it does happen
print "Console not ready, retrying in $sleepint seconds (Hit Ctrl-E,c,o to skip delay)\n";
sleep $sleepint;
get_lock();
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
}
release_lock(); #done with xcatd, can run with near impunity
$sleepint=10+int(rand(30)); #Stagger sleep to take it easy on AMM/hosting server
exec "ssh -t $username"."@"."$mm vsp";
my $pathtochild= dirname($scriptname). "/";
release_lock(); #done with xcatd, can run with near impunity
$sleepint = 10 + int(rand(30)); #Stagger sleep to take it easy on AMM/hosting server
exec "ssh -t $username" . "@" . "$mm vsp";
my $pathtochild = dirname($scriptname) . "/";
#exec $pathtochild."hpblade.expect";
#SECURITY: In this case, the authentication is expected to be done using the script user's ssh keys. As such,
#this script does not receive any particularly sensitive data from the xCAT server.

View File

@ -1,21 +1,23 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
use Fcntl qw(:DEFAULT :flock);
sub get_lock {
unless (flock(LOCKHANDLE,LOCK_EX|LOCK_NB)) {
unless (flock(LOCKHANDLE, LOCK_EX | LOCK_NB)) {
$| = 1;
print "Acquiring startup lock...";
flock(LOCKHANDLE,LOCK_EX) or die "Fatal Error securing startup lock";
flock(LOCKHANDLE, LOCK_EX) or die "Fatal Error securing startup lock";
print "done\n";
}
truncate(LOCKHANDLE,0);
print LOCKHANDLE $$."\n";
truncate(LOCKHANDLE, 0);
print LOCKHANDLE $$ . "\n";
}
sub release_lock {
truncate(LOCKHANDLE,0);
flock(LOCKHANDLE,LOCK_UN);
truncate(LOCKHANDLE, 0);
flock(LOCKHANDLE, LOCK_UN);
}
BEGIN
{
use Time::HiRes qw(sleep);
@ -24,53 +26,55 @@ BEGIN
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
umask 0077;
mkpath("/tmp/xcat/");
unless (sysopen(LOCKHANDLE,"/tmp/xcat/consolelock",O_WRONLY | O_CREAT)) {
unless (sysopen(LOCKHANDLE, "/tmp/xcat/consolelock", O_WRONLY | O_CREAT)) {
print "Unable to open lock file";
exec("sleep 15");
exit 0;
}
get_lock();
#my $sleepint=int(rand(10));
#print "Opening console in ".(2+(0.5*$sleepint))." seconds...\n";
#sleep $sleepint;
}
my $sleepint=int(rand(10)); #Stagger start to avoid overwhelming conserver/xCATd
my $sleepint = int(rand(10)); #Stagger start to avoid overwhelming conserver/xCATd
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
use lib "$::XCATROOT/lib/perl";
require xCAT::Client;
my $username = 'USERID';
my $password = 'PASSW0RD';
my $node = $ARGV[0];
my $node = $ARGV[0];
my $bmc;
sub getans {
my $rsp = shift;
my $rsp = shift;
if ($rsp->{node}) {
$bmc = $rsp->{node}->[0]->{bmcaddr}->[0];
$bmc = $rsp->{node}->[0]->{bmcaddr}->[0];
$username = $rsp->{node}->[0]->{bmcuser}->[0];
$password = $rsp->{node}->[0]->{bmcpass}->[0];
if (exists $rsp->{node}->[0]->{error}) {
my $error = $rsp->{node}->[0]->{error}->[0];
print $error."\n";
my $error = $rsp->{node}->[0]->{error}->[0];
print $error. "\n";
}
}
}
my $cmdref={
command=>["getipmicons"],
arg=>["text"],
noderange=>[$ARGV[0]]
my $cmdref = {
command => ["getipmicons"],
arg => ["text"],
noderange => [ $ARGV[0] ]
};
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
until (($username or $password) and $bmc) {
release_lock(); #Let other clients have a go
$sleepint=10+int(rand(20));
release_lock(); #Let other clients have a go
$sleepint = 10 + int(rand(20));
print "Console not ready, retrying in $sleepint seconds (Ctrl-e,c,o to skip delay) \n";
exec("sleep $sleepint");
get_lock();
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
}
release_lock();
my ($user,$pass);
my ($user, $pass);
if ($username) {
$user = "-U '$username'";
} else {
@ -81,6 +85,7 @@ if ($password) {
} else {
$pass = '';
}
#require xCAT::Table;
#require xCAT::Utils;
#my $dba;
@ -103,48 +108,49 @@ if ($password) {
#}
#xCAT::Utils::close_all_dbhs;
#my $isintel = system "ipmitool -I lanplus -U $username -P $password -H $bmc chassis status > /dev/null 2>&1";
my $isintel=0;
my $isintel = 0;
my $sleepint;
my $rc;
my $ipmitool = "ipmitool";
if (-x "$XCATROOT/bin/ipmitool-xcat") {
$ipmitool = "$XCATROOT/bin/ipmitool-xcat";
}
my @mcinfo=`$ipmitool -I lanplus $user $pass -H $bmc mc info`;#| grep 'Manufacturer ID : 343' > /dev/null 2>&1";
my @mcinfo = `$ipmitool -I lanplus $user $pass -H $bmc mc info`; #| grep 'Manufacturer ID : 343' > /dev/null 2>&1";
$rc = $?;
if ($rc) { #some shoddy vendors ignore the IPMI 2.0 requirement to support IPMI 1.5 formats for BMC capability determination, attempt IPMI 2.0 even without the ability to confirm IPMI 2.0 support. Though SOL was not baked in prior IPMI 2.0, this script supports pre-2.0 'ISOL' on older devices, hence why we are checking for 1.5/2.0 before proceeding normally
@mcinfo=`$ipmitool -I lan $user $pass -H $bmc mc info`;
$rc = $?;
@mcinfo = `$ipmitool -I lan $user $pass -H $bmc mc info`;
$rc = $?;
}
while ($rc != 0) {
$sleepint = 10+int(rand(20));
print "Failure to reach IPMI device, retrying in $sleepint seconds (Hit Ctrl-E,c,o to skip)\n";
exec("sleep $sleepint");
#sleep $sleepint;
@mcinfo=`$ipmitool -I lanplus $user $pass -H $bmc mc info`;#| grep 'Manufacturer ID : 343' > /dev/null 2>&1";
$rc = $?;
if ($rc) { #repeat workaround for shoddy vendors
@mcinfo=`$ipmitool -I lan $user $pass -H $bmc mc info`;
$rc = $?;
$sleepint = 10 + int(rand(20));
print "Failure to reach IPMI device, retrying in $sleepint seconds (Hit Ctrl-E,c,o to skip)\n";
exec("sleep $sleepint");
#sleep $sleepint;
@mcinfo = `$ipmitool -I lanplus $user $pass -H $bmc mc info`; #| grep 'Manufacturer ID : 343' > /dev/null 2>&1";
$rc = $?;
if ($rc) { #repeat workaround for shoddy vendors
@mcinfo = `$ipmitool -I lan $user $pass -H $bmc mc info`;
$rc = $?;
}
}
my $solcom="sol";
my $iface="lanplus";
if (grep /IPMI Version : 1.5/,@mcinfo) {
$solcom="isol";
$iface="lan";
} elsif (grep /Manufacturer ID : 343/,@mcinfo) {
$isintel=1;
my $solcom = "sol";
my $iface = "lanplus";
if (grep /IPMI Version : 1.5/, @mcinfo) {
$solcom = "isol";
$iface = "lan";
} elsif (grep /Manufacturer ID : 343/, @mcinfo) {
$isintel = 1;
}
my $inteloption="";
my $inteloption = "";
if ($isintel) {
$inteloption=" -o intelplus";
$inteloption = " -o intelplus";
}
if ($iface eq "lanplus") {
system "$ipmitool -I lanplus $inteloption $user $pass -H $bmc $solcom deactivate"; #Stop any active session
}
exec "$ipmitool -I $iface $inteloption $user $pass -H $bmc $solcom activate";

View File

@ -2,21 +2,23 @@
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
use Fcntl qw(:DEFAULT :flock);
use strict;
sub get_lock {
unless (flock(LOCKHANDLE,LOCK_EX|LOCK_NB)) {
unless (flock(LOCKHANDLE, LOCK_EX | LOCK_NB)) {
$| = 1;
print "Acquiring startup lock...";
flock(LOCKHANDLE,LOCK_EX) or die "Error trying to secure a startup lock";
flock(LOCKHANDLE, LOCK_EX) or die "Error trying to secure a startup lock";
print "done\n";
}
truncate(LOCKHANDLE,0);
print LOCKHANDLE $$."\n";
truncate(LOCKHANDLE, 0);
print LOCKHANDLE $$ . "\n";
}
sub release_lock {
truncate(LOCKHANDLE,0);
flock(LOCKHANDLE,LOCK_UN);
truncate(LOCKHANDLE, 0);
flock(LOCKHANDLE, LOCK_UN);
}
BEGIN
{
use Time::HiRes qw(sleep);
@ -25,20 +27,21 @@ BEGIN
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
umask 0077;
mkpath("/tmp/xcat/");
unless (sysopen(LOCKHANDLE,"/tmp/xcat/consolelock",O_WRONLY | O_CREAT)) {
unless (sysopen(LOCKHANDLE, "/tmp/xcat/consolelock", O_WRONLY | O_CREAT)) {
sleep 15;
print "Unable to open lock file";
exit 0;
}
get_lock();
my $sleepint=int(rand(10)); #Stagger start to avoid overwhelming conserver/xCATd
print "Opening console in ".(2+(0.5*$sleepint))." seconds...\n";
my $sleepint = int(rand(10)); #Stagger start to avoid overwhelming conserver/xCATd
print "Opening console in " . (2 + (0.5 * $sleepint)) . " seconds...\n";
sleep $sleepint;
}
my $sleepint=int(rand(10));
my $sleepint = int(rand(10));
use lib "$::XCATROOT/lib/perl";
require xCAT::Client;
use strict;
#use Getopt::Long;
#use xCAT::Table;
#use xCAT::PPCdb;
@ -89,7 +92,7 @@ my $credencial;
# if ( defined( $_[0] )) {
# print STDERR "$_[0]\n";
# }
# my @msg = (
# my @msg = (
# "$cmd -h|--help\n",
# "$cmd -v|--version\n",
# "$cmd singlenode [-V|-Verbose]\n" );
@ -162,7 +165,7 @@ my $credencial;
##########################################################################
# Open remote console
# Open remote console
##########################################################################
sub invoke_cmd {
@ -180,7 +183,7 @@ sub invoke_cmd {
# }
#}
###################################
## Get node power type
## Get node power type
###################################
#my $hwtype = __FILE__;
#$hwtype =~ s/.*([\w]{3})$/$1/;
@ -244,15 +247,15 @@ sub invoke_cmd {
#my $host = $att->{hcp};
#my $lparid = $att->{id};
#$type = "lpar";
my $type = "lpar";
my $hwtype = "ivm";
my $type = "lpar";
my $hwtype = "ivm";
my %request = (
ppcretry => 1,
verbose => $verbose
);
#################################
# Get userid and password
# Get userid and password
#################################
#my @cred = xCAT::PPCdb::credentials( $host, $hwtype );
@cred = split(/,/, $credencial);
@ -260,61 +263,61 @@ sub invoke_cmd {
#################################
# Connect to the remote server
#################################
my @exp = xCAT::PPCcli::connect( \%request, $hwtype, $host );
if ( ref($exp[0]) ne "Expect" ) {
return( $exp[0] );
my @exp = xCAT::PPCcli::connect(\%request, $hwtype, $host);
if (ref($exp[0]) ne "Expect") {
return ($exp[0]);
}
#################################
# Open console connection
# Open console connection
#################################
my $result = xCAT::PPCcli::mkvterm( \@exp, $type, $lparid, $mtms );
my $result = xCAT::PPCcli::mkvterm(\@exp, $type, $lparid, $mtms);
my $Rc = shift(@$result);
if ( $Rc != SUCCESS ) {
return( @$result[0] );
if ($Rc != SUCCESS) {
return (@$result[0]);
}
return(0);
return (0);
}
##############################################
# Start main body of code
# Start main body of code
##############################################
#if ( parse_args() ) {
# exit(1);
#}
sub getans {
my $rsp = shift;
my $rsp = shift;
if ($rsp->{node}) {
$host = $rsp->{node}->[0]->{host}->[0];
$lparid = $rsp->{node}->[0]->{lparid}->[0];
$mtms = $rsp->{node}->[0]->{mtms}->[0];
$credencial = $rsp->{node}->[0]->{cred}->[0];
$host = $rsp->{node}->[0]->{host}->[0];
$lparid = $rsp->{node}->[0]->{lparid}->[0];
$mtms = $rsp->{node}->[0]->{mtms}->[0];
$credencial = $rsp->{node}->[0]->{cred}->[0];
}
}
my $cmdref={
command=>["gethmccon"],
arg=>["text"],
noderange=>[$ARGV[0]]
my $cmdref = {
command => ["gethmccon"],
arg => ["text"],
noderange => [ $ARGV[0] ]
};
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
until ($lparid and $host and $mtms) {
release_lock(); #Let other clients have a go
$sleepint=10+int(rand(20)); #Stagger to minimize lock collisions, but no big deal when it does happen
release_lock(); #Let other clients have a go
$sleepint = 10 + int(rand(20)); #Stagger to minimize lock collisions, but no big deal when it does happen
print "Console not ready, retrying in $sleepint seconds (Hit Ctrl-E,c,o to skip delay)\n";
sleep $sleepint;
get_lock();
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
}
release_lock(); #done with xcatd, can run with near impunity
release_lock(); #done with xcatd, can run with near impunity
$node = $ARGV[0];
my $result = invoke_cmd($host, $lparid, $mtms);
if ( $result ne "0" ) {
if ($result ne "0") {
print STDERR "$node: $result\n";
exit(1);
}

View File

@ -1,21 +1,23 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
use Fcntl qw(:DEFAULT :flock);
sub get_lock {
unless (flock(LOCKHANDLE,LOCK_EX|LOCK_NB)) {
unless (flock(LOCKHANDLE, LOCK_EX | LOCK_NB)) {
$| = 1;
print "Acquiring startup lock...";
flock(LOCKHANDLE,LOCK_EX) or die "Fatal error securing startup lock";
flock(LOCKHANDLE, LOCK_EX) or die "Fatal error securing startup lock";
print "done\n";
}
truncate(LOCKHANDLE,0);
print LOCKHANDLE $$."\n";
truncate(LOCKHANDLE, 0);
print LOCKHANDLE $$ . "\n";
}
sub release_lock {
truncate(LOCKHANDLE,0);
flock(LOCKHANDLE,LOCK_UN);
truncate(LOCKHANDLE, 0);
flock(LOCKHANDLE, LOCK_UN);
}
BEGIN
{
use Time::HiRes qw(sleep);
@ -24,16 +26,18 @@ BEGIN
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
umask 0077;
mkpath("/tmp/xcat/");
unless (sysopen(LOCKHANDLE,"/tmp/xcat/consolelock",O_WRONLY | O_CREAT)) {
unless (sysopen(LOCKHANDLE, "/tmp/xcat/consolelock", O_WRONLY | O_CREAT)) {
sleep 15;
print "Unable to open lock file";
exit 0;
}
get_lock();
#my $sleepint=int(rand(10));
#print "Opening console in ".(2+(0.5*$sleepint))." seconds...\n";
#sleep $sleepint;
}
#BEGIN
#{
# use Time::HiRes qw(sleep);
@ -50,43 +54,45 @@ require File::Basename;
import File::Basename;
my $scriptname = $0;
my $cmdref={
command=>["getcons"],
arg=>["text"],
noderange=>[$ARGV[0]]
my $cmdref = {
command => ["getcons"],
arg => ["text"],
noderange => [ $ARGV[0] ]
};
use Data::Dumper;
my $dsthost;
my $dstty;
my $speed;
sub getans {
my $rsp = shift;
my $rsp = shift;
if ($rsp->{node}) {
$dsthost = $rsp->{node}->[0]->{sshhost}->[0];
$dstty = $rsp->{node}->[0]->{psuedotty}->[0];
$speed = $rsp->{node}->[0]->{baudrate}->[0];
$dstty = $rsp->{node}->[0]->{psuedotty}->[0];
$speed = $rsp->{node}->[0]->{baudrate}->[0];
}
}
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
until ($dsthost and $speed and $dstty) {
release_lock();
$sleepint=int(rand(30))+60;
$sleepint = int(rand(30)) + 60;
print "Console not ready, retrying in $sleepint seconds (Ctrl-C to skip delay)\n";
exec "sleep $sleepint";
}
release_lock();
# The screen command needs the TERM env var,
# TERM might be empty for some unknown reasons,
# for example, on SLES 12 and on PowerKVM
if (!$ENV{'TERM'}) {
$ENV{'TERM'}="vt100";
$ENV{'TERM'} = "vt100";
}
exec "ssh -t $dsthost screen -U -a -O -e ^]a -d -R -S serial-".$ARGV[0]."-cons -A $dstty $speed";
exec "ssh -t $dsthost screen -U -a -O -e ^]a -d -R -S serial-" . $ARGV[0] . "-cons -A $dstty $speed";
#my $pathtochild= dirname($scriptname). "/";
#exec $pathtochild."blade.expect $mm $slot $username $password";

View File

@ -1,21 +1,23 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
use Fcntl qw(:DEFAULT :flock);
sub get_lock {
unless (flock(LOCKHANDLE,LOCK_EX|LOCK_NB)) {
unless (flock(LOCKHANDLE, LOCK_EX | LOCK_NB)) {
$| = 1;
print "Acquiring startup lock...";
flock(LOCKHANDLE,LOCK_EX) or die "Error trying to secure a startup lock";
flock(LOCKHANDLE, LOCK_EX) or die "Error trying to secure a startup lock";
print "done\n";
}
truncate(LOCKHANDLE,0);
print LOCKHANDLE $$."\n";
truncate(LOCKHANDLE, 0);
print LOCKHANDLE $$ . "\n";
}
sub release_lock {
truncate(LOCKHANDLE,0);
flock(LOCKHANDLE,LOCK_UN);
truncate(LOCKHANDLE, 0);
flock(LOCKHANDLE, LOCK_UN);
}
BEGIN
{
use Time::HiRes qw(sleep);
@ -24,14 +26,14 @@ BEGIN
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
umask 0077;
mkpath("/tmp/xcat/");
unless (sysopen(LOCKHANDLE,"/tmp/xcat/consolelock",O_WRONLY | O_CREAT)) {
unless (sysopen(LOCKHANDLE, "/tmp/xcat/consolelock", O_WRONLY | O_CREAT)) {
sleep 15;
print "Unable to open lock file";
exit 0;
}
get_lock();
}
my $sleepint=int(rand(10));
my $sleepint = int(rand(10));
use lib "$::XCATROOT/lib/perl";
require xCAT::Client;
use strict;
@ -53,87 +55,88 @@ my $credencial;
my $fsp_ip;
my $id;
my $hcps;
my $result;
my $result;
##########################################################################
# Open remote console thourgh fsp
##########################################################################
sub invoke_fsp {
my $fsp_api = ($::XCATROOT) ? "$::XCATROOT/sbin/fsp-api" : "/opt/xcat/sbin/fsp-api";
my $fsp_api = ($::XCATROOT) ? "$::XCATROOT/sbin/fsp-api" : "/opt/xcat/sbin/fsp-api";
my $action = "console";
my $type = "0";
my $Rc = 0;
if( !(-e $fsp_api) && !(-x $fsp_api) ) {
my $type = "0";
my $Rc = 0;
if (!(-e $fsp_api) && !(-x $fsp_api)) {
return "please check the $fsp_api";
}
my $cmd = "$fsp_api -a $action -t $type:$fsp_ip:$id:$node:\r";
#print "cmd: $cmd\n";
my $running_failed_code = "Reason code: 0x1000000";
my $fsp_standby_msg = "Reason code: 0x1300";
my $timeout = 30;
my $failed = 0;
my $exp = new Expect;
$exp->log_stdout( 1 );
$exp->spawn( $cmd ) or die "Can't spawn $cmd\r\n";
my @result = $exp->expect( $timeout,
[ "$running_failed_code",
sub {
$failed = 1;
} ],
[ "$fsp_standby_msg",
sub {
$failed = 2;
}],
[ "Session closed, back from open_vterm",
sub {
$failed = 3;
}]
);
if($failed == 1) {
$exp->hard_close();
return("Virtual terminal is already connected");
}
if($failed == 2) {
$exp->hard_close();
return("Failed to open the console. Please check the related FSP's status");
}
if($failed == 3) {
$exp->hard_close();
return("Failed to open the console. Please check the related FSP's IP");
}
my $fsp_standby_msg = "Reason code: 0x1300";
my $timeout = 30;
my $failed = 0;
my $exp = new Expect;
$exp->log_stdout(1);
$exp->spawn($cmd) or die "Can't spawn $cmd\r\n";
my @result = $exp->expect($timeout,
[ "$running_failed_code",
sub {
$failed = 1;
} ],
[ "$fsp_standby_msg",
sub {
$failed = 2;
} ],
[ "Session closed, back from open_vterm",
sub {
$failed = 3;
} ]
);
if ($failed == 1) {
$exp->hard_close();
return ("Virtual terminal is already connected");
}
if ($failed == 2) {
$exp->hard_close();
return ("Failed to open the console. Please check the related FSP's status");
}
if ($failed == 3) {
$exp->hard_close();
return ("Failed to open the console. Please check the related FSP's IP");
}
my $escape = "\030";
$exp->send( "\r" );
$exp->interact( \*STDIN, $escape );
$exp->hard_close();
return(0);
$exp->send("\r");
$exp->interact(\*STDIN, $escape);
$exp->hard_close();
return (0);
}
##########################################################################
# Open remote console through hmc
# Open remote console through hmc
##########################################################################
sub invoke_hmc {
my $type = "lpar";
my $hwtype = "hmc";
my $type = "lpar";
my $hwtype = "hmc";
my %request = (
ppcretry => 1,
verbose => $verbose
);
#################################
# Get userid and password
# Get userid and password
#################################
#my @cred = xCAT::PPCdb::credentials( $host, $hwtype );
@cred = split(/,/, $credencial);
@ -141,85 +144,85 @@ sub invoke_hmc {
#################################
# Connect to the remote server
#################################
my @exp = xCAT::PPCcli::connect( \%request, $hwtype, $host );
if ( ref($exp[0]) ne "Expect" ) {
return( $exp[0] );
my @exp = xCAT::PPCcli::connect(\%request, $hwtype, $host);
if (ref($exp[0]) ne "Expect") {
return ($exp[0]);
}
#################################
# Open console connection
# Open console connection
#################################
my $result = xCAT::PPCcli::mkvterm( \@exp, $type, $lparid, $mtms );
my $result = xCAT::PPCcli::mkvterm(\@exp, $type, $lparid, $mtms);
my $Rc = shift(@$result);
if ( $Rc != SUCCESS ) {
return( @$result[0] );
if ($Rc != SUCCESS) {
return (@$result[0]);
}
return(0);
return (0);
}
##############################################
# Start main body of code
# Start main body of code
##############################################
sub getans {
my $rsp = shift;
my $rsp = shift;
if ($rsp->{node}) {
$hcps = $rsp->{node}->[0]->{hcp};
if ( $rsp->{node}->[0]->{errorcode} ) {
if ($rsp->{node}->[0]->{errorcode}) {
print STDERR "$rsp->{node}->[0]->{error}";
}
}
}
my $cmdref={
command=>["getmulcon"],
arg=>["text"],
noderange=>[$ARGV[0]]
my $cmdref = {
command => ["getmulcon"],
arg => ["text"],
noderange => [ $ARGV[0] ]
};
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
until ($hcps) {
release_lock(); #Let other clients have a go
$sleepint=10+int(rand(20)); #Stagger to minimize lock collisions, but no big deal when it does happen
release_lock(); #Let other clients have a go
$sleepint = 10 + int(rand(20)); #Stagger to minimize lock collisions, but no big deal when it does happen
print "Console not ready, retrying in $sleepint seconds (Hit Ctrl-E,c,o to skip delay)\n";
sleep $sleepint;
get_lock();
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
}
release_lock(); #done with xcatd, can run with near impunity
release_lock(); #done with xcatd, can run with near impunity
$node = $ARGV[0];
my $c = scalar ( keys %{${$hcps}[0]});
for my $thishcp (keys %{${$hcps}[0]}) {
my $nt = ${${${${${$hcps}[0]}{$thishcp}}[0]}{nodetype}}[0];
if ( $nt =~ /^(fsp)$/ ) {
$fsp_ip = ${${${${${$hcps}[0]}{$thishcp}}[0]}{fsp_ip}}[0];
$id = ${${${${${$hcps}[0]}{$thishcp}}[0]}{id}}[0];
if ($fsp_ip and $id ) {
$result = invoke_fsp();
my $c = scalar(keys %{ ${$hcps}[0] });
for my $thishcp (keys %{ ${$hcps}[0] }) {
my $nt = ${ ${ ${ ${ ${$hcps}[0] }{$thishcp} }[0] }{nodetype} }[0];
if ($nt =~ /^(fsp)$/) {
$fsp_ip = ${ ${ ${ ${ ${$hcps}[0] }{$thishcp} }[0] }{fsp_ip} }[0];
$id = ${ ${ ${ ${ ${$hcps}[0] }{$thishcp} }[0] }{id} }[0];
if ($fsp_ip and $id) {
$result = invoke_fsp();
} else {
print STDERR "fsp_ip or id is not available\n";
}
}
elsif ( $nt =~ /^(hmc)$/) {
$host = ${${${${${$hcps}[0]}{$thishcp}}[0]}{host}}[0];
$lparid = ${${${${${$hcps}[0]}{$thishcp}}[0]}{lparid}}[0];
$mtms = ${${${${${$hcps}[0]}{$thishcp}}[0]}{mtms}}[0];
$credencial = ${${${${${$hcps}[0]}{$thishcp}}[0]}{credencial}}[0];
elsif ($nt =~ /^(hmc)$/) {
$host = ${ ${ ${ ${ ${$hcps}[0] }{$thishcp} }[0] }{host} }[0];
$lparid = ${ ${ ${ ${ ${$hcps}[0] }{$thishcp} }[0] }{lparid} }[0];
$mtms = ${ ${ ${ ${ ${$hcps}[0] }{$thishcp} }[0] }{mtms} }[0];
$credencial = ${ ${ ${ ${ ${$hcps}[0] }{$thishcp} }[0] }{credencial} }[0];
if ($host and $lparid and $mtms and $credencial) {
$result = invoke_hmc();
} else {
print STDERR "hcp or lparid or mtms or user/passwd is not available\n";
}
}
if($result eq 0) {
if ($result eq 0) {
last;
}
}
##############
#Once every hcp is tried, if the $res!=0, it will return -1;
###############
###############
$c--;
if($c == 0) {
if ($c == 0) {
print STDERR "$node: $result\n";
exit(1)
}

View File

@ -1,21 +1,23 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
use Fcntl qw(:DEFAULT :flock);
sub get_lock {
unless (flock(LOCKHANDLE,LOCK_EX|LOCK_NB)) {
unless (flock(LOCKHANDLE, LOCK_EX | LOCK_NB)) {
$| = 1;
print "Acquiring startup lock...";
flock(LOCKHANDLE,LOCK_EX) or die "Fatal error securing startup lock";
flock(LOCKHANDLE, LOCK_EX) or die "Fatal error securing startup lock";
print "done\n";
}
truncate(LOCKHANDLE,0);
print LOCKHANDLE $$."\n";
truncate(LOCKHANDLE, 0);
print LOCKHANDLE $$ . "\n";
}
sub release_lock {
truncate(LOCKHANDLE,0);
flock(LOCKHANDLE,LOCK_UN);
truncate(LOCKHANDLE, 0);
flock(LOCKHANDLE, LOCK_UN);
}
BEGIN
{
use Time::HiRes qw(sleep);
@ -24,16 +26,18 @@ BEGIN
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
umask 0077;
mkpath("/tmp/xcat/");
unless (sysopen(LOCKHANDLE,"/tmp/xcat/consolelock",O_WRONLY | O_CREAT)) {
unless (sysopen(LOCKHANDLE, "/tmp/xcat/consolelock", O_WRONLY | O_CREAT)) {
sleep 15;
print "Unable to open lock file";
exit 0;
}
get_lock();
#my $sleepint=int(rand(10));
#print "Opening console in ".(2+(0.5*$sleepint))." seconds...\n";
#sleep $sleepint;
}
#BEGIN
#{
# use Time::HiRes qw(sleep);
@ -50,36 +54,37 @@ require File::Basename;
import File::Basename;
my $scriptname = $0;
my $cmdref={
command=>"getxencons",
arg=>"text",
noderange=>$ARGV[0]
my $cmdref = {
command => "getxencons",
arg => "text",
noderange => $ARGV[0]
};
use Data::Dumper;
my $dsthost;
my $dstty;
my $speed;
sub getans {
my $rsp = shift;
my $rsp = shift;
if ($rsp->{node}) {
$dsthost = $rsp->{node}->[0]->{sshhost}->[0];
$dstty = $rsp->{node}->[0]->{psuedotty}->[0];
$speed = $rsp->{node}->[0]->{baudrate}->[0];
$dstty = $rsp->{node}->[0]->{psuedotty}->[0];
$speed = $rsp->{node}->[0]->{baudrate}->[0];
}
}
xCAT::Client::submit_request($cmdref,\&getans);
xCAT::Client::submit_request($cmdref, \&getans);
until ($dsthost and $speed and $dstty) {
release_lock();
$sleepint=int(rand(30))+60;
$sleepint = int(rand(30)) + 60;
print "Console not ready, retrying in $sleepint seconds (Ctrl-C to skip delay)\n";
exec "sleep $sleepint";
}
release_lock();
exec "ssh -t $dsthost screen -U -a -O -e ^]a -d -R -S serial-".$ARGV[0]."-cons -A $dstty $speed";
exec "ssh -t $dsthost screen -U -a -O -e ^]a -d -R -S serial-" . $ARGV[0] . "-cons -A $dstty $speed";
#my $pathtochild= dirname($scriptname). "/";
#exec $pathtochild."blade.expect $mm $slot $username $password";

File diff suppressed because it is too large Load Diff

View File

@ -25,19 +25,19 @@ use strict;
use Getopt::Long;
# Log file
$::GUIDS_LOG = "/var/log/xcat/getGuids.log";
$::DEFAULT_RESULT_FILE = "/var/opt/xcat/ib/Guids.xcat";
$::GUIDS_LOG_PATH = "/var/log/xcat";
$::GUIDS_LOG = "/var/log/xcat/getGuids.log";
$::DEFAULT_RESULT_FILE = "/var/opt/xcat/ib/Guids.xcat";
$::GUIDS_LOG_PATH = "/var/log/xcat";
$::DEFAULT_RESULT_FILE_PATH = "/var/opt/xcat/ib";
# variables and Commands
$::OK = 0;
$::NOK = 1;
$::logging = 0;
$::OK = 0;
$::NOK = 1;
$::logging = 0;
$::GLOBAL_EXIT = 0;
$::NODEGRP = "/opt/xcat/bin/nodels";
$::LinuxIBCmd = "/usr/bin/ibv_devinfo";
$::AIXIBCmd = "/usr/bin/ibstat";
$::NODEGRP = "/opt/xcat/bin/nodels";
$::LinuxIBCmd = "/usr/bin/ibv_devinfo";
$::AIXIBCmd = "/usr/bin/ibstat";
# MAIN Main main#
&getArgs;
@ -51,16 +51,16 @@ local *FILE;
unless (open(FILE, ">$::RESULT_FILE"))
{
print "Can't open file $::RESULT_FILE for writing.\n";
print $::LOG_FILE_HANDLE
print $::LOG_FILE_HANDLE
"Can't open file $::RESULT_FILE for writing.\n";
$::GLOBAL_EXIT = $::NOK;
exit;
}
# get Linux nodes
my @LnxNodes = `$::NODEGRP all nodetype.os | grep -E "sles|rhel"`;
print $::LOG_FILE_HANDLE "Running command: $::NODEGRP LinuxNodes\n";
print $::LOG_FILE_HANDLE "Running command: $::NODEGRP LinuxNodes\n";
chomp @LnxNodes;
my @ReachableLnxNodes;
@ -77,7 +77,7 @@ if ($num > 0)
my $rest;
($node, $rest) = split(/:/, $node);
my $rc = &checkxDshReachability($node);
if ($rc == 0) # xdsh is ok
if ($rc == 0) # xdsh is ok
{
push @ReachableLnxNodes, $node;
}
@ -87,14 +87,14 @@ if ($num > 0)
}
}
if (scalar (@UnreachableLnxNodes))
if (scalar(@UnreachableLnxNodes))
{
my $UnreachableLnxNodes = join (", ", @UnreachableLnxNodes);
print
"Warning: xdsh is unreachable for the node(s): $UnreachableLnxNodes.\n" .
my $UnreachableLnxNodes = join(", ", @UnreachableLnxNodes);
print
"Warning: xdsh is unreachable for the node(s): $UnreachableLnxNodes.\n" .
"Please use xdsh <Node> -K command to configure it.\n";
print $::LOG_FILE_HANDLE
"Warning: xdsh is unreachable for the node(s): $UnreachableLnxNodes.\n" .
"Warning: xdsh is unreachable for the node(s): $UnreachableLnxNodes.\n" .
"Please use xdsh <Node> -K command to configure it.\n";
}
@ -111,16 +111,16 @@ if ($num > 0)
}
}
if (scalar (@BadLnxNodes))
if (scalar(@BadLnxNodes))
{
my $BadLnxNodes = join (", ", @BadLnxNodes);
print
"Warning: Command $::LinuxIBCmd is not available on the node(s): $BadLnxNodes.\nPlease ensure the libibverbs rpm is installed.\n";
my $BadLnxNodes = join(", ", @BadLnxNodes);
print
"Warning: Command $::LinuxIBCmd is not available on the node(s): $BadLnxNodes.\nPlease ensure the libibverbs rpm is installed.\n";
print $::LOG_FILE_HANDLE
"Warning: Command $::LinuxIBCmd is not available on the node(s): $BadLnxNodes.\nPlease ensure the libibverbs rpm is installed.\n";
"Warning: Command $::LinuxIBCmd is not available on the node(s): $BadLnxNodes.\nPlease ensure the libibverbs rpm is installed.\n";
}
if (scalar (@ValidLnxNodes))
if (scalar(@ValidLnxNodes))
{
my $rc = &getLinuxGUIDS(\@ValidLnxNodes);
if ($rc)
@ -133,7 +133,7 @@ if ($num > 0)
# get AIX nodes
my @AIXNodes = `$::NODEGRP all nodetype.os | grep "AIX"`;
print $::LOG_FILE_HANDLE "Running command: $::NODEGRP\n";
print $::LOG_FILE_HANDLE "Running command: $::NODEGRP\n";
chomp @AIXNodes;
my @ReachableAIXNodes;
@ -143,15 +143,15 @@ my @BadAIXNodes;
my $num = scalar(@AIXNodes);
if ($num > 0)
{
# Handle AIX Nodes
# Handle AIX Nodes
# Check if xdsh is reachable
foreach my $node (@AIXNodes)
{
my $rest;
($node, $rest) = split(/:/, $node);
my $rc = &checkxDshReachability($node);
if ($rc == 0) # xdsh is ok
if ($rc == 0) # xdsh is ok
{
push @ReachableAIXNodes, $node;
}
@ -161,14 +161,14 @@ if ($num > 0)
}
}
if (scalar (@UnreachableAIXNodes))
if (scalar(@UnreachableAIXNodes))
{
my $UnreachableAIXNodes = join (", ", @UnreachableAIXNodes);
print
"Warning: The xdsh is unreachable for the node(s): $UnreachableAIXNodes.\n" .
my $UnreachableAIXNodes = join(", ", @UnreachableAIXNodes);
print
"Warning: The xdsh is unreachable for the node(s): $UnreachableAIXNodes.\n" .
"Please use xdsh <Node> -K command to configure it.\n";
print $::LOG_FILE_HANDLE
"Warning: The xdsh is unreachable for the node(s): $UnreachableAIXNodes.\n" .
"Warning: The xdsh is unreachable for the node(s): $UnreachableAIXNodes.\n" .
"Please use xdsh <Node> -K command to configure it.\n";
}
@ -185,16 +185,16 @@ if ($num > 0)
}
}
if (scalar (@BadAIXNodes))
if (scalar(@BadAIXNodes))
{
my $BadAIXNodes = join (", ", @BadAIXNodes);
print
"Warning: Command $::AIXIBCmd is not available on the node(s): $BadAIXNodes.\nPlease ensure the devices.common.IBM.ib.rte fileset is installed.\n";
my $BadAIXNodes = join(", ", @BadAIXNodes);
print
"Warning: Command $::AIXIBCmd is not available on the node(s): $BadAIXNodes.\nPlease ensure the devices.common.IBM.ib.rte fileset is installed.\n";
print $::LOG_FILE_HANDLE
"Warning: Command $::AIXIBCmd is not available on the node(s): $BadAIXNodes.\nPlease ensure the devices.common.IBM.ib.rte fileset is installed.\n";
"Warning: Command $::AIXIBCmd is not available on the node(s): $BadAIXNodes.\nPlease ensure the devices.common.IBM.ib.rte fileset is installed.\n";
}
if (scalar (@ValidAIXNodes))
if (scalar(@ValidAIXNodes))
{
my $rc = &getAIXGUIDS(\@ValidAIXNodes);
if ($rc)
@ -231,7 +231,7 @@ END
}
}
exit; # end of Main
exit; # end of Main
#--------------------------------------------------------------------------------
@ -244,8 +244,8 @@ exit; # end of Main
sub getArgs()
{
GetOptions(
'h' => \$::HELP,
'f=s' => \$::RESULT_FILE
'h' => \$::HELP,
'f=s' => \$::RESULT_FILE
);
if ($::HELP)
{
@ -265,7 +265,7 @@ sub getArgs()
exit;
}
}
}
}
}
#--------------------------------------------------------------------------------
@ -279,11 +279,11 @@ sub getArgs()
sub usage()
{
print
"Usage: getGuids [-h] [-f output_file]
"Usage: getGuids [-h] [-f output_file]
-f output_file
Specifies a file full path name that is used to save the GUIDs output.
-h
Display usage information.\n";
Display usage information.\n";
}
#--------------------------------------------------------------------------------
@ -308,7 +308,7 @@ sub checkxDshReachability()
my ($node) = @_;
my $output = `xdsh $node date 2>/dev/null`;
print $::LOG_FILE_HANDLE "Running command: xdsh $node date 2>/dev/null\n";
print $::LOG_FILE_HANDLE "Running command: xdsh $node date 2>/dev/null\n";
if ($? == $::OK)
{
return $::OK;
@ -367,7 +367,7 @@ sub append_logging()
{
#my ($class, $logfile) = @_;
my ($logfile) = @_;
my ($cmd, $rc);
my ($cmd, $rc);
#
# get log file ready
@ -402,10 +402,10 @@ sub append_logging()
print "Output log is being written to \"$logfile\".\n";
print $::LOG_FILE_HANDLE
"---------------------------------------------------------------------\n";
"---------------------------------------------------------------------\n";
print $::LOG_FILE_HANDLE "Logging started $sdate.\n";
print $::LOG_FILE_HANDLE
"---------------------------------------------------------------------\n";
"---------------------------------------------------------------------\n";
return $::OK;
}
@ -426,10 +426,10 @@ sub stop_logging()
my $sdate = `/bin/date`;
chomp $sdate;
print $::LOG_FILE_HANDLE
"---------------------------------------------------------------------\n";
"---------------------------------------------------------------------\n";
print $::LOG_FILE_HANDLE "Logging stopped $sdate.\n";
print $::LOG_FILE_HANDLE
"---------------------------------------------------------------------\n";
"---------------------------------------------------------------------\n";
close($::LOG_FILE_HANDLE);
$::LOG_FILE_HANDLE = undef;
@ -450,7 +450,7 @@ Arguments:
sub getAIXGUIDS()
{
my ($refAIXNodes) = @_;
my $AIXNodes = join (",", @$refAIXNodes);
my $AIXNodes = join(",", @$refAIXNodes);
print "Getting GUIDs from AIX nodes...\n";
print $::LOG_FILE_HANDLE "Getting GUIDs from AIX nodes...\n";
@ -466,20 +466,20 @@ sub getAIXGUIDS()
return $::NOK;
}
my $oldhost = "";
my $host = "";
my $dev = "";
my $guid = "";
my $port = "";
my $gid = "";
my $oldhost = "";
my $host = "";
my $dev = "";
my $guid = "";
my $port = "";
my $gid = "";
my $baseguid = "";
my $lsw0 = "";
my $lsw1 = "";
my $lsw0 = "";
my $lsw1 = "";
foreach my $line (@output)
{
chomp $line;
# Get node hostname
if ($line =~ /(\S*):.*/)
{
@ -488,7 +488,7 @@ sub getAIXGUIDS()
{
print FILE "Node name is $host.\n";
print $::LOG_FILE_HANDLE "Node name is $host.\n";
$oldhost=$host;
$oldhost = $host;
}
}
@ -502,23 +502,23 @@ sub getAIXGUIDS()
if ($line =~ /.*\(GUID\):.*\s+(\S*)/)
{
$guid = $1;
$guid=~s/\.//g;
$baseguid=$guid;
$baseguid=~s/..$//;
$lsw0=$guid;
$lsw0=~s/..$/80/;
$lsw1=$guid;
$lsw1=~s/..$/81/;
$guid =~ s/\.//g;
$baseguid = $guid;
$baseguid =~ s/..$//;
$lsw0 = $guid;
$lsw0 =~ s/..$/80/;
$lsw1 = $guid;
$lsw1 =~ s/..$/81/;
print FILE "$host: $dev: baseguid: $baseguid\n";
print FILE "$host: $dev: dev: $guid\n";
print FILE "$host: $dev: lsw0: $lsw0\n";
print FILE "$host: $dev: lsw1: $lsw1\n";
print FILE "$host: $dev: baseguid: $baseguid\n";
print FILE "$host: $dev: dev: $guid\n";
print FILE "$host: $dev: lsw0: $lsw0\n";
print FILE "$host: $dev: lsw1: $lsw1\n";
print $::LOG_FILE_HANDLE "$host: $dev: baseguid: $baseguid\n";
print $::LOG_FILE_HANDLE "$host: $dev: dev: $guid\n";
print $::LOG_FILE_HANDLE "$host: $dev: lsw0: $lsw0\n";
print $::LOG_FILE_HANDLE "$host: $dev: lsw1: $lsw1\n";
print $::LOG_FILE_HANDLE "$host: $dev: baseguid: $baseguid\n";
print $::LOG_FILE_HANDLE "$host: $dev: dev: $guid\n";
print $::LOG_FILE_HANDLE "$host: $dev: lsw0: $lsw0\n";
print $::LOG_FILE_HANDLE "$host: $dev: lsw1: $lsw1\n";
}
# Get port number under device(iba)
@ -531,7 +531,7 @@ sub getAIXGUIDS()
if ($line =~ /.*GUID\[.*\s+(\S*)/)
{
$gid = $1;
$gid=~s/\.//g;
$gid =~ s/\.//g;
print FILE "$host: $dev: portGUID_$port: $gid\n";
print $::LOG_FILE_HANDLE "$host: $dev: portGUID_$port: $gid\n";
}
@ -553,9 +553,9 @@ Arguments:
sub getLinuxGUIDS()
{
my ($refLnxNodes) = @_;
my $LnxNodes = join (",", @$refLnxNodes);
my $LnxNodes = join(",", @$refLnxNodes);
print
print
"Getting GUIDs from Linux nodes...\n";
print $::LOG_FILE_HANDLE
"Getting GUIDs from Linux nodes...\n";
@ -566,26 +566,27 @@ sub getLinuxGUIDS()
if ($?)
{
print
print
"Command failed: $getCmd.\n";
print $::LOG_FILE_HANDLE
print $::LOG_FILE_HANDLE
"Command failed: $getCmd.\n";
return $::NOK;
}
my $oldhost = "";
my $host ="";
my $dev = "";
my $guid = "";
my $port = "";
my $gid = "";
my $oldhost = "";
my $host = "";
my $dev = "";
my $guid = "";
my $port = "";
my $gid = "";
my $baseguid = "";
my $lsw0 = "" ;
my $lsw1 = "";
my $lsw0 = "";
my $lsw1 = "";
foreach my $line (@output)
{
chomp $line;
# Get node hostname
if ($line =~ /(\S*):.*/)
{
@ -594,27 +595,27 @@ sub getLinuxGUIDS()
{
print FILE "Node name is $host.\n";
print $::LOG_FILE_HANDLE "Node name is $host.\n";
$oldhost=$host;
$oldhost = $host;
}
}
# Get device name
if ($line =~ /.*hca_id:\s(\S*).*/)
{
$dev = $1;
$dev = $1;
}
# Get node_guid under hca_id
if ($line =~ /.*node_guid:\s*(\S*)/)
{
$guid = $1;
$guid =~s/://g;
$guid =~ s/://g;
$baseguid = $guid;
$baseguid =~s/..$//;
$baseguid =~ s/..$//;
$lsw0 = $guid;
$lsw0 =~s/..$/80/;
$lsw0 =~ s/..$/80/;
$lsw1 = $guid;
$lsw1 =~s/..$/81/;
$lsw1 =~ s/..$/81/;
print FILE "$host: $dev: baseguid: $baseguid\n";
print FILE "$host: $dev: dev: $guid\n";
@ -637,9 +638,9 @@ sub getLinuxGUIDS()
if ($line =~ /.*GID.* *(\S*:\S*:\S*:\S*).*/)
{
$gid = $1;
$gid=~s/://g;
my $prefix = substr $baseguid, 0, 4;
$gid = $prefix . $gid;
$gid =~ s/://g;
my $prefix = substr $baseguid, 0, 4;
$gid = $prefix . $gid;
print FILE "$host: $dev: portGUID_$port: $gid\n";
print $::LOG_FILE_HANDLE "$host: $dev: portGUID_$port: $gid\n";
}

View File

@ -6,15 +6,15 @@
# Command: healthCheck #
# #
#-------------------------------------------------------------------------#
# This script is used to check the system health for both AIX and
# This script is used to check the system health for both AIX and
# Linux Managed Nodes on Power6 platforms. It will use xdsh to access
# the target nodes, and check the status for processor clock speed,
# IB interfaces, memory, large page configuration and HCA status.
# If xdsh is unreachable, an error message will be given.
# If xdsh is unreachable, an error message will be given.
# Command Syntax:
# healthCheck { [-n node_list] [-M]}
# {[-p min_clock_speed] [-i method] [-m min_memory]
# [-l min_freelp] [ -H [--speed speed --ignore interface_list --width width]]}
# [-l min_freelp] [ -H [--speed speed --ignore interface_list --width width]]}
# [ -h ]
#
# -M Check status for all the Managed Nodes that are defined on this MN.
@ -23,7 +23,7 @@
# -p min_clock_speed
# Specifies the minimal processor clock speed in MHz for processor monitor.
# -i method
# Specifies the method to do Infiniband interface status check, the supported
# Specifies the method to do Infiniband interface status check, the supported
# check methods are LL and RSCT.
# -m min_memory
# Specifies the minimal total memory in MB.
@ -33,7 +33,7 @@
# --speed speed
# Specifies the physical port speed in G bps, it should be used with -H flag.
# --ignore interface_list
# Specifies a comma-separated list of interface name to ignore from HCA status check,
# Specifies a comma-separated list of interface name to ignore from HCA status check,
# such as ib0,ib1. It should be used with -H flag.
# --width width
# Specifies the physical port width, such as 4X or 12X. It should be used with -H flag.
@ -48,28 +48,29 @@ use Getopt::Long;
# Log file
$::HEALTHCHECK_PATH = "/var/log/xcat";
$::HEALTHCHECK_LOG = "$::HEALTHCHECK_PATH/healthCheck.log";
$::HEALTHCHECK_LOG = "$::HEALTHCHECK_PATH/healthCheck.log";
# variables and Commands
$::OK = 0;
$::NOK = 1;
$::logging = 0;
$::GLOBAL_EXIT = 0;
$::NODELS = "/opt/xcat/bin/nodels";
$::OK = 0;
$::NOK = 1;
$::logging = 0;
$::GLOBAL_EXIT = 0;
$::NODELS = "/opt/xcat/bin/nodels";
$::LinuxProcCmd = "cat /proc/cpuinfo";
$::AIXProcCmd = "/usr/pmapi/tools/pmcycles";
$::IBifLLCmdL = "/opt/ibmll/LoadL/full/bin/llstatus";
$::IBifLLCmdA = "/usr/lpp/LoadL/full/bin/llstatus";
$::IBifRSCTCmd = "/usr/bin/lsrsrc";
$::AIXMemCmd = "/usr/bin/vmstat";
$::LinuxMemCmd = "cat /proc/meminfo";
$::AIXHCACmd = "/usr/bin/ibstat";
$::LinuxHCACmd = "/usr/bin/ibv_devinfo";
$::AIXProcCmd = "/usr/pmapi/tools/pmcycles";
$::IBifLLCmdL = "/opt/ibmll/LoadL/full/bin/llstatus";
$::IBifLLCmdA = "/usr/lpp/LoadL/full/bin/llstatus";
$::IBifRSCTCmd = "/usr/bin/lsrsrc";
$::AIXMemCmd = "/usr/bin/vmstat";
$::LinuxMemCmd = "cat /proc/meminfo";
$::AIXHCACmd = "/usr/bin/ibstat";
$::LinuxHCACmd = "/usr/bin/ibv_devinfo";
#Nodes to be checked
my @NodeList;
my @LnxNodeList;
my @AIXNodeList;
#Ignored ib interfaces when checking HCA status
my @IgnoreList;
@ -89,7 +90,7 @@ if (scalar(@NodeList) > 0)
{
my $rc = &checkDshReachability($node);
if ($rc == 0)
{ # xdsh is ok
{ # xdsh is ok
push @ReachableNodes, $node;
}
else
@ -98,9 +99,9 @@ if (scalar(@NodeList) > 0)
}
}
if (scalar (@UnreachableNodes))
if (scalar(@UnreachableNodes))
{
my $UnreachableNodes = join (", ", @UnreachableNodes);
my $UnreachableNodes = join(", ", @UnreachableNodes);
print "Warning: The xdsh is unreachable for the node(s): $UnreachableNodes. Run updatenode to configure xdsh for that node(s).\n";
print $::LOG_FILE_HANDLE "Warning: The xdsh is unreachable for the node(s): $UnreachableNodes. Run updatenode to configure xdsh for that node(s).\n";
}
@ -123,18 +124,18 @@ chomp @AllAIXNodes;
foreach my $node (@ReachableNodes)
{
if ( grep {$_ =~ /$node/} @AllLnxNodes )
if (grep { $_ =~ /$node/ } @AllLnxNodes)
{
push @LnxNodeList, $node;
}
if ( grep {$_ =~ /$node/} @AllAIXNodes )
if (grep { $_ =~ /$node/ } @AllAIXNodes)
{
push @AIXNodeList, $node;
}
}
#Do health check for Linux nodes and AIX nodes
if (scalar (@LnxNodeList))
if (scalar(@LnxNodeList))
{
my $rc = &healthCheckLinux(\@LnxNodeList);
if ($rc)
@ -143,7 +144,7 @@ if (scalar (@LnxNodeList))
exit;
}
}
if (scalar (@AIXNodeList))
if (scalar(@AIXNodeList))
{
my $rc = &healthCheckAIX(\@AIXNodeList);
if ($rc)
@ -156,17 +157,18 @@ if (scalar (@AIXNodeList))
# Finish up and exit
END
{
if ($::logging)
if ($::logging)
{
&stop_logging();
}
#Determine exit code
if ($::GLOBAL_EXIT > $?)
&stop_logging();
}
#Determine exit code
if ($::GLOBAL_EXIT > $?)
{
$? = $::GLOBAL_EXIT;
}
$? = $::GLOBAL_EXIT;
}
}
exit; # end of Main
exit; # end of Main
#--------------------------------------------------------------------------------
@ -198,7 +200,7 @@ sub getArgs()
exit;
}
if (!$rc)
{ #There are syntax errors in parameters
{ #There are syntax errors in parameters
&usage();
$::GLOBAL_EXIT = $::NOK;
exit;
@ -213,25 +215,25 @@ sub getArgs()
exit;
}
}
if(!defined($::MIN_CLOCK_SPEED) && !defined($::IF_CHECK_METHOD) && !defined($::MIN_MEMORY) && !defined($::MIN_FREELP) && !defined($::HCA))
if (!defined($::MIN_CLOCK_SPEED) && !defined($::IF_CHECK_METHOD) && !defined($::MIN_MEMORY) && !defined($::MIN_FREELP) && !defined($::HCA))
{
print "There is nothing to check. Please specify what you want to check.\n";
&usage();
$::GLOBAL_EXIT = $::NOK;
exit;
}
if(!defined($::HCA) && (defined($::HCASPEED) || $::IGNORE_LIST ne "" || $::WIDTH ne ""))
if (!defined($::HCA) && (defined($::HCASPEED) || $::IGNORE_LIST ne "" || $::WIDTH ne ""))
{
print "The flag --speed, --ignore or --width should be used with -H flag.\n";
&usage();
$::GLOBAL_EXIT = $::NOK;
exit;
}
if($::WIDTH ne "")
if ($::WIDTH ne "")
{
if(!($::WIDTH =~ /^(\d+)X$/))
if (!($::WIDTH =~ /^(\d+)X$/))
{
print "The parameter of --width should be 4X, 12X, etc.\n";
&usage();
@ -242,13 +244,13 @@ sub getArgs()
#Parse the node list
if ($::NODE_LIST)
{
{
@NodeList = `$::NODELS $::NODE_LIST`; chomp @NodeList;
if ($?) {
print $::LOG_FILE_HANDLE "Running command: $::NODELS $::NODE_LIST fail\n";
print $::LOG_FILE_HANDLE "Running command: $::NODELS $::NODE_LIST fail\n";
exit;
} else {
print $::LOG_FILE_HANDLE "Running command: $::NODELS $::NODE_LIST\n";
print $::LOG_FILE_HANDLE "Running command: $::NODELS $::NODE_LIST\n";
}
}
@ -257,7 +259,7 @@ sub getArgs()
{
my @templist = `$::NODELS`;
chomp @templist;
print $::LOG_FILE_HANDLE "Running command: lsnode -w \"Mode='Managed' or Mode='MinManaged'\"\n";
print $::LOG_FILE_HANDLE "Running command: lsnode -w \"Mode='Managed' or Mode='MinManaged'\"\n";
@NodeList = @templist;
}
if ($::IGNORE_LIST)
@ -277,7 +279,7 @@ sub getArgs()
sub usage()
{
print
"Usage: healthCheck { [-n node_list] [-M]}
"Usage: healthCheck { [-n node_list] [-M]}
{[-p min_clock_speed] [-i method] [-m min_memory]
[-l min_freelp] [ -H [--speed speed --ignore interface_list --width width]]}
[ -h ]
@ -303,7 +305,7 @@ sub usage()
--width width
Specifies the physical port width, such as 4X or 12X. It should be used with -H flag.
-h Display usage information.
";
";
}
#--------------------------------------------------------------------------------
@ -327,7 +329,7 @@ sub checkDshReachability()
{
my ($node) = @_;
my $output = `xdsh $node date 2>/dev/null`;
print $::LOG_FILE_HANDLE "Running command: xdsh $node date 2>/dev/null\n";
print $::LOG_FILE_HANDLE "Running command: xdsh $node date 2>/dev/null\n";
if ($? == $::OK)
{
return $::OK;
@ -356,7 +358,7 @@ sub checkCmdAvailability
my @BadNodes;
foreach my $node (@$refNodes)
{
#Use xdsh to "ls" the command
#Use xdsh to "ls" the command
`xdsh $node ls $cmd 2>/dev/null`;
print $::LOG_FILE_HANDLE "Running command: xdsh $node ls $cmd 2>/dev/null\n";
if ($? == $::OK)
@ -369,9 +371,9 @@ sub checkCmdAvailability
}
}
if (scalar (@BadNodes))
if (scalar(@BadNodes))
{
my $BadNodes = join (", ", @BadNodes);
my $BadNodes = join(", ", @BadNodes);
print "Warning: The command $cmd is not available on the node(s): $BadNodes.\n";
print $::LOG_FILE_HANDLE "Warning: The command $cmd is not available on the node(s): $BadNodes.\n";
}
@ -390,12 +392,13 @@ sub checkCmdAvailability
sub append_logging()
{
my ($logfile) = @_;
my ($cmd, $rc);
my ($cmd, $rc);
# get log file ready
if (!-e $logfile)
{
`mkdir -p $::HEALTHCHECK_PATH`;
# create the log file if not already there
unless (open(LOGFILE, ">$logfile"))
{
@ -422,10 +425,10 @@ sub append_logging()
print "Output log is being written to \"$logfile\".\n";
print $::LOG_FILE_HANDLE
"---------------------------------------------------------------------\n";
"---------------------------------------------------------------------\n";
print $::LOG_FILE_HANDLE "Logging started $sdate.\n";
print $::LOG_FILE_HANDLE
"---------------------------------------------------------------------\n";
"---------------------------------------------------------------------\n";
return $::OK;
}
@ -445,10 +448,10 @@ sub stop_logging()
my $sdate = `/bin/date`;
chomp $sdate;
print $::LOG_FILE_HANDLE
"---------------------------------------------------------------------\n";
"---------------------------------------------------------------------\n";
print $::LOG_FILE_HANDLE "Logging stopped $sdate.\n";
print $::LOG_FILE_HANDLE
"---------------------------------------------------------------------\n";
"---------------------------------------------------------------------\n";
close($::LOG_FILE_HANDLE);
$::LOG_FILE_HANDLE = undef;
@ -471,16 +474,16 @@ sub healthCheckLinux()
my ($refLnxNodes) = @_;
my $allnodes = join ", ", @$refLnxNodes;
print "Checking health for Linux nodes: $allnodes...\n";
print $::LOG_FILE_HANDLE "Checking health for Linux nodes: $allnodes...\n";
print $::LOG_FILE_HANDLE "Checking health for Linux nodes: $allnodes...\n";
my $rc;
if ( defined($::MIN_CLOCK_SPEED) )
if (defined($::MIN_CLOCK_SPEED))
{
$rc = procsrCheckLinux($refLnxNodes);
if ($rc != $::OK) {
return $::NOK;
}
}
if ( defined($::MIN_MEMORY) || defined($::MIN_FREELP) )
if (defined($::MIN_MEMORY) || defined($::MIN_FREELP))
{
$rc = memCheckLinux($refLnxNodes);
if ($rc != $::OK)
@ -488,7 +491,7 @@ sub healthCheckLinux()
return $::NOK;
}
}
if ( $::IF_CHECK_METHOD ne "" )
if ($::IF_CHECK_METHOD ne "")
{
$rc = ifCheck($refLnxNodes, 'Linux');
if ($rc != $::OK)
@ -496,7 +499,7 @@ sub healthCheckLinux()
return $::NOK;
}
}
if ( defined($::HCA) )
if (defined($::HCA))
{
$rc = HCACheckLinux($refLnxNodes);
if ($rc != $::OK)
@ -522,9 +525,9 @@ sub healthCheckAIX()
my $allnodes = join ", ", @$refAIXNodes;
print "Checking health for AIX nodes: $allnodes...\n";
print $::LOG_FILE_HANDLE "Checking health for AIX nodes: $allnodes...\n";
my $rc;
if ( defined($::MIN_CLOCK_SPEED) )
if (defined($::MIN_CLOCK_SPEED))
{
$rc = procsrCheckAIX($refAIXNodes);
if ($rc != $::OK)
@ -532,7 +535,7 @@ sub healthCheckAIX()
return $::NOK;
}
}
if ( defined($::MIN_MEMORY) || defined($::MIN_FREELP) )
if (defined($::MIN_MEMORY) || defined($::MIN_FREELP))
{
$rc = memCheckAIX($refAIXNodes);
if ($rc != $::OK)
@ -540,7 +543,7 @@ sub healthCheckAIX()
return $::NOK;
}
}
if ( $::IF_CHECK_METHOD ne "" )
if ($::IF_CHECK_METHOD ne "")
{
$rc = ifCheck($refAIXNodes, 'AIX');
if ($rc != $::OK)
@ -548,7 +551,7 @@ sub healthCheckAIX()
return $::NOK;
}
}
if ( defined($::HCA) )
if (defined($::HCA))
{
$rc = HCACheckAIX($refAIXNodes);
if ($rc != $::OK)
@ -571,7 +574,7 @@ Arguments:
sub procsrCheckLinux()
{
my ($refLnxNodes) = @_;
my $ValidLnxNodes = join (",", @$refLnxNodes);
my $ValidLnxNodes = join(",", @$refLnxNodes);
print "\nChecking processor clock speed for nodes: $ValidLnxNodes...\n";
print $::LOG_FILE_HANDLE "Checking processor clock speed for nodes: $ValidLnxNodes...\n";
@ -584,7 +587,7 @@ sub procsrCheckLinux()
print "Command failed: $checkCmd.\n";
print $::LOG_FILE_HANDLE "Command failed: $checkCmd.\n";
}
my $host;
my $pcrnum;
my $clspeed;
@ -592,6 +595,7 @@ sub procsrCheckLinux()
foreach my $line (@output)
{
chomp $line;
# Get node hostname
if ($line =~ /(\S*):.*/)
{
@ -646,14 +650,14 @@ sub procsrCheckAIX()
my $allnodes = join ", ", @$refAIXNodes;
print "\nChecking processor clock speed for nodes: $allnodes...\n";
print $::LOG_FILE_HANDLE "Checking processor clock speed for nodes: $allnodes...\n";
@ValidAIXNodes = &checkCmdAvailability($refAIXNodes, $::AIXProcCmd);
if (!scalar (@ValidAIXNodes))
if (!scalar(@ValidAIXNodes))
{
return $::NOK;
}
my $ValidAIXNodes = join (",", @ValidAIXNodes);
my $ValidAIXNodes = join(",", @ValidAIXNodes);
my $checkCmd = "xdsh $ValidAIXNodes \"$::AIXProcCmd\" 2>/dev/null";
print $::LOG_FILE_HANDLE "Running command: $checkCmd.\n";
my @output = `$checkCmd`;
@ -662,13 +666,14 @@ sub procsrCheckAIX()
print "Command failed: $checkCmd.\n";
print $::LOG_FILE_HANDLE "Command failed: $checkCmd.\n";
}
my $host;
my $pcrnum;
my $clspeed;
foreach my $line (@output)
{
chomp $line;
# Get node hostname
if ($line =~ /(\S*):.*/)
{
@ -686,7 +691,7 @@ sub procsrCheckAIX()
}
}
}
if(!$abnormal)
if (!$abnormal)
{
print "The processor clock speed of all nodes is normal.\n";
print $::LOG_FILE_HANDLE "The processor clock speed of all nodes is normal.\n";
@ -712,7 +717,7 @@ sub ifCheck()
my $cmd;
my $abnormal = 0;
my $allnodes = join ", ", @$refNodes;
if ($::IF_CHECK_METHOD eq "LL")
{
if ($os eq 'Linux')
@ -736,19 +741,19 @@ sub ifCheck()
{
return $::NOK;
}
print "\nChecking IB interface status using command $cmd for nodes: $allnodes...\n";
print $::LOG_FILE_HANDLE "Checking IB interface status using command $cmd for nodes: $allnodes...\n";
@ValidNodes = &checkCmdAvailability($refNodes, $cmd);
if (!scalar (@ValidNodes))
if (!scalar(@ValidNodes))
{
return $::NOK;
}
my $ValidNodes = join (",", @ValidNodes);
my $ValidNodes = join(",", @ValidNodes);
#Method is "LL"
if ($::IF_CHECK_METHOD eq "LL")
{
@ -761,67 +766,72 @@ sub ifCheck()
print "Command failed: $checkCmd.\n";
print $::LOG_FILE_HANDLE "Command failed: $checkCmd.\n";
}
#Record whether the next line is the beginning of a new section
my $armed = 0;
my $ibnum;
my $host;
#Record abnormal ib interfaces of a node
my @ib_array = ();
foreach my $line (@output)
{
chomp $line;
#The text returned by llstatus is seperared into several sections by "=================="
if ($line =~ /==================/)
{
#If there are abnormal interfaces found after check last section
if ( @ib_array )
if (@ib_array)
{
print "$host IB interface(s) down: ";
print $::LOG_FILE_HANDLE "$host IB interface(s) down: ";
foreach (sort @ib_array)
{
print "ib$_ " ;
print $::LOG_FILE_HANDLE "ib$_ " ;
{
print "ib$_ ";
print $::LOG_FILE_HANDLE "ib$_ ";
}
print "\n";
print $::LOG_FILE_HANDLE "\n";
}
@ib_array = ();
$armed = 1;
$armed = 1;
}
elsif ( ( $armed ) && ($line =~ /\S+?:\s*(\S+)/) )
{ #The first line of a new section
#Get node hostname
$host = $1;
elsif (($armed) && ($line =~ /\S+?:\s*(\S+)/))
{ #The first line of a new section
#Get node hostname
$host = $1;
$armed = 0;
}
elsif ( $line =~ /\S+?:\s*ib(\d+).*/ )
elsif ($line =~ /\S+?:\s*ib(\d+).*/)
{
#Get interface number
$ibnum = $1;
#Check the status
if ( ! ($line =~ /READY/) )
if (!($line =~ /READY/))
{
$abnormal = 1;
$abnormal = 1;
push @ib_array, $ibnum;
}
}
}
#If there are abnormal interfaces found after check the last section
if ( @ib_array )
if (@ib_array)
{
print "$host IB interface(s) down: ";
print $::LOG_FILE_HANDLE "$host IB interface(s) down: ";
foreach (sort @ib_array)
{
print "ib$_ " ;
print $::LOG_FILE_HANDLE "ib$_ " ;
{
print "ib$_ ";
print $::LOG_FILE_HANDLE "ib$_ ";
}
print "\n";
print $::LOG_FILE_HANDLE "\n";
}
}
#Method is "RSCT"
elsif ($::IF_CHECK_METHOD eq "RSCT")
{
@ -845,6 +855,7 @@ sub ifCheck()
{
#Get node hostname
$host = $1;
#If the host is not equal prevhost, it indicates this is beginning of a section for another node.
#If there are abnormal interfaces found after check last node, print them.
if (($host ne $prevhost) && @ib_array)
@ -852,15 +863,15 @@ sub ifCheck()
print "$prevhost IB interface(s) down: ";
print $::LOG_FILE_HANDLE "$prevhost IB interface(s) down: ";
foreach (sort @ib_array)
{
print "$_ " ;
print $::LOG_FILE_HANDLE "$_ " ;
{
print "$_ ";
print $::LOG_FILE_HANDLE "$_ ";
}
print "\n";
print $::LOG_FILE_HANDLE "\n";
@ib_array = ();
}
$prevhost = $host;
$prevhost = $host;
}
if ($line =~ /\S*:\s*Name\s*=\s*\"(.*)\"/)
{
@ -878,21 +889,22 @@ sub ifCheck()
}
}
}
#If there are abnormal interfaces found after check the last node, print them.
if (@ib_array)
{
print "$host IB interface(s) down: ";
print $::LOG_FILE_HANDLE "$host IB interface(s) down: ";
foreach (sort @ib_array)
{
print "$_ " ;
print $::LOG_FILE_HANDLE "$_ " ;
{
print "$_ ";
print $::LOG_FILE_HANDLE "$_ ";
}
print "\n";
print $::LOG_FILE_HANDLE "\n";
}
}
if(!$abnormal)
if (!$abnormal)
{
print "IB interfaces of all nodes are normal.\n";
print $::LOG_FILE_HANDLE "IB interfaces of all nodes are normal.\n";
@ -913,9 +925,9 @@ Arguments:
sub memCheckLinux()
{
my ($refLnxNodes) = @_;
my $abnormalmem = 0;
my $abnormalflp = 0;
my $ValidLnxNodes = join (",", @$refLnxNodes);
my $abnormalmem = 0;
my $abnormalflp = 0;
my $ValidLnxNodes = join(",", @$refLnxNodes);
print "\nChecking memory for nodes: $ValidLnxNodes...\n";
print $::LOG_FILE_HANDLE "Checking memory for nodes: $ValidLnxNodes...\n";
@ -928,7 +940,7 @@ sub memCheckLinux()
print "Command failed: $checkCmd.\n";
print $::LOG_FILE_HANDLE "Command failed: $checkCmd.\n";
}
my $host;
my $mem;
my $freelp;
@ -939,7 +951,7 @@ sub memCheckLinux()
{
# Get node hostname and memory size
$host = $1;
$mem = $2;
$mem = $2;
if ($mem < ($::MIN_MEMORY * 1000))
{
$abnormalmem = 1;
@ -951,7 +963,7 @@ sub memCheckLinux()
if ($line =~ /(\S*): HugePages_Free:\s*(\d+)/ && defined($::MIN_FREELP))
{
# Get node hostname and number of free large page
$host = $1;
$host = $1;
$freelp = $2;
if ($freelp < $::MIN_FREELP)
{
@ -961,12 +973,12 @@ sub memCheckLinux()
}
}
}
if(!$abnormalmem && defined($::MIN_MEMORY))
if (!$abnormalmem && defined($::MIN_MEMORY))
{
print "Memory size of all nodes are normal.\n";
print $::LOG_FILE_HANDLE "Memory size of all nodes are normal.\n"
}
if(!$abnormalflp && defined($::MIN_FREELP))
if (!$abnormalflp && defined($::MIN_FREELP))
{
print "Free large page number of all nodes are normal.\n";
print $::LOG_FILE_HANDLE "Free large page number of all nodes are normal.\n";
@ -987,20 +999,20 @@ Arguments:
sub memCheckAIX()
{
my ($refAIXNodes) = @_;
my $abnormalmem = 0;
my $abnormalflp = 0;
my $abnormalmem = 0;
my $abnormalflp = 0;
my @ValidAIXNodes;
my $allnodes = join ", ", @$refAIXNodes;
print "\nChecking memory for nodes $allnodes...\n";
print $::LOG_FILE_HANDLE "Checking memory for nodes $allnodes...\n";
@ValidAIXNodes = &checkCmdAvailability($refAIXNodes, $::AIXMemCmd);
if (!scalar (@ValidAIXNodes))
if (!scalar(@ValidAIXNodes))
{
return $::NOK;
}
my $ValidAIXNodes = join (",", @ValidAIXNodes);
my $ValidAIXNodes = join(",", @ValidAIXNodes);
my $checkCmd = "xdsh $ValidAIXNodes \"$::AIXMemCmd -l\" 2>/dev/null";
print $::LOG_FILE_HANDLE "Running command: $checkCmd.\n";
@ -1010,18 +1022,18 @@ sub memCheckAIX()
print "Command failed: $checkCmd.\n";
print $::LOG_FILE_HANDLE "Command failed: $checkCmd.\n";
}
my $host;
my $mem;
my $freelp;
foreach my $line (@output)
{
chomp $line;
chomp $line;
if ($line =~ /(\S*):\s+System Configuration: lcpu=(\d+)\s+mem=(\d+)\s*MB/ && defined($::MIN_MEMORY))
{
# Get node hostname and memory size
$host = $1;
$mem = $3;
$mem = $3;
if ($mem < $::MIN_MEMORY)
{
$abnormalmem = 1;
@ -1032,7 +1044,7 @@ sub memCheckAIX()
elsif ($line =~ /(\S*):\s*\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+(\d+)/ && defined($::MIN_FREELP))
{
# Get node hostname and number of free large page
$host = $1;
$host = $1;
$freelp = $2;
if ($freelp < $::MIN_FREELP)
{
@ -1045,7 +1057,7 @@ sub memCheckAIX()
{
# Get node hostname and memory size
$host = $1;
$mem = $3;
$mem = $3;
if ($mem < $::MIN_MEMORY)
{
$abnormalmem = 1;
@ -1054,12 +1066,12 @@ sub memCheckAIX()
}
}
}
if(!$abnormalmem && defined($::MIN_MEMORY))
if (!$abnormalmem && defined($::MIN_MEMORY))
{
print "Memory size of all nodes are normal.\n";
print $::LOG_FILE_HANDLE "Memory size of all nodes are normal.\n"
}
if(!$abnormalflp && defined($::MIN_FREELP))
if (!$abnormalflp && defined($::MIN_FREELP))
{
print "Free large page number of all nodes is normal.\n";
print $::LOG_FILE_HANDLE "Free large page number of all nodes is normal.\n";
@ -1085,14 +1097,14 @@ sub HCACheckAIX()
my $allnodes = join ", ", @$refAIXNodes;
print "\nChecking HCA status for nodes $allnodes...\n";
print $::LOG_FILE_HANDLE "Checking HCA status for nodes $allnodes...\n";
@ValidAIXNodes = &checkCmdAvailability($refAIXNodes, $::AIXHCACmd);
if (!scalar (@ValidAIXNodes))
if (!scalar(@ValidAIXNodes))
{
return $::NOK;
}
my $ValidAIXNodes = join (",", @ValidAIXNodes);
my $ValidAIXNodes = join(",", @ValidAIXNodes);
my $checkCmd = "xdsh $ValidAIXNodes \"$::AIXHCACmd -v | egrep 'IB PORT.*INFO|Port State:|Physical Port'\" 2>/dev/null";
print $::LOG_FILE_HANDLE "Running command: $checkCmd.\n";
my @output = `$checkCmd`;
@ -1101,7 +1113,7 @@ sub HCACheckAIX()
print "Command failed: $checkCmd.\n";
print $::LOG_FILE_HANDLE "Command failed: $checkCmd.\n";
}
my $host;
my $hca_id;
my $port;
@ -1110,20 +1122,24 @@ sub HCACheckAIX()
foreach my $line (@output)
{
chomp $line;
#Get host name
if ($line =~ /(\S*): (.*)/)
{
$host = $1;
}
#Get HCA ID and port number
if ($line =~ /\S*:\s*IB PORT (\d+) INFORMATION \(iba(\d+)\)/)
{
$port = $1;
$port = $1;
$hca_id = $2;
#Calculate interface number according to HCA ID and port number
$if_id = $hca_id * 2 + $port - 1;
#If the interface is in ignore list
if ( grep {$_ eq "ib$if_id"} @IgnoreList )
if (grep { $_ eq "ib$if_id" } @IgnoreList)
{
$ignore = 1;
}
@ -1133,6 +1149,7 @@ sub HCACheckAIX()
}
next;
}
#Check Logical Port State
if ($line =~ /\S*:\s*Logical Port State:\s*(\w+)/ && $ignore == 0)
{
@ -1149,6 +1166,7 @@ sub HCACheckAIX()
}
next;
}
#Check Physical Port State
if ($line =~ /\S*:\s*Physical Port State:\s*(\w+)/ && $ignore == 0)
{
@ -1165,6 +1183,7 @@ sub HCACheckAIX()
}
next;
}
#Check Physical Port Physical State
if ($line =~ /\S*:\s*Physical Port Physical State:\s*(\.+)/ && $ignore == 0)
{
@ -1181,6 +1200,7 @@ sub HCACheckAIX()
}
next;
}
#Check speed
if ($line =~ /\S*:\s*Physical Port Speed:\s*(.+)\s*G/ && $ignore == 0)
{
@ -1202,6 +1222,7 @@ sub HCACheckAIX()
}
next;
}
#Ckeck width
if ($line =~ /\S*:\s*Physical Port Width:\s*(\w+)/ && $ignore == 0)
{
@ -1224,8 +1245,9 @@ sub HCACheckAIX()
next;
}
}
#All are normal
if(!$abnormal)
if (!$abnormal)
{
print "HCA status of all nodes is normal.\n";
print $::LOG_FILE_HANDLE "HCA status of all nodes is normal.\n";
@ -1256,14 +1278,14 @@ sub HCACheckLinux()
my $allnodes = join ", ", @$refLnxNodes;
print "\nChecking HCA status for nodes: $allnodes...\n";
print $::LOG_FILE_HANDLE "Checking HCA status for nodes: $allnodes...\n";
@ValidLnxNodes = &checkCmdAvailability($refLnxNodes, $::LinuxHCACmd);
if (!scalar (@ValidLnxNodes))
if (!scalar(@ValidLnxNodes))
{
return $::NOK;
}
my $ValidLnxNodes = join (",", @ValidLnxNodes);
my $ValidLnxNodes = join(",", @ValidLnxNodes);
my $checkCmd = "xdsh $ValidLnxNodes \"$::LinuxHCACmd -v | egrep 'ehca|port:|state:|width:|speed:'\" 2>/dev/null";
print $::LOG_FILE_HANDLE "Running command: $checkCmd.\n";
my @output = `$checkCmd`;
@ -1272,7 +1294,7 @@ sub HCACheckLinux()
print "Command failed: $checkCmd.\n";
print $::LOG_FILE_HANDLE "Command failed: $checkCmd.\n";
}
my $host;
my $hca_id;
my $port;
@ -1281,25 +1303,29 @@ sub HCACheckLinux()
foreach my $line (@output)
{
chomp $line;
#Get host name
if ($line =~ /(\S*): (.*)/)
{
$host = $1;
}
#Get HCA ID
if ($line =~ /\S*:\s*hca_id:\s*ehca(\d+)/)
{
$hca_id = $1;
next;
}
#Get port number
if ($line =~ /\S*:\s*port:\s*(\d+)/)
{
#Calculate interface number according to HCA ID and port number
$port = $1;
$port = $1;
$if_id = $hca_id * 2 + $port - 1;
#If the interface is in ignore list
if ( grep {$_ eq "ib$if_id"} @IgnoreList )
if (grep { $_ eq "ib$if_id" } @IgnoreList)
{
$ignore = 1;
}
@ -1309,6 +1335,7 @@ sub HCACheckLinux()
}
next;
}
#Check state
if ($line =~ /\S*:\s*state:\s*(\w+)\s*\(.*/ && $ignore == 0)
{
@ -1325,6 +1352,7 @@ sub HCACheckLinux()
}
next;
}
#Check width
if ($line =~ /\S*:\s*active_width:\s*(\w+)\s*\(.*/ && $ignore == 0)
{
@ -1346,6 +1374,7 @@ sub HCACheckLinux()
}
next;
}
#Check speed
if ($line =~ /\S*:\s*active_speed:\s*(.+)\s*Gbps.*/ && $ignore == 0)
{
@ -1367,6 +1396,7 @@ sub HCACheckLinux()
}
next;
}
#Check Physical State
if ($line =~ /\S*:\s*phys_state:\s*(\w+)\s*\(.*/ && $ignore == 0)
{
@ -1384,8 +1414,9 @@ sub HCACheckLinux()
next;
}
}
#All are normal
if(!$abnormal)
if (!$abnormal)
{
print "HCA status of all nodes is normal.\n";
print $::LOG_FILE_HANDLE "HCA status of all nodes is normal.\n";

View File

@ -4,13 +4,13 @@
$/ = '';
open(STAT,"pbsnodes -a |") || die "pbsnodes error\n";
while(<STAT>) {
my $node = /^([a-zA-Z0-9\-]+)\b$/im ? $1 : '';
my $state = / + state = (.*)$/im ? $1 : '';
my $np = / + np = (.*)$/im ? $1 : '';
my $jobs = / + jobs = (.*)$/im ? $1 : '';
push @results, "$node: $state\t$jobs\n";
open(STAT, "pbsnodes -a |") || die "pbsnodes error\n";
while (<STAT>) {
my $node = /^([a-zA-Z0-9\-]+)\b$/im ? $1 : '';
my $state = / + state = (.*)$/im ? $1 : '';
my $np = / + np = (.*)$/im ? $1 : '';
my $jobs = / + jobs = (.*)$/im ? $1 : '';
push @results, "$node: $state\t$jobs\n";
}
print @results;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
#!/usr/bin/env perl
# generate the image for mic
# generate the image for mic
# Since the root file system for mic is generated on the host by
# micctrl command, this script only help to generate the /etc/hosts,
# /root/.ssh from the management node to the root file system.
@ -41,29 +41,29 @@ my $prompt;
my $imagename;
GetOptions(
'a=s' => \$arch,
'p=s' => \$profile,
'o=s' => \$osver,
'pkglist=s' => \$pkglist,
'srcdir=s' => \$srcdir,
'otherpkglist=s' => \$otherpkglist,
'otherpkgdir=s' => \$srcdir_otherpkgs,
'tempfile=s' => \$tempfile,
'postinstall=s' => \$postinstall,
'rootimgdir=s' => \$rootimgdir,
'imagename=s' => \$imagename,
'interactive' =>\$prompt,
'a=s' => \$arch,
'p=s' => \$profile,
'o=s' => \$osver,
'pkglist=s' => \$pkglist,
'srcdir=s' => \$srcdir,
'otherpkglist=s' => \$otherpkglist,
'otherpkgdir=s' => \$srcdir_otherpkgs,
'tempfile=s' => \$tempfile,
'postinstall=s' => \$postinstall,
'rootimgdir=s' => \$rootimgdir,
'imagename=s' => \$imagename,
'interactive' => \$prompt,
);
if ($rootimgdir) {
$rootimg_dir = $rootimgdir."/rootimg"; # for 2.8.4 and later
$rootimg_dir = $rootimgdir . "/rootimg"; # for 2.8.4 and later
} else {
$rootimg_dir = "$srcdir/overlay/package"; # for 2.8.3 that rootimgdir was not set by default
$rootimg_dir = "$srcdir/overlay/package"; # for 2.8.3 that rootimgdir was not set by default
}
my @yumdirs;
if (!$imagename && @ARGV > 0) {
$imagename=$ARGV[0];
$imagename = $ARGV[0];
}
unless ($imagename) {
print "Error: osimage name needs be specified.\n";
@ -71,11 +71,11 @@ unless ($imagename) {
}
sub isyumdir {
if ($File::Find::name =~ /\/repodata$/) {
my $location = $File::Find::name;
$location =~ s/\/repodata$//;
push @yumdirs,$location;
}
if ($File::Find::name =~ /\/repodata$/) {
my $location = $File::Find::name;
$location =~ s/\/repodata$//;
push @yumdirs, $location;
}
}
# creae default paths
@ -93,183 +93,186 @@ if ($otherpkglist) {
print "Error: Cannot open table osimage.\n";
return 1;
}
# generate the yum configuration file
my $aiddistro;
my $oient = $oitab->getAttribs({'imagename'=>$imagename}, 'osdistroname');
my $oient = $oitab->getAttribs({ 'imagename' => $imagename }, 'osdistroname');
if ($oient && $oient->{'osdistroname'}) {
$aiddistro = $oient->{'osdistroname'};
}
my $distrotab = xCAT::Table->new('osdistro');
unless ($distrotab) {
print "Error: Cannot open table osdistro.\n";
return 1;
}
my $aiddistrodir;
my $distroent = $distrotab->getAttribs({'osdistroname'=>$aiddistro}, 'dirpaths');
my $distroent = $distrotab->getAttribs({ 'osdistroname' => $aiddistro }, 'dirpaths');
if ($distroent && $distroent->{'dirpaths'}) {
$aiddistrodir = $distroent->{'dirpaths'}
}
my @pkgdirs = split(",", $aiddistrodir);
my @pkgdirs = split(",", $aiddistrodir);
foreach my $dir (@pkgdirs) {
find(\&isyumdir, <$dir/>);
if (!grep /$dir/, @yumdirs) {
print "The repository for $dir should be created before running the genimge. Try to run [createrepo $dir].\n";
}
find(\&isyumdir, <$dir/>);
if (!grep /$dir/, @yumdirs) {
print "The repository for $dir should be created before running the genimge. Try to run [createrepo $dir].\n";
}
}
my $yumconfig;
open($yumconfig,">","/tmp/genimage.$$.yum.conf");
my $repnum=0;
open($yumconfig, ">", "/tmp/genimage.$$.yum.conf");
my $repnum = 0;
foreach $srcdir (@yumdirs) {
print $yumconfig "[$aiddistro-$repnum]\nname=$aiddistro-$repnum\nbaseurl=file://$srcdir\ngpgpcheck=0\n\n";
$repnum += 1;
print $yumconfig "[$aiddistro-$repnum]\nname=$aiddistro-$repnum\nbaseurl=file://$srcdir\ngpgpcheck=0\n\n";
$repnum += 1;
}
$repnum-=1;
$repnum -= 1;
close($yumconfig);
mkpath "$rootimg_dir/etc";
my %extra_hash = imgutils::get_package_names($otherpkglist);
my %extrapkgnames;
my %extrapkgnames;
my %repohash;
if (keys(%extra_hash) > 0) {
open($yumconfig,">>","/tmp/genimage.$$.yum.conf");
my $index=1;
my $pass;
foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) {
foreach (keys(%{$extra_hash{$pass}})) {
if($_ eq "INCLUDEBAD") {
print "Unable to open the following pkglist files:\n".join("\n",@{$extra_hash{$pass}{INCLUDEBAD}});
exit 1;
open($yumconfig, ">>", "/tmp/genimage.$$.yum.conf");
my $index = 1;
my $pass;
foreach $pass (sort { $a <=> $b } (keys(%extra_hash))) {
foreach (keys(%{ $extra_hash{$pass} })) {
if ($_ eq "INCLUDEBAD") {
print "Unable to open the following pkglist files:\n" . join("\n", @{ $extra_hash{$pass}{INCLUDEBAD} });
exit 1;
}
if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next; }
print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=file://$srcdir_otherpkgs/$_\ngpgpcheck=0\n\n";
$repohash{$pass}{$index} = 1;
$index++;
my $pa = $extra_hash{$pass}{$_};
$extrapkgnames{$pass} .= " " . join(' ', @$pa);
}
}
close($yumconfig);
$index--;
my $yumcmd_base = "yum -y -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* ";
foreach (0 .. $repnum) {
$yumcmd_base .= "--enablerepo=$aiddistro-$_ ";
}
foreach $pass (sort { $a <=> $b } (keys(%extra_hash))) {
my $yumcmd = $yumcmd_base;
foreach my $repo_index (keys %{ $repohash{$pass} }) {
$yumcmd .= "--enablerepo=otherpkgs$repo_index ";
}
if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;}
print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=file://$srcdir_otherpkgs/$_\ngpgpcheck=0\n\n";
$repohash{$pass}{$index} = 1;
$index++;
my $pa=$extra_hash{$pass}{$_};
$extrapkgnames{$pass} .= " " . join(' ', @$pa);
system("$yumcmd clean all");
my $envlist;
if (exists($extra_hash{$pass}{ENVLIST})) {
$envlist = join(' ', @{ $extra_hash{$pass}{ENVLIST} });
}
# remove the packages that are specified in the otherpkgs.list files with leading '-'
my $yumcmd_remove = "$yumcmd erase ";
if (exists($extra_hash{$pass}{'PRE_REMOVE'})) {
my $pa = $extra_hash{$pass}{'PRE_REMOVE'};
my $rm_packges = join(' ', @$pa);
if ($rm_packges) {
print "$envlist $yumcmd_remove $rm_packges\n";
my $rc = system("$envlist $yumcmd_remove $rm_packges");
if ($rc) {
print "yum invocation failed\n";
exit 1;
}
}
}
# install extra packages
$yumcmd .= "install ";
# append extra pkg names to yum command
if ($extrapkgnames{$pass}) {
$yumcmd .= " $extrapkgnames{$pass} ";
$yumcmd =~ s/ $/\n/;
print "$envlist $yumcmd\n";
my $rc = system("$envlist $yumcmd");
if ($rc) {
print "yum invocation failed\n";
exit 1;
}
} else {
print "No Packages marked for install\n";
}
# remove the packages that are specified in the otherpkgs.list files with leading '--'
if (exists($extra_hash{$pass}{'POST_REMOVE'})) {
my $pa = $extra_hash{$pass}{'POST_REMOVE'};
my $rm_packges = join(' ', @$pa);
if ($rm_packges) {
print "$envlist $yumcmd_remove $rm_packges\n";
my $rc = system("$envlist $yumcmd_remove $rm_packges");
if ($rc) {
print "yum invocation failed\n";
exit 1;
}
}
}
}
}
close($yumconfig);
$index--;
my $yumcmd_base = "yum -y -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* ";
foreach (0..$repnum) {
$yumcmd_base .= "--enablerepo=$aiddistro-$_ ";
}
foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) {
my $yumcmd = $yumcmd_base;
foreach my $repo_index ( keys %{$repohash{$pass}} ) {
$yumcmd .= "--enablerepo=otherpkgs$repo_index ";
}
system("$yumcmd clean all");
my $envlist;
if(exists($extra_hash{$pass}{ENVLIST})){
$envlist = join(' ', @{$extra_hash{$pass}{ENVLIST}});
}
# remove the packages that are specified in the otherpkgs.list files with leading '-'
my $yumcmd_remove= "$yumcmd erase ";
if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) {
my $pa=$extra_hash{$pass}{'PRE_REMOVE'};
my $rm_packges= join(' ', @$pa);
if ($rm_packges) {
print "$envlist $yumcmd_remove $rm_packges\n";
my $rc = system("$envlist $yumcmd_remove $rm_packges");
if ($rc) {
print "yum invocation failed\n";
exit 1;
}
}
}
# install extra packages
$yumcmd .= "install ";
# append extra pkg names to yum command
if ($extrapkgnames{$pass}) {
$yumcmd .= " $extrapkgnames{$pass} ";
$yumcmd =~ s/ $/\n/;
print "$envlist $yumcmd\n";
my $rc = system("$envlist $yumcmd");
if ($rc) {
print "yum invocation failed\n";
exit 1;
}
} else {
print "No Packages marked for install\n";
}
# remove the packages that are specified in the otherpkgs.list files with leading '--'
if (exists ($extra_hash{$pass}{'POST_REMOVE'})) {
my $pa=$extra_hash{$pass}{'POST_REMOVE'};
my $rm_packges= join(' ', @$pa);
if ($rm_packges) {
print "$envlist $yumcmd_remove $rm_packges\n";
my $rc = system("$envlist $yumcmd_remove $rm_packges");
if ($rc) {
print "yum invocation failed\n";
exit 1;
}
}
}
}
}
}
# run postinstall scripts
foreach my $post ( split /,/, $postinstall) {
if ( !-x $post) {
foreach my $post (split /,/, $postinstall) {
if (!-x $post) {
print "postinstall script $post is not executable\n";
exit 1;
}
my $rc = system($postinstall, $rootimg_dir, $osver, $arch, $profile);
if($rc) {
if ($rc) {
print "postinstall script $post failed\n";
exit 1;
}
}
my $fsdir = "$srcdir/";
my $fsdir = "$srcdir/";
my $systemdir = "$fsdir/system";
mkpath ($systemdir);
mkpath($systemdir);
# this is the file list which includes the files which should be copied
# this is the file list which includes the files which should be copied
# from MN to the root file system
my @sysfilelist = (
"/etc/hosts",
"/etc/group",
"/etc/passwd",
"/etc/shadow",
"/etc/resolv.conf",
"/etc/nsswitch.conf",
"/etc/ssh/ssh_host_rsa_key",
"/etc/ssh/ssh_config",
"/etc/ssh/sshd_config",
"/etc/ssh/ssh_host_dsa_key",
"/root/.ssh/id_rsa",
"/root/.ssh/id_rsa.pub",
"/root/.ssh/authorized_keys",);
"/etc/hosts",
"/etc/group",
"/etc/passwd",
"/etc/shadow",
"/etc/resolv.conf",
"/etc/nsswitch.conf",
"/etc/ssh/ssh_host_rsa_key",
"/etc/ssh/ssh_config",
"/etc/ssh/sshd_config",
"/etc/ssh/ssh_host_dsa_key",
"/root/.ssh/id_rsa",
"/root/.ssh/id_rsa.pub",
"/root/.ssh/authorized_keys",);
# do the copy
foreach my $file (@sysfilelist) {
my $dirname = dirname("$systemdir/$file");
unless (-d $dirname) {
mkpath ($dirname);
mkpath($dirname);
}
copy ($file, "$systemdir/$file");
copy($file, "$systemdir/$file");
}
# Create emtpy common dir and common.filelist for later using
mkpath ("$fsdir/common");
system ("touch $fsdir/common.filelist");
mkpath("$fsdir/common");
system("touch $fsdir/common.filelist");
print "Genimage for mic has been done.\n";

Some files were not shown because too many files have changed in this diff Show More