diff --git a/perl-xCAT/xCAT/InstUtils.pm b/perl-xCAT/xCAT/InstUtils.pm new file mode 100644 index 000000000..3db0ae1fd --- /dev/null +++ b/perl-xCAT/xCAT/InstUtils.pm @@ -0,0 +1,370 @@ +#!/usr/bin/env perl +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html +package xCAT::InstUtils; + +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} + +# if AIX - make sure we include perl 5.8.2 in INC path. +# Needed to find perl dependencies shipped in deps tarball. +if ($^O =~ /^aix/i) { + use lib "/usr/opt/perl5/lib/5.8.2/aix-thread-multi"; + use lib "/usr/opt/perl5/lib/5.8.2"; + use lib "/usr/opt/perl5/lib/site_perl/5.8.2/aix-thread-multi"; + use lib "/usr/opt/perl5/lib/site_perl/5.8.2"; +} + +use lib "$::XCATROOT/lib/perl"; +require xCAT::Table; +use POSIX qw(ceil); +use Socket; +use strict; +require xCAT::Schema; +require Data::Dumper; +require xCAT::NodeRange; +require DBI; + +our @ISA = qw(Exporter); +our @EXPORT_OK = qw(genpassword); + +#------------------------------------------------------------------------------- + +=head1 xCAT::InstUtils + +=head2 Package Description + +This program module file, is a set of utilities used by xCAT install +related commands. + +=cut + +#------------------------------------------------------------- + +#---------------------------------------------------------------------------- + +=head3 getnimprime + + Get the name of the primary AIX NIM master + + Returns: + + hostname - short hostname of primary NIM master + undef - could not find primary NIM master + Example: + + my $nimprime = xCAT::InstUtils->getnimprime(); + Comments: + +=cut + +#----------------------------------------------------------------------------- + +sub getnimprime +{ + + # the primary NIM master is either specified in the site table + # or it is the xCAT management node. + + my $nimprime = xCAT::Utils->get_site_Master(); + my $sitetab = xCAT::Table->new('site'); + (my $et) = $sitetab->getAttribs({key => "NIMprime"}, 'value'); + if ($et and $et->{value}) { + $nimprime = $et->{value}; + } + + my $hostname; + if ($nimprime) { + if ($nimprime =~ /\d+\.\d+\.\d+\.\d+/) { + my $packedaddr = inet_aton($nimprime); + $hostname = gethostbyaddr($packedaddr, AF_INET); + } else { + $hostname = $nimprime; + } + + my $shorthost; + ($shorthost = $hostname) =~ s/\..*$//; + chomp $shorthost; + return $shorthost; + } + + return undef; +} + +#---------------------------------------------------------------------------- + +=head3 myxCATname + + Gets the name of the node I'm running on - as known by xCAT + (Either the management node or a service node) + + +=cut + +#----------------------------------------------------------------------------- + +sub myxCATname +{ + my ($junk, $name); + + $name = hostname(); + + if (xCAT::Utils->isMN()) { + # read the site table, master attrib + my $hostname = xCAT::Utils->get_site_Master(); + if ($hostname =~ /\d+\.\d+\.\d+\.\d+/) { + my $packedaddr = inet_aton($hostname); + $name = gethostbyaddr($packedaddr, AF_INET); + } else { + $name = $hostname; + } + + } elsif (xCAT::Utils->isServiceNode()) { + + # the myxcatpost_ file should exist on all nodes! + my $catcmd="cat /xcatpost/myxcatpost_* | grep '^NODE='"; + my $output = xCAT::Utils->runcmd("$catcmd", -1); + if ($::RUNCMD_RC == 0) { + ($junk, $name) = split('=', $output); + } + } + + my $shorthost; + ($shorthost = $name) =~ s/\..*$//; + chomp $shorthost; + return $shorthost; +} + +#---------------------------------------------------------------------------- + +=head3 is_me + + returns 1 if the hostname is the node I am running on + + Gets all the interfcaes defined on this node and sees if + any of them match the IP of the hostname passed in + + Arguments: + none + Returns: + 1 - this is the node I am running on + 0 - this is not the node I am running on + Globals: + none + Error: + none + Example: + if (xCAT::InstUtils->is_me(&somehostname)) { blah; } + Comments: + none + +=cut + +#----------------------------------------------------------------------------- + +sub is_me +{ + my ($class, $name) = @_; + #my $name = shift; + + # convert to IP + my $nameIP = inet_ntoa(inet_aton($name)); + chomp $nameIP; + + # split into octets + my ($b1, $b2, $b3, $b4) = split /\./, $nameIP; + + # get all the possible IPs for the node I'm running on + my $ifcmd = "ifconfig -a | grep 'inet '"; + my $result = xCAT::Utils->runcmd($ifcmd, 0, 1); + if ($::RUNCMD_RC != 0) + { + my $rsp; + # push @{$rsp->{data}}, "Could not run $ifcmd.\n"; + # xCAT::MsgUtils->message("E", $rsp, $callback); + return 0; + } + + foreach my $int (@$result) + { + my ($inet, $myIP, $str) = split(" ", $int); + chomp $myIP; + # Split the two ip addresses up into octets + my ($a1, $a2, $a3, $a4) = split /\./, $myIP; + + if ( ($a1 == $b1) && ($a2 == $b2) && ($a3 == $b3) && ($a4 == $b4) ) { + return 1; + } + } + return 0; +} + +#---------------------------------------------------------------------------- + +=head3 get_nim_attr_val + + Use the lsnim command to find the value of a resource attribute. + + Arguments: + Returns: + 0 - OK + 1 - error + Globals: + + Error: + + Example: + + xCAT::InstUtils->get_nim_attr_val + + Comments: +=cut + +#----------------------------------------------------------------------------- +sub get_nim_attr_val +{ + my $class = shift; + my $resname = shift; + my $attrname = shift; + my $callback = shift; + my $target = shift; + + if (!$target) { + $target = xCAT::InstUtils->getnimprime(); + } + chomp $target; + + my $cmd = "/usr/sbin/lsnim -a $attrname -Z $resname 2>/dev/null"; + my $nout = xCAT::InstUtils->xcmd($callback, "xdsh", $target, $cmd, 0); + if ($::RUNCMD_RC != 0) + { + my $rsp; + push @{$rsp->{data}}, "Could not run lsnim command: \'$cmd\'.\n"; + xCAT::MsgUtils->message("E", $rsp, $callback); + return undef; + } + + my ($junk, $junk, $junk, $loc) = split(/:/, $nout); + chomp $loc; + + return $loc; +} + + + +#------------------------------------------------------------------------------- + +=head3 xcmd + Run command either locally or on a remote system. + Calls either runcmd or runxcmd and does either xdcp or xdsh. + + Arguments: + + Returns: + Output of runcmd or runxcmd or blank. + + Comments: + + ex. xCAT::InstUtils->xcmd($callback, "xdcp", $nimprime, $cmd); +=cut + +#------------------------------------------------------------------------------- +sub xcmd +{ + my $class = shift; + my $callback = shift; + my $xdcmd = shift; # xdcp or xdsh + my $target = shift; # the node to run it on + my $cmd = shift; # the actual cmd to run + my $doarray = shift; # should the return be a string or array ptr? + + my $returnformat = 0; # default is to return string + my $exitcode = 0; + if ($doarray) { + $returnformat = $doarray; + } + + my $output; + if (xCAT::InstUtils->is_me($target)) { + $output=xCAT::Utils->runcmd($cmd, $exitcode, $returnformat); + + } else { + # need xdsh or xdcp + my @snodes; + push( @snodes, $target ); + $output=xCAT::Utils->runxcmd( + { + command => [$xdcmd], + node => \@snodes, + arg => [ $cmd ] + }, + $::sub_req, + $exitcode, $returnformat + ); + } + + if ($::VERBOSE) { + my $rsp; + if(ref($output) eq 'ARRAY'){ + if (scalar(@$output)) { + push @{$rsp->{data}}, "Running command \'$cmd\' on \'$target\'\n"; + push @{$rsp->{data}}, "Output from command: \'@$output\'.\n"; + xCAT::MsgUtils->message("I", $rsp, $callback); + } + } else { + if ($output) { + push @{$rsp->{data}}, "Running command \'$cmd\' on \'$target\'\n"; + push @{$rsp->{data}}, "Output from command: \'$output\'.\n"; + xCAT::MsgUtils->message("I", $rsp, $callback); + } + } + } + + return $output; +} + +#---------------------------------------------------------------------------- + +=head3 readBNDfile + + Get the contents of a NIM installp_bundle file based on the name + of the NIM resource. + +=cut + +#----------------------------------------------------------------------------- +sub readBNDfile +{ + + my ($class, $callback, $BNDname, $nimprime) = @_; + + my $junk; + my @pkglist, + my $pkgname; + + # get the location of the file from the NIM resource definition + my $bnd_file_name = xCAT::InstUtils->get_nim_attr_val($BNDname, 'location', $callback, $nimprime); + + # open the file + unless (open(BNDFILE, "<$bnd_file_name")) { + return (1); + } + + # get the names of the packages + while (my $l = ) { + + chomp $l; + + # skip blank and comment lines + next if ($l =~ /^\s*$/ || $l =~ /^\s*#/); + + push (@pkglist, $l); + } + close(BNDFILE); + + return (0, \@pkglist, $bnd_file_name); +} + + +1;