2008-02-08 17:59:49 +00:00
|
|
|
#!/usr/bin/env perl
|
|
|
|
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
2008-02-16 01:25:59 +00:00
|
|
|
|
2008-02-08 17:59:49 +00:00
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
=head1 mkrmcresources
|
|
|
|
=head2 mkrmcresources is used to predefine RMC conditions, responses, associations,
|
|
|
|
sensors (and can be extended to support any RSCT resource
|
|
|
|
class).
|
|
|
|
To use the command, create perl modules in a directory. Each resource
|
|
|
|
should have its own perl module (so that it is easy to update a
|
|
|
|
resource without interfering with other resources),
|
|
|
|
and should be named <Resource Name>.pm.
|
|
|
|
After the resource perl modules are installed, they will be created
|
|
|
|
by the next execution of the this command.
|
|
|
|
This command should be called by the post install scripts
|
|
|
|
of packaging files, script run after install or from the command line.
|
|
|
|
=cut
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
use Getopt::Long;
|
|
|
|
|
|
|
|
|
|
|
|
$Getopt::Long::ignorecase = 0; #Checks case in GetOptions
|
|
|
|
Getopt::Long::Configure("bundling"); #allows short command line options to be grouped (e.g. -av)
|
|
|
|
|
2008-02-16 01:25:59 +00:00
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
=head3 quote
|
|
|
|
Quote a string, taking into account embedded quotes. This function is most
|
|
|
|
useful when passing string through the shell to another cmd. It handles one
|
|
|
|
level of embedded double quotes, single quotes, and dollar signs.
|
|
|
|
Arguments:
|
|
|
|
string to quote
|
|
|
|
Returns:
|
|
|
|
quoted string
|
|
|
|
Globals:
|
|
|
|
none
|
|
|
|
Error:
|
|
|
|
none
|
|
|
|
Example:
|
|
|
|
Comments:
|
|
|
|
none
|
|
|
|
=cut
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
sub quote
|
|
|
|
{
|
|
|
|
my ($str) = @_;
|
|
|
|
|
|
|
|
# if the value has imbedded double quotes, use single quotes. If it also has
|
|
|
|
# single quotes, escape the double quotes.
|
|
|
|
if (!($str =~ /\"/)) # no embedded double quotes
|
|
|
|
{
|
|
|
|
$str =~ s/\$/\\\$/sg; # escape the dollar signs
|
|
|
|
$str =~ s/\`/\\\`/sg;
|
|
|
|
$str = qq("$str");
|
|
|
|
}
|
|
|
|
elsif (!($str =~ /\'/))
|
|
|
|
{
|
|
|
|
$str = qq('$str');
|
|
|
|
} # no embedded single quotes
|
|
|
|
else # has both embedded double and single quotes
|
|
|
|
{
|
|
|
|
# Escape the double quotes. (Escaping single quotes does not seem to work
|
|
|
|
# in the shells.)
|
|
|
|
$str =~ s/\"/\\\"/sg; #" this comment helps formating
|
|
|
|
$str =~ s/\$/\\\$/sg; # escape the dollar signs
|
|
|
|
$str =~ s/\`/\\\`/sg;
|
|
|
|
$str = qq("$str");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
=head3 filterRmcApiOutput
|
|
|
|
filter RMC Api Output
|
|
|
|
Arguments:
|
|
|
|
RMC command
|
|
|
|
Output reference
|
|
|
|
Returns:
|
|
|
|
none
|
|
|
|
Globals:
|
|
|
|
none
|
|
|
|
Error:
|
|
|
|
none
|
|
|
|
Example:
|
|
|
|
filterRmcApiOutput($cmd, $outref);
|
|
|
|
Comments:
|
|
|
|
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 ($::VERBOSE || !($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}//;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub isHMC
|
|
|
|
{
|
|
|
|
my $hmcfile = "/opt/hsc/data/hmcType.properties";
|
|
|
|
if (-e $hmcfile) { return 1; }
|
|
|
|
else { return 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
|
|
|
|
with the newlines separating the lines.
|
|
|
|
Arguments:
|
|
|
|
command, exitcode and reference to output
|
|
|
|
Returns:
|
|
|
|
see below
|
|
|
|
Error:
|
|
|
|
Normally, if there is an error running the cmd, it will display the error msg
|
|
|
|
and exit with the cmds exit code, unless exitcode is given one of the
|
|
|
|
following values:
|
|
|
|
0: display error msg, DO NOT exit on error, but set
|
|
|
|
$::RUNCMD_RC to the exit code.
|
|
|
|
-1: DO NOT display error msg and DO NOT exit on error, but set
|
|
|
|
$::RUNCMD_RC to the exit code.
|
|
|
|
-2: DO the default behavior (display error msg and exit with cmds
|
|
|
|
exit code.
|
|
|
|
number > 0: Display error msg and exit with the given code
|
|
|
|
Example:
|
|
|
|
my $outref = runcmd($cmd, -2, 1);
|
|
|
|
Comments:
|
|
|
|
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 (!$::NO_STDERR_REDIRECT) {
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
{
|
|
|
|
my $line = join('', @$outref);
|
|
|
|
chomp $line;
|
|
|
|
return $line;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
=head3 runrmccmd
|
|
|
|
Runs an RMC commmand
|
|
|
|
Arguments:
|
|
|
|
$rmccmd, $resclass, $options, $select, $exitcode, $nodelist_ref
|
|
|
|
Returns:
|
|
|
|
the output from runcmd($cmd, -2, 1)
|
|
|
|
as a ref to the output array.
|
|
|
|
Error:
|
|
|
|
none
|
|
|
|
Example:
|
|
|
|
my $outref =runrmccmd('lsrsrc-api', "-i -D ':|:'", $where);
|
|
|
|
Comments:
|
|
|
|
When $nodelist_ref is not null, break it up into smaller slices
|
|
|
|
and run RMC commands seperately for each slice.
|
|
|
|
Otherwise just run RMC commands with the arguments passed in.
|
|
|
|
=cut
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
sub runrmccmd
|
|
|
|
{
|
|
|
|
my ($rmccmd, $options, $select, $exitcode, $nodelist_ref) = @_;
|
|
|
|
|
|
|
|
my @nodelist;
|
|
|
|
my $return_ref = [];
|
|
|
|
|
|
|
|
if (!defined($exitcode))
|
|
|
|
{
|
|
|
|
$exitcode = -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(! grep /usr\/bin/, $rmccmd)
|
|
|
|
{
|
|
|
|
# add absolute path
|
|
|
|
$rmccmd = "/usr/bin/$rmccmd";
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($nodelist_ref)
|
|
|
|
{
|
|
|
|
# check whether to break up nodelist for better scalability.
|
|
|
|
@nodelist = @$nodelist_ref;
|
|
|
|
my $divide = 500; # max number of nodes for each division
|
|
|
|
my @sublist;
|
|
|
|
my @newarray;
|
|
|
|
my ($start_index, $end_index, $nodestring);
|
|
|
|
|
|
|
|
my $count = 0;
|
|
|
|
my $times = int(scalar(@nodelist) / $divide);
|
|
|
|
while ($count <= $times)
|
|
|
|
{
|
|
|
|
$start_index = $count * $divide;
|
|
|
|
$end_index =
|
|
|
|
((scalar(@nodelist) - 1) < (($count + 1) * $divide - 1))
|
|
|
|
? (scalar(@nodelist) - 1)
|
|
|
|
: (($count + 1) * $divide - 1);
|
|
|
|
@sublist = @nodelist[$start_index .. $end_index];
|
|
|
|
@newarray = ();
|
|
|
|
foreach my $node (@sublist)
|
|
|
|
{
|
|
|
|
my @vals = split ',|\s', $node;
|
|
|
|
push @newarray, @vals;
|
|
|
|
}
|
|
|
|
$nodestring = join("','", @newarray);
|
|
|
|
|
|
|
|
# replace the pattern in select string with the broken up node string
|
|
|
|
my $select_new = $select;
|
|
|
|
$select_new =~ s/XXX/$nodestring/;
|
|
|
|
my $cmd = "$rmccmd $options $select_new";
|
|
|
|
my $outref = runcmd($cmd, $exitcode, 1);
|
|
|
|
push @$return_ref, @$outref;
|
|
|
|
$count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
my $cmd = "$rmccmd $options $select";
|
|
|
|
$return_ref = runcmd($cmd, $exitcode, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
# returns a reference to the output array
|
|
|
|
return $return_ref;
|
|
|
|
}
|
|
|
|
|
2008-02-08 17:59:49 +00:00
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
=head3 queryResources
|
|
|
|
Queries all resources of a given class or classes. Places
|
|
|
|
results into a global hash for each resource class.
|
|
|
|
Arguments: a list of RSCT resource classes
|
|
|
|
Globals: %::EXISTS::{$resource}
|
|
|
|
=cut
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
sub queryResources
|
|
|
|
{
|
|
|
|
my @resources = @_;
|
|
|
|
|
|
|
|
my $where = "";
|
|
|
|
foreach my $res (@resources)
|
|
|
|
{
|
|
|
|
if ($res eq "IBM.Association")
|
|
|
|
{
|
|
|
|
#special case: run lscondresp because Associations do not have names
|
|
|
|
#cant run lsrsrc because Assoctation also does not store names of resources (just handles)
|
2008-02-16 01:25:59 +00:00
|
|
|
my @condresp = runcmd("LANG=C /usr/bin/lscondresp");
|
2008-02-08 17:59:49 +00:00
|
|
|
my $class = $res;
|
|
|
|
$class =~ s/^IBM\.//;
|
|
|
|
splice @condresp, 0,
|
|
|
|
2; #delete first two lines -- they are just comments
|
|
|
|
foreach my $line (@condresp)
|
|
|
|
{
|
|
|
|
my ($condition, $response, $node, $state) = split ' ', $line;
|
|
|
|
$condition = &removeQuotes($condition);
|
|
|
|
$response = &removeQuotes($response);
|
|
|
|
my $key = "${condition}:_:${response}";
|
|
|
|
my $ActiveFlag = 0; #assume offline
|
|
|
|
if ($state =~ m/Active/)
|
|
|
|
{
|
|
|
|
$ActiveFlag = 1;
|
|
|
|
}
|
|
|
|
#currently does not checked for locked
|
|
|
|
# This \%{typeglob} syntax auto-vivifies
|
|
|
|
# the hash table for us, and gives us a reference.
|
|
|
|
my $ref = \%{$::EXISTS::{$class}};
|
|
|
|
$ref->{$key} = {ActiveFlag => $ActiveFlag,};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$where .= " -s ${res}::::'*p0x0020'";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-02-16 01:25:59 +00:00
|
|
|
my $output = runrmccmd("lsrsrc-api", "-i -m -n -D ':|:'", $where);
|
2008-02-08 17:59:49 +00:00
|
|
|
foreach my $line (@$output)
|
|
|
|
{
|
|
|
|
my @array = split(/:\|:/, $line);
|
|
|
|
my $class = shift @array; #the -m flag puts the class name in front
|
|
|
|
$class =~ s/^IBM\.//;
|
|
|
|
my %attrs = @array;
|
|
|
|
# This \%{typeglob} syntax auto-vivifies
|
|
|
|
# the hash table for us, and gives us a reference.
|
|
|
|
my $ref = \%{$::EXISTS::{$class}};
|
|
|
|
my $key = $attrs{'Name'};
|
|
|
|
$ref->{$key} = {%attrs}; #sets the EXISTS array with the info
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
=head3 traverseDirectories
|
|
|
|
Calls readFiles on each sub-directory of the given path.
|
|
|
|
Creates a global array with all target resource classes.
|
|
|
|
Arguments: A directory
|
|
|
|
Globals: @::DIRECTORIES (will hold all resource classes)
|
|
|
|
=cut
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
sub traverseDirectories
|
|
|
|
{
|
|
|
|
my ($dir) = @_;
|
|
|
|
my ($dir_fh, $file);
|
|
|
|
|
|
|
|
opendir($dir_fh, $dir)
|
|
|
|
or die "Can not open directory $dir\n";
|
|
|
|
while ($file = readdir($dir_fh))
|
|
|
|
{
|
|
|
|
if ($file ne '.' and $file ne '..')
|
|
|
|
{
|
|
|
|
my $subdir = "$dir/$file";
|
|
|
|
if (-d $subdir)
|
|
|
|
{ #only look at directories
|
|
|
|
&readFiles($subdir);
|
|
|
|
push @::DIRECTORIES, $file; #file=just the filename
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir($dir_fh)
|
|
|
|
or die "Can not close directory $dir\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
=head3 readFiles
|
|
|
|
Calls require on all .pm files in a given directory
|
|
|
|
Arguments: A directory
|
|
|
|
=cut
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
sub readFiles
|
|
|
|
{
|
|
|
|
my ($dir) = @_;
|
|
|
|
my ($dir_fh, $file);
|
|
|
|
opendir($dir_fh, $dir)
|
|
|
|
or die "Can not open directory $dir\n";
|
|
|
|
while ($file = readdir($dir_fh))
|
|
|
|
{
|
|
|
|
if ($file ne '.' and $file ne '..')
|
|
|
|
{
|
|
|
|
$file = "$dir/$file";
|
|
|
|
if ($file =~ m/\.pm$/)
|
|
|
|
{
|
|
|
|
#its a perl module
|
|
|
|
require $file;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir($dir_fh)
|
|
|
|
or die "Can not close directory $dir\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
=head3 compareResources
|
|
|
|
Compares existing resources to those requiring definition.
|
|
|
|
Globals: uses %::EXISTS and %::RES and makes %::CHANGE and %::CREATE
|
|
|
|
=cut
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
sub compareResources
|
|
|
|
{
|
|
|
|
foreach my $class (@::DIRECTORIES)
|
|
|
|
{ #this has all subdirectory names
|
|
|
|
$class =~ s/^IBM\.//; #the IBM prefix is not used in the hash name
|
|
|
|
local *exi = $::EXISTS::{$class}; #defined on system
|
|
|
|
local *res = $::RES::{$class}; #defined in file
|
|
|
|
foreach my $resource (keys %res)
|
|
|
|
{
|
|
|
|
if (defined $exi{$resource})
|
|
|
|
{ #exists on the system
|
|
|
|
if (defined $res{$resource}{'Locked'}
|
|
|
|
&& $res{$resource}{'Locked'} == 1)
|
|
|
|
{
|
|
|
|
#only change the resource if it is supposed to be locked
|
|
|
|
foreach my $attr (keys %{$res{$resource}})
|
|
|
|
{
|
|
|
|
if ($exi{$resource}{$attr} ne $res{$resource}{$attr})
|
|
|
|
{
|
|
|
|
if (!($class eq "Association" && $attr eq "Locked"))
|
|
|
|
{ # association locked attrs are not stored
|
|
|
|
# something has changed
|
|
|
|
if ($::VERBOSE)
|
|
|
|
{
|
|
|
|
print "Differs: Class=$class\tExists=$exi{$resource}{$attr}\tDefined=$res{$resource}{$attr}\n";
|
|
|
|
}
|
|
|
|
$::CHANGE::{$class}{$resource} = $res{$resource};
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ #resource is not defined on the system
|
|
|
|
$::CREATE::{$class}{$resource} = $res{$resource};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
=head3 removeQuotes
|
|
|
|
removes starting and ending quotes that are in the output of lsrsrc
|
|
|
|
Arguments: string
|
|
|
|
Returns: string with no leading or trailing quotes
|
|
|
|
=cut
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
sub removeQuotes
|
|
|
|
{
|
|
|
|
my ($string) = @_;
|
|
|
|
$string =~ s/^\"|^\'//;
|
|
|
|
$string =~ s/\"$|\'$//;
|
|
|
|
return $string;
|
|
|
|
}
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
=head3 createResources
|
|
|
|
Calls mkrsrc-api on all resources in the %::CREATE hash
|
|
|
|
Globals: %::CREATE
|
|
|
|
=cut
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
sub createResources
|
|
|
|
{
|
|
|
|
my $string;
|
|
|
|
my $counter = 0;
|
|
|
|
my @assoc_cmds;
|
|
|
|
my $sensorflg = 0;
|
|
|
|
foreach my $class (@::DIRECTORIES)
|
|
|
|
{ #all the class names
|
|
|
|
local *cre = $::CREATE::{$class};
|
|
|
|
if ($class eq "Sensor")
|
|
|
|
{
|
|
|
|
$sensorflg = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$sensorflg = 0;
|
|
|
|
}
|
|
|
|
foreach my $resource (keys %cre)
|
|
|
|
{
|
|
|
|
if ($class eq "Association")
|
|
|
|
{ #special case
|
|
|
|
my ($cond, $resp) = split ":_:", $resource;
|
|
|
|
if ($cre{$resource}{'ActiveFlag'} == 1)
|
|
|
|
{
|
|
|
|
push @assoc_cmds, "/usr/bin/startcondresp $cond $resp";
|
|
|
|
if ($cre{$resource}{'Locked'} == 1)
|
|
|
|
{
|
|
|
|
push @assoc_cmds, "/usr/bin/startcondresp -L $cond $resp";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ #not active
|
|
|
|
push @assoc_cmds, "/usr/bin/mkcondresp $cond $resp";
|
|
|
|
#no need to lock stopped associations
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$string .= " IBM.${class}::";
|
|
|
|
foreach my $attr (keys %{$cre{$resource}})
|
|
|
|
{
|
|
|
|
my $value = $cre{$resource}{$attr};
|
2008-02-16 01:25:59 +00:00
|
|
|
$string .= "${attr}::" . quote($value) . "::";
|
2008-02-08 17:59:49 +00:00
|
|
|
}
|
|
|
|
if (($sensorflg == 1) && ($::INSTALL))
|
|
|
|
{
|
|
|
|
# make the Sensor with no userid check
|
|
|
|
$string .= "::Options::1";
|
|
|
|
}
|
|
|
|
#
|
|
|
|
# Only build up to 10 resources at a pass
|
|
|
|
# to avoid command line limit
|
|
|
|
#
|
|
|
|
$counter = $counter + 1;
|
|
|
|
if ($counter > 10)
|
|
|
|
{
|
|
|
|
if ($string =~ m/\w+/)
|
|
|
|
{
|
|
|
|
#my $cmd = "/usr/bin/mkrsrc-api $string";
|
|
|
|
#print "running $cmd\n";
|
|
|
|
#system($cmd);
|
2008-02-16 01:25:59 +00:00
|
|
|
runrmccmd("mkrsrc-api", "", $string);
|
2008-02-08 17:59:49 +00:00
|
|
|
$string = "";
|
|
|
|
$counter = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($string =~ m/\w+/) # for any remaining resources
|
|
|
|
{
|
|
|
|
#my $cmd = "/usr/bin/mkrsrc-api $string";
|
|
|
|
#print "running $cmd\n";
|
|
|
|
#system($cmd);
|
2008-02-16 01:25:59 +00:00
|
|
|
runrmccmd("mkrsrc-api", "", $string);
|
2008-02-08 17:59:49 +00:00
|
|
|
}
|
|
|
|
foreach my $cmd (@assoc_cmds)
|
|
|
|
{
|
|
|
|
#need to make associations after conds and resps have been made
|
2008-02-16 01:25:59 +00:00
|
|
|
runcmd("$cmd");
|
2008-02-08 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
=head3 changeResources
|
|
|
|
Calls chrsrc-api on all resources in the %::CHANGE hash
|
|
|
|
Globals: %::CHANGE
|
|
|
|
=cut
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
sub changeResources
|
|
|
|
{
|
|
|
|
my $string;
|
|
|
|
my $ustring; #unlock
|
|
|
|
my @unlock; #unlock each class
|
|
|
|
my $where; #unlock each class
|
|
|
|
foreach my $class (@::DIRECTORIES)
|
|
|
|
{ #all the class names
|
|
|
|
local *cha = $::CHANGE::{$class};
|
|
|
|
foreach my $resource (keys %cha)
|
|
|
|
{
|
|
|
|
if ($class eq "Association")
|
|
|
|
{ #special case
|
|
|
|
#code here is identical to createResource
|
|
|
|
my ($cond, $resp) = split ":_:", $resource;
|
|
|
|
if ($cre{$resource}{'ActiveFlag'} == 1)
|
|
|
|
{
|
2008-02-16 01:25:59 +00:00
|
|
|
runcmd("/usr/bin/startcondresp $cond $resp");
|
2008-02-08 17:59:49 +00:00
|
|
|
if ($cre{$resource}{'Locked'} == 1)
|
|
|
|
{
|
2008-02-16 01:25:59 +00:00
|
|
|
runcmd( "/usr/bin/startcondresp -L $cond $resp");
|
2008-02-08 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ #not active
|
2008-02-16 01:25:59 +00:00
|
|
|
runcmd("/usr/bin/mkcondresp $cond $resp");
|
2008-02-08 17:59:49 +00:00
|
|
|
#no need to lock stopped associations
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else # not class association
|
|
|
|
{
|
|
|
|
$where = qq/"Name IN ('XXX')"/;
|
|
|
|
$string .= " -s IBM.${class}::${where}::";
|
|
|
|
push @unlock, $cha{$resource}{'Name'};
|
|
|
|
delete $cha{$resource}{'Name'};
|
|
|
|
foreach my $attr (keys %{$cha{$resource}})
|
|
|
|
{
|
|
|
|
my $value = $cha{$resource}{$attr};
|
2008-02-16 01:25:59 +00:00
|
|
|
$string .= "${attr}::" . quote($value) . "::";
|
2008-02-08 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (@unlock)
|
|
|
|
{
|
|
|
|
$where = qq/"Name IN ('XXX')"/;
|
|
|
|
$ustring .= " -s IBM.${class}::${where}::Locked::'0'";
|
|
|
|
}
|
|
|
|
} # foreach resource
|
|
|
|
} # foreach key
|
|
|
|
#
|
|
|
|
# although @unlock contains the resource and not the node name
|
|
|
|
# this is a hack to use runrmccmd and the node_ref must
|
|
|
|
# be provided even though we are not really dealing with nodes
|
|
|
|
# here
|
|
|
|
|
|
|
|
if ($ustring =~ m/\w+/) {
|
2008-02-16 01:25:59 +00:00
|
|
|
runrmccmd("chrsrc-api", "", $ustring, undef, \@unlock);
|
2008-02-08 17:59:49 +00:00
|
|
|
}
|
|
|
|
if ($string =~ m/\w+/) {
|
2008-02-16 01:25:59 +00:00
|
|
|
runrmccmd("chrsrc-api", "", $string, undef, \@unlock);
|
2008-02-08 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
=head3 writeAllFiles
|
|
|
|
creates all files for the given resources classes
|
|
|
|
Arguments: a array ref of class names, basedir
|
|
|
|
=cut
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
sub writeAllFiles
|
|
|
|
{
|
|
|
|
my @classes = @{shift()};
|
|
|
|
my $basedir = shift;
|
|
|
|
print "classes=@classes, basedir=$basedir";
|
|
|
|
foreach my $class (@classes)
|
|
|
|
{
|
2008-02-16 01:25:59 +00:00
|
|
|
my $output = runrmccmd("lsrsrc-api", "-i", "-s ${class}::::Name");
|
2008-02-08 17:59:49 +00:00
|
|
|
foreach my $line (@$output)
|
|
|
|
{
|
|
|
|
&writeFile("${class}::$line", $basedir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
=head3 writeFile
|
|
|
|
creates a file with the resource info in
|
|
|
|
$basedir/<class>
|
|
|
|
Arguments: class::resource_name, basedir
|
|
|
|
=cut
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
sub writeFile
|
|
|
|
{
|
|
|
|
my $input = shift;
|
|
|
|
my $basedir= shift;
|
|
|
|
print "input=$input, basedir=$basedir\n";
|
|
|
|
|
|
|
|
my ($class, $resourcefilename) = split "::", $input;
|
|
|
|
if (!$resourcefilename) {
|
|
|
|
print 'mkrmcresource --mkfile requires <class::resource> as input.\n';
|
|
|
|
exit 1;
|
|
|
|
}
|
|
|
|
my $resource;
|
|
|
|
push(@$resource, $resourcefilename);
|
|
|
|
|
|
|
|
if (!-e "$basedir/$class") {
|
|
|
|
`mkdir -p "$basedir/$class"`;
|
|
|
|
}
|
|
|
|
my $file = "$basedir/$class/$resourcefilename.pm";
|
|
|
|
my $where = qq/"Name IN ('XXX')"/;
|
|
|
|
my $string = " -s ${class}::${where}::*p0x0002";
|
2008-02-16 01:25:59 +00:00
|
|
|
my $output = runrmccmd("lsrsrc-api", "-i -n -D ':|:'",
|
2008-02-08 17:59:49 +00:00
|
|
|
$string, undef, $resource);
|
|
|
|
$string = " -s ${class}::${where}::*p0x0008";
|
2008-02-16 01:25:59 +00:00
|
|
|
my $optional = runrmccmd("lsrsrc-api", "-i -n -D ':|:'",
|
2008-02-08 17:59:49 +00:00
|
|
|
$string, undef, $resource);
|
|
|
|
|
2008-02-16 01:25:59 +00:00
|
|
|
#my @output = runcmd("/usr/bin/lsrsrc -s $where $class");
|
2008-02-08 17:59:49 +00:00
|
|
|
#uses lsrsrc instead of lsrsrc-api because format is almost right (just needs a few mods)
|
|
|
|
|
|
|
|
my $fh;
|
|
|
|
open($fh, ">$file")
|
|
|
|
or die "Can not open this file for writing $file.\n";
|
|
|
|
print $fh "#!/usr/bin/perl\n\n";
|
|
|
|
$class =~ s/IBM\.//;
|
|
|
|
|
|
|
|
print $fh '$RES::' . $class . "{" . "'"
|
|
|
|
. $resourcefilename . "'"
|
|
|
|
. "} = {\n";
|
|
|
|
foreach my $line (@$output)
|
|
|
|
{
|
|
|
|
my %attrs = split /:\|:/,
|
|
|
|
$line; #can't go straight into a hash because -p creates extra fields
|
|
|
|
foreach my $attr (keys %attrs)
|
|
|
|
{
|
|
|
|
if ( $attr !~ m/ActivePeerDomain/
|
|
|
|
&& $attr !~ m/NodeNameList/
|
|
|
|
&& $attr !~ m/NodeIDs/)
|
|
|
|
{
|
|
|
|
my $value = $attrs{$attr};
|
|
|
|
if ($value =~ m/\w/ || $value =~ m/\d/)
|
|
|
|
{
|
|
|
|
# print "value = |$value|\n";
|
|
|
|
#$value = &removeQuotes($value); #quotes are not needed becaues of q()
|
|
|
|
#print "value = |$value|\n";
|
|
|
|
my $line = "\t$attr => q($value),";
|
|
|
|
print $fh "$line\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach my $line (@$optional)
|
|
|
|
{
|
|
|
|
my %attrs = split /:\|:/,
|
|
|
|
$line; #can't go straight into a hash because -p creates extra fields
|
|
|
|
foreach my $attr (keys %attrs)
|
|
|
|
{
|
|
|
|
if ( $attr !~ m/ActivePeerDomain/
|
|
|
|
&& $attr !~ m/NodeNameList/
|
|
|
|
&& $attr !~ m/NodeIDs/)
|
|
|
|
{
|
|
|
|
my $value = $attrs{$attr};
|
|
|
|
if ($value =~ m/\w/ || $value =~ m/\d/)
|
|
|
|
{
|
|
|
|
# print "value = |$value|\n";
|
|
|
|
#$value = &removeQuotes($value); #quotes are not needed becaues of q()
|
|
|
|
#print "value = |$value|\n";
|
|
|
|
my $line = "\t$attr => q($value),";
|
|
|
|
print $fh "$line\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
print $fh "};";
|
|
|
|
print $fh "\n";
|
|
|
|
print $fh "1;";
|
|
|
|
print $fh "\n";
|
|
|
|
close($fh)
|
|
|
|
or die "cabbit close file $file\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
=head3 usage
|
|
|
|
Prints the command usage statement
|
|
|
|
=cut
|
|
|
|
#--------------------------------------------------------------------------------
|
|
|
|
sub usage
|
|
|
|
{
|
|
|
|
print "Usage:
|
|
|
|
mkrmcresources [--install|--mkfile classname::rsrcname|--mkall] \
|
|
|
|
[-V|--verbose] directory\n\
|
|
|
|
mkrmcresources -h|--help\n\
|
|
|
|
directory a full path to a base directory for resurce files \
|
|
|
|
to be created or to be read from. \
|
|
|
|
-V|--verbose Verbose mode.\
|
|
|
|
-h|--help shows usage information.\
|
|
|
|
--install\
|
|
|
|
The userid in the Sensor resource will not be verified.\n";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
# main Main MAIN
|
|
|
|
#######################################################################
|
|
|
|
|
|
|
|
# get arguments
|
|
|
|
if (
|
|
|
|
!GetOptions(
|
|
|
|
'h|help' => \$::HELP,
|
|
|
|
'V|verbose' => \$::VERBOSE,
|
|
|
|
'install' => \$::INSTALL,
|
|
|
|
'mkfile=s' => \$::MKFILE,
|
|
|
|
'mkall' => \$::MKALL,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
&usage;
|
|
|
|
exit 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($::HELP) { &usage; exit; }
|
2008-02-16 01:25:59 +00:00
|
|
|
if (isHMC() && ($ENV{'DC_ENVIRONMENT'} ne 1))
|
2008-02-08 17:59:49 +00:00
|
|
|
{
|
|
|
|
print "mkresources is not supported on HMC.\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
# any function requested
|
|
|
|
if (@ARGV < 1) {
|
|
|
|
&usage;
|
|
|
|
exit 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
my $basedir = $ARGV[0];
|
|
|
|
|
|
|
|
if ($::MKFILE) {
|
|
|
|
&writeFile($::MKFILE, $basedir);
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
if ($::MKALL) {
|
|
|
|
@rsrc_classes=('IBM.Condition', 'IBM.EventResponse', 'IBM.Sensor');
|
|
|
|
&writeAllFiles(\@rsrc_classes, $basedir);
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&traverseDirectories($basedir);
|
|
|
|
|
|
|
|
#TODO: wait for RSCT to come online
|
|
|
|
|
|
|
|
&queryResources(@::DIRECTORIES);
|
|
|
|
|
|
|
|
#compares whats defined in the files to the existing resources
|
|
|
|
&compareResources();
|
|
|
|
|
|
|
|
&createResources();
|
|
|
|
|
|
|
|
&changeResources();
|
|
|
|
|
|
|
|
END
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
exit 0;
|
|
|
|
|