2007-10-26 22:44:33 +00:00
#!/usr/bin/env perl
2010-05-07 02:04:04 +00:00
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
2007-10-26 22:44:33 +00:00
package xCAT::Utils ;
2009-02-04 17:18:44 +00:00
2008-09-26 23:07:45 +00:00
BEGIN
{
2009-02-04 17:18:44 +00:00
$ ::XCATROOT = $ ENV { 'XCATROOT' } ? $ ENV { 'XCATROOT' } : '/opt/xcat' ;
2008-09-26 23:07:45 +00:00
}
2009-07-29 16:54:53 +00:00
# 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" ;
}
2008-09-26 23:07:45 +00:00
use lib "$::XCATROOT/lib/perl" ;
2011-04-01 14:02:44 +00:00
# do not put a use or require for xCAT::Table here. Add to each new routine
# needing it to avoid reprocessing of user tables ( ExtTab.pm) for each command call
2008-02-25 14:18:18 +00:00
use POSIX qw( ceil ) ;
2010-02-24 06:41:20 +00:00
use File::Path ;
2008-02-02 19:39:33 +00:00
use Socket ;
2008-07-18 12:30:22 +00:00
use strict ;
2010-05-18 19:30:49 +00:00
use Symbol ;
2010-07-21 14:13:12 +00:00
use Digest::SHA1 qw/sha1/ ;
2010-05-18 19:35:39 +00:00
use IPC::Open3 ;
2011-08-25 13:06:55 +00:00
use IO::Select ;
2011-10-18 12:32:51 +00:00
require xCAT::RemoteShellExp ;
2010-02-04 18:29:12 +00:00
use warnings "all" ;
2009-11-25 16:24:08 +00:00
require xCAT::InstUtils ;
2010-05-12 01:45:48 +00:00
require xCAT::NetworkUtils ;
2008-04-05 14:53:35 +00:00
require xCAT::Schema ;
2011-04-11 13:49:13 +00:00
#require Data::Dumper;
2008-04-05 14:53:35 +00:00
require xCAT::NodeRange ;
2011-04-26 16:57:13 +00:00
require xCAT::Version ;
2008-04-05 14:53:35 +00:00
require DBI ;
2008-05-07 17:35:14 +00:00
2008-05-13 12:36:13 +00:00
our @ ISA = qw( Exporter ) ;
2010-05-18 19:30:49 +00:00
our @ EXPORT_OK = qw( genpassword runcmd3 ) ;
2008-05-07 14:51:12 +00:00
2009-04-17 16:35:54 +00:00
my $ utildata ; #data to persist locally
2008-05-07 17:35:14 +00:00
#--------------------------------------------------------------------------------
= head1 xCAT:: Utils
= head2 Package Description
This program module file , is a set of utilities used by xCAT commands .
= cut
2008-07-28 13:48:15 +00:00
#-------------------------------------------------------------
2009-02-04 17:18:44 +00:00
2008-07-28 13:48:15 +00:00
= head3 genUUID
2010-05-16 22:56:22 +00:00
Returns an RFC 4122 compliant UUIDv4 or UUIDv1
2008-07-28 13:48:15 +00:00
Arguments:
2010-05-16 22:56:22 +00:00
mac: If requesting a UUIDv1 , the mac to use to base it upon
2008-07-28 13:48:15 +00:00
Returns:
string representation of a UUDv4 ,
for example: f16196d1 - 7534 - 41 c1 - a0ae - a9633b030583
2009-12-10 18:51:03 +00:00
for example: f16196d1 - 7534 - 41 c1 - a0ae - a9633b030583
2008-07-28 13:48:15 +00:00
= cut
2009-02-04 17:18:44 +00:00
2008-07-28 13:48:15 +00:00
#-------------------------------------------------------
2009-02-04 17:18:44 +00:00
sub genUUID
{
2008-07-28 13:48:15 +00:00
#UUIDv4 has 6 fixed bits and 122 random bits
#Though a UUID of this form is not guaranteed to be unique absolutely,
2009-02-04 17:18:44 +00:00
#the chances of a cluster the size of the entire internet generating
#two identical UUIDs is 4 in 10 octillion.
2010-05-16 18:54:46 +00:00
my % args = @ _ ;
if ( $ args { mac } ) { #if a mac address was supplied, generate a uuidv1 instead
2010-05-19 13:54:38 +00:00
use Math::BigInt ;
no warnings 'portable' ;
use Time::HiRes qw/gettimeofday/ ;
my $ sec ;
my $ usec ;
( $ sec , $ usec ) = gettimeofday ( ) ;
my $ uuidtime = Math::BigInt - > new ( $ sec ) ;
2010-05-19 14:05:00 +00:00
$ uuidtime - > bmul ( '10000000' ) ;
$ uuidtime - > badd ( $ usec * 10 ) ;
2010-05-19 13:54:38 +00:00
$ uuidtime - > badd ( '0x01B21DD213814000' ) ;
my $ timelow = $ uuidtime - > copy ( ) ;
2010-05-19 14:01:44 +00:00
$ timelow - > band ( '0xffffffff' ) ; # get lower 32bit
2010-05-19 13:54:38 +00:00
my $ timemid = $ uuidtime - > copy ( ) ;
2010-05-19 14:01:44 +00:00
$ timemid - > band ( '0xffff00000000' ) ;
2010-05-19 13:54:38 +00:00
my $ timehigh = $ uuidtime - > copy ( ) ;
2010-05-19 14:01:44 +00:00
$ timehigh - > band ( '0xffff000000000000' ) ;
$ timemid - > brsft ( 32 ) ;
$ timehigh - > brsft ( 48 ) ;
$ timehigh - > bior ( '0x1000' ) ; #add in version, don't bother stripping out the high bits since by the year 5236, none of this should matter
2010-05-19 13:54:38 +00:00
my $ clockseq = rand ( 8191 ) ; #leave the top three bits alone. We could leave just top two bits, but it's unneeded
#also, randomness matters very little, as the time+mac is here
$ clockseq = $ clockseq | 0x8000 ; #RFC4122 variant
#time to assemble...
$ timelow = $ timelow - > bstr ( ) ;
2010-05-19 14:01:44 +00:00
$ usec = $ timelow == 0 ; # doing numeric comparison induces perl to 'int'-ify it. Safe at this point as the subpieces are all sub-32 bit now
#assign to $usec the result so that perl doesn't complain about this trickery
2010-05-19 13:54:38 +00:00
$ timemid = $ timemid - > bstr ( ) ;
2010-05-19 14:01:44 +00:00
$ usec = $ timemid == 0 ;
$ timehigh = $ timehigh - > bstr ( ) ;
$ usec = $ timehigh == 0 ;
2010-05-19 13:54:38 +00:00
my $ uuid = sprintf ( "%08x-%04x-%04x-%04x-" , $ timelow , $ timemid , $ timehigh , $ clockseq ) ;
my $ mac = $ args { mac } ;
$ mac =~ s/://g ;
$ mac = lc ( $ mac ) ;
$ uuid . = $ mac ;
return $ uuid ;
2010-07-16 20:49:38 +00:00
} elsif ( $ args { url } ) { #generate a UUIDv5 from URL
#6ba7b810-9dad-11d1-80b4-00c04fd430c8 is the uuid for URL namespace
my $ sum = sha1 ( '6ba7b810-9dad-11d1-80b4-00c04fd430c8' . $ args { url } ) ;
my @ data = unpack ( "C*" , $ sum ) ;
splice @ data , 16 ;
$ data [ 6 ] = $ data [ 6 ] & 0xf ;
$ data [ 6 ] = $ data [ 6 ] | ( 5 << 4 ) ;
$ data [ 8 ] = $ data [ 8 ] & 127 ;
$ data [ 8 ] = $ data [ 8 ] | 64 ;
my $ uuid = unpack ( "H*" , pack ( "C*" , splice @ data , 0 , 4 ) ) ;
$ uuid . = "-" . unpack ( "H*" , pack ( "C*" , splice @ data , 0 , 2 ) ) ;
$ uuid . = "-" . unpack ( "H*" , pack ( "C*" , splice @ data , 0 , 2 ) ) ;
$ uuid . = "-" . unpack ( "H*" , pack ( "C*" , splice @ data , 0 , 2 ) ) ;
$ uuid . = "-" . unpack ( "H*" , pack ( "C*" , @ data ) ) ;
return $ uuid ;
2010-05-16 18:54:46 +00:00
}
2009-02-04 17:18:44 +00:00
srand ( ) ; #Many note this as bad practice, however, forks are going on..
2008-07-28 13:48:15 +00:00
my $ uuid ;
2009-02-04 17:18:44 +00:00
$ uuid =
sprintf ( "%08x-%04x-4%03x-" ,
int ( rand ( 4294967295 ) ) ,
int ( rand ( 65535 ) ) , int ( rand ( 4095 ) ) ) ;
my $ num = 32768 ;
2008-07-28 13:48:15 +00:00
$ num = $ num | int ( rand ( 16383 ) ) ;
2009-02-04 17:18:44 +00:00
$ uuid . =
sprintf ( "%04x-%04x%08x" , $ num , int ( rand ( 65535 ) ) , int ( rand ( 4294967295 ) ) ) ;
2008-07-28 13:48:15 +00:00
return $ uuid ;
}
2008-05-07 14:51:12 +00:00
#--------------------------------------------------------------------------------
2008-05-13 12:36:13 +00:00
2008-05-07 14:51:12 +00:00
= head3 genpassword
returns a random string of specified length or 8 if none given
Arguments:
length of string requested
Returns:
string of requested length or 8
Globals:
none
Error:
none
Example:
my $ salt = genpassword ( 8 ) ;
Comments:
none
= cut
#--------------------------------------------------------------------------------
2008-05-13 12:36:13 +00:00
sub genpassword
{
#Generate a pseudo-random password of specified length
my $ length = shift ;
unless ( $ length ) { $ length = 8 ; }
my $ password = '' ;
my $ characters =
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890' ;
srand ; #have to reseed, rand is not rand otherwise
while ( length ( $ password ) < $ length )
{
$ password . = substr ( $ characters , int ( rand 63 ) , 1 ) ;
2008-05-07 14:51:12 +00:00
}
return $ password ;
}
2007-10-26 22:44:33 +00:00
#--------------------------------------------------------------------------------
2007-12-20 19:02:45 +00:00
2007-10-26 22:44:33 +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:
if ( defined ( $$ opthashref { 'WhereStr' } ) ) {
$ where = xCAT::Utils - > quote ( $$ opthashref { 'WhereStr' } ) ;
}
Comments:
none
= cut
2007-12-20 19:02:45 +00:00
2007-10-26 22:44:33 +00:00
#--------------------------------------------------------------------------------
sub quote
{
my ( $ class , $ 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" ) ;
}
}
#-------------------------------------------------------------------------------
2007-12-20 19:02:45 +00:00
2007-10-26 22:44:33 +00:00
= head3 isAIX
returns 1 if localHost is AIX
Arguments:
none
Returns:
1 - localHost is AIX
0 - localHost is some other platform
Globals:
none
Error:
none
Example:
if ( xCAT::Utils - > isAIX ( ) ) { blah ; }
Comments:
none
= cut
#-------------------------------------------------------------------------------
sub isAIX
{
if ( $^O =~ /^aix/i ) { return 1 ; }
else { return 0 ; }
}
2009-08-09 17:46:04 +00:00
#-------------------------------------------------------------------------------
= head3 get_OS_VRMF
Arguments:
none
Returns:
v . r . m . f - if success
undef - if error
Example:
my $ osversion = xCAT::Utils - > get_OS_VRMF ( ) ;
Comments:
Only implemented for AIX for now
= cut
#-------------------------------------------------------------------------------
sub get_OS_VRMF
{
my $ version ;
if ( xCAT::Utils - > isAIX ( ) ) {
my $ cmd = "/usr/bin/lslpp -cLq bos.rte" ;
my $ output = xCAT::Utils - > runcmd ( $ cmd ) ;
chomp ( $ output ) ;
# The third field in the lslpp output is the VRMF
$ version = ( split ( /:/ , $ output ) ) [ 2 ] ;
# not sure if the field would ever contain more than 4 parts?
my ( $ v1 , $ v2 , $ v3 , $ v4 , $ rest ) = split ( /\./ , $ version ) ;
$ version = join ( "." , $ v1 , $ v2 , $ v3 , $ v4 ) ;
}
return ( length ( $ version ) ? $ version : undef ) ;
}
#----------------------------------------------------------------------------
= head3 testversion
Compare version1 and version2 according to the operator and
return True or False .
Arguments:
$ version1
$ operator
$ version2
$ release1
$ release2
Returns:
True or False
Example:
if ( ArchiveUtils - > testversion ( $ ins_ver ,
"<" ,
$ req_ver ,
$ ins_rel ,
$ req_rel ) ) { blah ; }
Comments:
= cut
#-------------------------------------------------------------------------------
sub testversion
{
my ( $ class , $ version1 , $ operator , $ version2 , $ release1 , $ release2 ) = @ _ ;
my @ a1 = split ( /\./ , $ version1 ) ;
my @ a2 = split ( /\./ , $ version2 ) ;
my $ len = ( scalar ( @ a1 ) > scalar ( @ a2 ) ? scalar ( @ a1 ) : scalar ( @ a2 ) ) ;
$# a1 = $ len - 1 ; # make the arrays the same length before appending release
$# a2 = $ len - 1 ;
push @ a1 , split ( /\./ , $ release1 ) ;
push @ a2 , split ( /\./ , $ release2 ) ;
$ len = ( scalar ( @ a1 ) > scalar ( @ a2 ) ? scalar ( @ a1 ) : scalar ( @ a2 ) ) ;
my $ num1 = '' ;
my $ num2 = '' ;
for ( my $ i = 0 ; $ i < $ len ; $ i + + )
{
my ( $ d1 ) = $ a1 [ $ i ] =~ /^(\d*)/ ; # remove any non-numbers on the end
my ( $ d2 ) = $ a2 [ $ i ] =~ /^(\d*)/ ;
my $ diff = length ( $ d1 ) - length ( $ d2 ) ;
if ( $ diff > 0 ) # pad d2
{
$ num1 . = $ d1 ;
$ num2 . = ( '0' x $ diff ) . $ d2 ;
}
elsif ( $ diff < 0 ) # pad d1
{
$ num1 . = ( '0' x abs ( $ diff ) ) . $ d1 ;
$ num2 . = $ d2 ;
}
else # they are the same length
{
$ num1 . = $ d1 ;
$ num2 . = $ d2 ;
}
}
# Remove the leading 0s or perl will interpret the numbers as octal
$ num1 =~ s/^0+// ;
$ num2 =~ s/^0+// ;
#SLES Changes ??
# if $num1="", the "eval '$num1 $operator $num2'" will fail.
# So MUST BE be sure that $num1 is not a "".
if ( length ( $ num1 ) == 0 ) { $ num1 = 0 ; }
if ( length ( $ num2 ) == 0 ) { $ num2 = 0 ; }
#End of SLES Changes
if ( $ operator eq '=' ) { $ operator = '==' ; }
my $ bool = eval "$num1 $operator $num2" ;
if ( length ( $@ ) )
{
# error msg ?
}
return $ bool ;
}
2008-01-21 19:39:09 +00:00
#-------------------------------------------------------------------------------
2008-01-21 19:49:59 +00:00
= head3 xfork
2008-01-21 19:39:09 +00:00
forks , safely coping with open database handles
Argumens:
none
Returns:
same as fork
= cut
2008-02-04 20:02:15 +00:00
2008-03-26 18:20:05 +00:00
#-------------------------------------------------------------------------------
2008-02-04 20:02:15 +00:00
sub xfork
{
my $ rc = fork ;
unless ( defined ( $ rc ) )
{
return $ rc ;
}
unless ( $ rc )
{
#my %drivers = DBI->installed_drivers;
foreach ( values % { $ ::XCAT_DBHS } )
{ #@{$drh->{ChildHandles}}) {
2009-11-10 15:07:16 +00:00
#if ($_) { $_->disconnect(); }
2008-02-04 20:02:15 +00:00
$ _ - > { InactiveDestroy } = 1 ;
undef $ _ ;
2008-01-21 19:39:09 +00:00
}
2008-02-04 20:02:15 +00:00
}
return $ rc ;
2008-01-21 19:39:09 +00:00
}
2008-03-26 18:20:05 +00:00
sub close_all_dbhs
{
foreach ( values % { $ ::XCAT_DBHS } )
{ #@{$drh->{ChildHandles}}) {
$ _ - > disconnect ;
undef $ _ ;
}
2008-03-11 20:27:46 +00:00
}
2008-03-26 18:20:05 +00:00
2007-10-26 22:44:33 +00:00
#-------------------------------------------------------------------------------
2007-12-20 19:02:45 +00:00
2007-10-26 22:44:33 +00:00
= head3 isLinux
returns 1 if localHost is Linux
Arguments:
none
Returns:
1 - localHost is Linux
0 - localHost is some other platform
Globals:
none
Error:
none
Example:
if ( xCAT::Utils - > isLinux ( ) ) { blah ; }
Comments:
none
= cut
2007-12-20 19:02:45 +00:00
2007-10-26 22:44:33 +00:00
#-------------------------------------------------------------------------------
sub isLinux
{
if ( $^O =~ /^linux/i ) { return 1 ; }
else { return 0 ; }
}
#-------------------------------------------------------------------------------
2008-06-10 16:39:20 +00:00
= head3 Version
Arguments:
2008-09-19 17:39:06 +00:00
Optional 'short' string to request only the version ;
2008-06-10 16:39:20 +00:00
Returns:
xcat Version number
Globals:
none
Error:
none
Example:
$ version = xCAT::Utils - > Version ( ) ;
Comments:
none
= cut
#-------------------------------------------------------------------------------
sub Version
{
2009-02-04 17:18:44 +00:00
#The following tag tells the build script where to append build info
my $ version = shift ;
2011-04-26 16:57:13 +00:00
$ version = xCAT::Version - > Version ( ) ;
2009-02-04 17:18:44 +00:00
return $ version ;
2009-02-18 19:03:45 +00:00
2008-06-10 16:39:20 +00:00
}
#-------------------------------------------------------------------------------
2007-10-26 22:44:33 +00:00
= head3 make_node_list_file
2008-04-05 14:53:35 +00:00
Makes a node list file .
2007-10-26 22:44:33 +00:00
Arguments:
( \ @ list_of_nodes ) - reference to an arrary of nodes .
Returns:
$ file_name and sets the global var: $ ::NODE_LIST_FILE
Globals:
the ENV vars: DSH_LIST , RPOWER_LIST , RCONSOLE_LIST
Error:
None documented
Example:
2008-04-05 14:53:35 +00:00
xCAT::Utils - > make_node_list_file ( \ @ nodelist ) ;
2007-10-26 22:44:33 +00:00
Comments:
IMPORTANT:
Make sure to cleanup afterwards with:
xCAT::Utils - > close_delete_file ( $ file_handle , $ file_name )
= cut
#--------------------------------------------------------------------------------
sub make_node_list_file
{
my ( $ class , $ ref_node_list ) = @ _ ;
my @ node_list = @$ ref_node_list ;
srand ( time | $$ ) ; #random number generator start
my $ file = "/tmp/csm_$$" ;
while ( - e $ file )
{
$ file = xCAT::Utils - > CreateRandomName ( $ file ) ;
}
open ( $ ::NODE_LIST_FILE , ">$file" )
2009-01-06 17:58:01 +00:00
or xCAT::MsgUtils - > message ( "E" , "Cannot write to file: $file\n" ) ;
2007-10-26 22:44:33 +00:00
foreach my $ node ( @ node_list )
{
print $ ::NODE_LIST_FILE "$node\n" ;
}
return $ file ;
}
#--------------------------------------------------------------------------------
= head3 CreateRandomName
Create a randome file name .
Arguments:
Prefix of name
Returns:
Prefix with 8 random letters appended
Error:
none
Example:
$ file = xCAT::Utils - > CreateRandomName ( $ namePrefix ) ;
Comments:
None
= cut
#-------------------------------------------------------------------------------
sub CreateRandomName
{
my ( $ class , $ name ) = @ _ ;
my $ nI ;
for ( $ nI = 0 ; $ nI < 8 ; $ nI + + )
{
my $ char = ( 'a' .. 'z' , 'A' .. 'Z' ) [ int ( rand ( 52 ) ) + 1 ] ;
$ name . = $ char ;
}
$ name ;
}
#-----------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3
2007-10-26 22:44:33 +00:00
close_delete_file .
Arguments:
file handle , filename
Returns:
2008-04-05 14:53:35 +00:00
none
2007-10-26 22:44:33 +00:00
Globals:
none
Error:
undef
Example:
xCAT::Utils - > close_delete_file ( $ file_handle , $ file_name ) ;
Comments:
none
= cut
#------------------------------------------------------------------------
sub close_delete_file
{
my ( $ class , $ file_handle , $ file_name ) = @ _ ;
close $ file_handle ;
unlink ( $ file_name ) ;
}
#-----------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3
2007-10-26 22:44:33 +00:00
list_all_nodes
Arguments:
2008-04-05 14:53:35 +00:00
2007-10-26 22:44:33 +00:00
Returns:
2008-04-05 14:53:35 +00:00
an array of all define nodes from the nodelist table
2007-10-26 22:44:33 +00:00
Globals:
none
Error:
undef
Example:
@ nodes = xCAT::Utils - > list_all_nodes ;
Comments:
none
= cut
#------------------------------------------------------------------------
sub list_all_nodes
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2007-10-26 22:44:33 +00:00
my @ nodes ;
my @ nodelist ;
my $ nodelisttab ;
if ( $ nodelisttab = xCAT::Table - > new ( "nodelist" ) )
{
my @ attribs = ( "node" ) ;
@ nodes = $ nodelisttab - > getAllAttribs ( @ attribs ) ;
foreach my $ node ( @ nodes )
{
push @ nodelist , $ node - > { node } ;
}
}
else
{
xCAT::MsgUtils - > message ( "E" , " Could not read the nodelist table\n" ) ;
}
return @ nodelist ;
}
#-----------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3
2007-10-26 22:44:33 +00:00
list_all_nodegroups
Arguments:
2008-04-05 14:53:35 +00:00
2007-10-26 22:44:33 +00:00
Returns:
2010-04-09 19:14:36 +00:00
an array of all define node groups from the nodelist and nodegroup
table
2007-10-26 22:44:33 +00:00
Globals:
none
Error:
undef
Example:
@ nodegrps = xCAT::Utils - > list_all_nodegroups ;
Comments:
none
= cut
#------------------------------------------------------------------------
sub list_all_node_groups
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2007-10-26 22:44:33 +00:00
my @ grouplist ;
my @ grouplist2 ;
my @ distinctgroups ;
my $ nodelisttab ;
if ( $ nodelisttab = xCAT::Table - > new ( "nodelist" ) )
{
my @ attribs = ( "groups" ) ;
@ grouplist = $ nodelisttab - > getAllAttribs ( @ attribs ) ;
# build a distinct list of unique group names
foreach my $ group ( @ grouplist )
{
my $ gnames = $ group - > { groups } ;
my @ groupnames = split "," , $ gnames ;
foreach my $ groupname ( @ groupnames )
{
if ( ! grep ( /$groupname/ , @ distinctgroups ) )
{ # not already in list
push @ distinctgroups , $ groupname ;
}
}
}
}
else
{
xCAT::MsgUtils - > message ( "E" , " Could not read the nodelist table\n" ) ;
}
2008-04-22 13:24:38 +00:00
$ nodelisttab - > close ;
2010-04-09 19:14:36 +00:00
# now read the nodegroup table
if ( $ nodelisttab = xCAT::Table - > new ( "nodegroup" ) )
{
my @ attribs = ( "groupname" ) ;
@ grouplist = $ nodelisttab - > getAllAttribs ( @ attribs ) ;
# build a distinct list of unique group names
foreach my $ group ( @ grouplist )
{
my $ groupname = $ group - > { groupname } ;
if ( ! grep ( /$groupname/ , @ distinctgroups ) )
{ # not already in list
push @ distinctgroups , $ groupname ;
}
}
$ nodelisttab - > close ;
}
else
{
xCAT::MsgUtils - > message ( "E" , " Could not read the nodegroup table\n" ) ;
}
2007-10-26 22:44:33 +00:00
return @ distinctgroups ;
}
#-----------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3
2010-10-28 19:08:56 +00:00
list_nodes_in_nodegroups
2007-10-26 22:44:33 +00:00
Arguments: nodegroup
2008-04-05 14:53:35 +00:00
2007-10-26 22:44:33 +00:00
Returns:
2008-04-05 14:53:35 +00:00
an array of all define nodes in the node group
2007-10-26 22:44:33 +00:00
Globals:
none
Error:
undef
Example:
2010-10-28 19:08:56 +00:00
@ nodes = xCAT::Utils - > list_nodes_in_nodegroups ( $ group ) ;
2007-10-26 22:44:33 +00:00
Comments:
none
= cut
#------------------------------------------------------------------------
sub list_nodes_in_nodegroups
{
my ( $ class , $ group ) = @ _ ;
2009-02-04 17:18:44 +00:00
my $ req = { } ;
2007-10-26 22:44:33 +00:00
$ req - > { noderange } - > [ 0 ] = $ group ;
2008-04-05 14:53:35 +00:00
my @ nodes = xCAT::NodeRange:: noderange ( $ req - > { noderange } - > [ 0 ] ) ;
2007-10-26 22:44:33 +00:00
return @ nodes ;
}
#-----------------------------------------------------------------------
2010-10-28 19:08:56 +00:00
= head3
isMemberofGroup
Arguments: node , group
Returns:
1 = is a member
0 = not a member
Globals:
none
Error:
undef
Example:
$ ismember = xCAT::Utils - > isMemberofGroup ( $ node , $ group ) ;
Comments:
none
= cut
#------------------------------------------------------------------------
sub isMemberofGroup
{
my ( $ class , $ node , $ group ) = @ _ ;
my $ ismember ;
my @ nodes = xCAT::Utils - > list_nodes_in_nodegroups ( $ group ) ;
2010-11-02 18:16:33 +00:00
if ( grep ( /^$node$/ , @ nodes ) ) {
2010-10-28 19:08:56 +00:00
$ ismember = 1 ;
} else {
$ ismember = 0 ;
}
return $ ismember ;
}
#-----------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3
get_site_attribute
2007-10-26 22:44:33 +00:00
Arguments:
2008-04-05 14:53:35 +00:00
2007-10-26 22:44:33 +00:00
Returns:
2008-04-05 14:53:35 +00:00
The value of the attribute requested from the site table
2007-10-26 22:44:33 +00:00
Globals:
none
Error:
undef
Example:
@ attr = xCAT::Utils - > get_site_attribute ( $ attribute ) ;
Comments:
none
= cut
#------------------------------------------------------------------------
sub get_site_attribute
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2007-10-26 22:44:33 +00:00
my ( $ class , $ attr ) = @ _ ;
2011-04-01 14:02:44 +00:00
2007-10-26 22:44:33 +00:00
my $ values ;
my $ sitetab = xCAT::Table - > new ( 'site' ) ;
if ( $ sitetab )
{
2008-07-18 12:30:22 +00:00
( my $ ref ) = $ sitetab - > getAttribs ( { key = > $ attr } , 'value' ) ;
2009-03-12 17:54:44 +00:00
if ( $ ref )
2007-10-26 22:44:33 +00:00
{
$ values = $ ref - > { value } ;
}
}
else
{
xCAT::MsgUtils - > message ( "E" , " Could not read the site table\n" ) ;
}
2008-04-22 13:24:38 +00:00
$ sitetab - > close ;
2007-10-26 22:44:33 +00:00
return $ values ;
}
2007-11-27 14:22:04 +00:00
2007-11-28 19:44:47 +00:00
#-----------------------------------------------------------------------
2007-12-20 19:02:45 +00:00
2008-04-05 14:53:35 +00:00
= head3
2007-11-28 19:44:47 +00:00
add_cron_job
This function adds a new cron job .
Arguments:
2008-04-05 14:53:35 +00:00
job - - - string in the crontab job format .
2007-11-28 19:44:47 +00:00
Returns:
( code , message )
Globals:
none
Error:
undef
Example:
xCAT::Utils - > add_cron_job ( "*/5 * * * * /usr/bin/myjob" ) ;
Comments:
none
= cut
2007-12-20 19:02:45 +00:00
2007-11-28 19:44:47 +00:00
#------------------------------------------------------------------------
2007-12-20 19:02:45 +00:00
sub add_cron_job
{
2008-07-18 12:30:22 +00:00
my $ newentry = shift ;
2007-12-20 19:02:45 +00:00
if ( $ newentry =~ /xCAT::Utils/ )
{
$ newentry = shift ;
}
#read the cron tab entries
my @ tabs = `/usr/bin/crontab -l 2>/dev/null` ;
my @ newtabs = ( ) ;
foreach ( @ tabs )
{
chomp ( $ _ ) ;
# stop adding if it's already there
if ( $ _ eq $ newentry ) { return ( 0 , "started" ) ; }
#skip headers for Linux
next
if $ _ =~
m/^\#.+(DO NOT EDIT THIS FILE|\(.+ installed on |Cron version )/ ;
push ( @ newtabs , $ _ ) ;
}
#add new entries to the cron tab
push ( @ newtabs , $ newentry ) ;
my $ tabname = "" ;
2008-09-26 23:07:45 +00:00
if ( xCAT::Utils - > isLinux ( ) ) { $ tabname = "-" ; }
2007-12-20 19:02:45 +00:00
open ( CRONTAB , "|/usr/bin/crontab $tabname" )
or return ( 1 , "cannot open crontab." ) ;
foreach ( @ newtabs ) { print CRONTAB $ _ . "\n" ; }
close ( CRONTAB ) ;
2007-11-28 19:44:47 +00:00
2007-12-20 19:02:45 +00:00
return ( 0 , "" ) ;
}
2007-11-28 19:44:47 +00:00
#-----------------------------------------------------------------------
2007-12-20 19:02:45 +00:00
2008-04-05 14:53:35 +00:00
= head3
2007-11-28 19:44:47 +00:00
remove_cron_job
This function removes a new cron job .
Arguments:
2008-04-05 14:53:35 +00:00
job - - - a substring that is contained in a crontab entry .
( use crontab - l to see all the job entries . )
2007-11-28 19:44:47 +00:00
Returns:
( code , message )
Globals:
none
Error:
undef
Example:
xCAT::Utils - > remove_cron_job ( "/usr/bin/myjob" ) ;
This will remove any cron job that contains this string .
Comments:
none
= cut
2007-12-20 19:02:45 +00:00
2007-11-28 19:44:47 +00:00
#------------------------------------------------------------------------
2007-12-20 19:02:45 +00:00
sub remove_cron_job
{
2008-07-18 12:30:22 +00:00
my $ job = shift ;
2007-12-20 19:02:45 +00:00
if ( $ job =~ /xCAT::Utils/ )
{
$ job = shift ;
}
#read the cron tab entries and remove the one that contains $job
my @ tabs = `/usr/bin/crontab -l 2>/dev/null` ;
my @ newtabs = ( ) ;
foreach ( @ tabs )
{
chomp ( $ _ ) ;
# stop adding if it's already there
next if index ( $ _ , $ job , 0 ) >= 0 ;
#skip headers for Linux
next
if $ _ =~
m/^\#.+(DO NOT EDIT THIS FILE|\(.+ installed on |Cron version )/ ;
push ( @ newtabs , $ _ ) ;
}
#refresh the cron
my $ tabname = "" ;
2008-09-26 23:07:45 +00:00
if ( xCAT::Utils - > isLinux ( ) ) { $ tabname = "-" ; }
2007-12-20 19:02:45 +00:00
open ( CRONTAB , "|/usr/bin/crontab $tabname" )
or return ( 1 , "cannot open crontab." ) ;
foreach ( @ newtabs ) { print CRONTAB $ _ . "\n" ; }
close ( CRONTAB ) ;
2007-11-28 19:44:47 +00:00
2007-12-20 19:02:45 +00:00
return ( 0 , "" ) ;
}
2007-11-28 19:44:47 +00:00
2010-05-18 19:30:49 +00:00
#-------------------------------------------------------------------------------
= head3 runcmd3
Run the specified command with optional input and return stderr , stdout , and exit code
Arguments:
command = > [] - Array reference of command to run
input = > [] or string - Data to send to stdin of process like piping input
Returns:
{ exitcode = > number , output = > $ string , errors = > string }
= cut
sub runcmd3 { #a proper runcmd that indpendently returns stdout, stderr, pid and accepts a stdin
my % args = @ _ ;
my @ indata ;
my $ output ;
my $ errors ;
if ( $ args { input } ) {
if ( ref $ args { input } ) { #array ref
@ indata = @ { $ args { input } } ;
} else { #just a string
@ indata = ( $ args { input } ) ;
}
}
my @ cmd ;
if ( ref $ args { command } ) {
@ cmd = @ { $ args { command } } ;
} else {
@ cmd = ( $ args { command } ) ;
}
my $ cmdin ;
my $ cmdout ;
my $ cmderr = gensym ;
my $ cmdpid = open3 ( $ cmdin , $ cmdout , $ cmderr , @ cmd ) ;
2010-05-18 19:54:43 +00:00
my $ cmdsel = IO::Select - > new ( $ cmdout , $ cmderr ) ;
2010-05-18 19:30:49 +00:00
foreach ( @ indata ) {
print $ cmdin $ _ ;
}
2010-05-18 21:01:49 +00:00
close ( $ cmdin ) ;
2010-05-18 19:30:49 +00:00
my @ handles ;
2010-05-19 12:52:52 +00:00
while ( $ cmdsel - > count ( ) ) {
2010-05-19 12:47:07 +00:00
@ handles = $ cmdsel - > can_read ( ) ;
2010-05-18 19:30:49 +00:00
foreach ( @ handles ) {
my $ line ;
my $ done = sysread $ _ , $ line , 180 ;
if ( $ done ) {
if ( $ _ eq $ cmdout ) {
$ output . = $ line ;
} else {
$ errors . = $ line ;
}
} else {
$ cmdsel - > remove ( $ _ ) ;
close ( $ _ ) ;
}
}
}
waitpid ( $ cmdpid , 0 ) ;
my $ exitcode = $? >> 8 ;
return { 'exitcode' = > $ exitcode , 'output' = > $ output , 'errors' = > $ errors }
}
2007-11-27 14:22:04 +00:00
#-------------------------------------------------------------------------------
= head3 runcmd
Run the given cmd and return the output in an array ( already chopped ) .
2008-04-05 14:53:35 +00:00
Alternately , if this function is used in a scalar context , the output
2007-11-27 14:22:04 +00:00
is joined into a single string with the newlines separating the lines .
Arguments:
2011-08-24 18:05:11 +00:00
command , exitcode , reference to output , streaming mode
2007-11-27 14:22:04 +00:00
Returns:
see below
Globals:
2008-04-05 14:53:35 +00:00
$ ::RUNCMD_RC , $ ::CALLBACK
2007-11-27 14:22:04 +00:00
Error:
Normally , if there is an error running the cmd , it will display the
error 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 = xCAT::Utils - > runcmd ( $ cmd , - 2 , 1 ) ;
2011-08-25 12:52:19 +00:00
$ ::CALLBACK = your callback ( required for streaming from plugins )
2011-08-24 18:05:11 +00:00
my $ outref = xCAT::Utils - > runcmd ( $ cmd , - 2 , 1 , 1 ) ; streaming
2007-11-27 14:22:04 +00:00
Comments:
If refoutput is true , then the output will be returned as a
reference to an array for efficiency .
= cut
#-------------------------------------------------------------------------------
sub runcmd
{
2011-08-24 18:05:11 +00:00
my ( $ class , $ cmd , $ exitcode , $ refoutput , $ stream ) = @ _ ;
2007-11-27 14:22:04 +00:00
$ ::RUNCMD_RC = 0 ;
2010-05-13 12:15:23 +00:00
# redirect stderr to stdout
if ( ! ( $ cmd =~ /2>&1$/ ) ) { $ cmd . = ' 2>&1' ; }
2007-11-27 14:22:04 +00:00
2011-01-30 17:00:54 +00:00
if ( $ ::VERBOSE )
{
# get this systems name as known by xCAT management node
my $ Sname = xCAT::InstUtils - > myxCATname ( ) ;
my $ msg ;
if ( $ Sname ) {
$ msg = "Running command on $Sname: $cmd" ;
} else {
$ msg = "Running command: $cmd" ;
}
if ( $ ::CALLBACK ) {
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "$msg\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::CALLBACK ) ;
} else {
xCAT::MsgUtils - > message ( "I" , "$msg\n" ) ;
}
}
2010-02-05 16:17:28 +00:00
2007-11-27 14:22:04 +00:00
my $ outref = [] ;
2011-09-28 12:08:15 +00:00
if ( ! defined ( $ stream ) || ( length ( $ stream ) == 0 ) ) { # do not stream
2011-08-24 18:05:11 +00:00
@$ outref = `$cmd` ;
} else { # streaming mode
my @ cmd ;
push @ cmd , $ cmd ;
my $ rsp = { } ;
my $ output ;
my $ errout ;
2011-09-28 12:08:15 +00:00
open ( PIPE , "$cmd |" ) ;
while ( <PIPE> ) {
if ( $ ::CALLBACK ) {
$ rsp - > { data } - > [ 0 ] = $ _ ;
$ ::CALLBACK - > ( $ rsp ) ;
} else {
xCAT::MsgUtils - > message ( "D" , "$_" ) ;
2011-08-24 18:05:11 +00:00
}
2011-09-28 12:08:15 +00:00
$ output . = $ _ ;
2011-08-24 18:05:11 +00:00
}
# store the return string
push @$ outref , $ output ;
}
2011-09-28 12:08:15 +00:00
# now if not streaming process errors
if ( ( $? ) && ( ! defined ( $ stream ) ) )
2007-11-27 14:22:04 +00:00
{
$ ::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 )
{
2009-02-04 17:18:44 +00:00
my $ rsp = { } ;
2007-11-27 14:22:04 +00:00
my $ errmsg = '' ;
if ( xCAT::Utils - > isLinux ( ) && $ ::RUNCMD_RC == 139 )
{
$ errmsg = "Segmentation fault $errmsg" ;
}
else
{
$ errmsg = join ( '' , @$ outref ) ;
chomp $ errmsg ;
}
2007-12-20 19:02:45 +00:00
if ( $ ::CALLBACK )
{
$ rsp - > { data } - > [ 0 ] =
"Command failed: $cmd. Error message: $errmsg.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
}
else
2007-11-27 14:22:04 +00:00
{
xCAT::MsgUtils - > message ( "E" ,
"Command failed: $cmd. Error message: $errmsg.\n" ) ;
}
$ xCAT:: Utils:: errno = 29 ;
}
}
if ( $ refoutput )
{
chomp ( @$ outref ) ;
return $ outref ;
}
elsif ( wantarray )
{
chomp ( @$ outref ) ;
return @$ outref ;
}
else
{
my $ line = join ( '' , @$ outref ) ;
chomp $ line ;
return $ line ;
}
}
2007-11-28 19:44:47 +00:00
2008-10-06 14:51:33 +00:00
#-------------------------------------------------------------------------------
= head3 runxcmd
Run the given xCAT cmd and return the output in an array .
Alternately , if this function is used in a scalar context , the output
is joined into a single string with newlines separating the lines .
Arguments:
command - string with following format :
< xCAT cmd name > < comma - delimited nodelist > < cmd args >
2008-10-22 15:56:46 +00:00
where the xCAT cmd name is as reqistered in the plugins ,
2008-10-06 14:51:33 +00:00
the nodelist is already flattened and verified
2008-10-22 15:56:46 +00:00
the remainder of the string is passed as args .
The nodelist may be set to the string "NO_NODE_RANGE" to
not pass in any nodes to the command .
2008-10-06 14:51:33 +00:00
OR
command - request hash
reference to xCAT daemon sub_req routine
exitcode
reference to output
Returns:
see below
Globals:
$ ::RUNCMD_RC , $ ::CALLBACK
Error:
Cannot determine error code . If ERROR data set in response
hash , $ ::RUNCMD_RC will be set to 1 .
Normally , if there is an error running the cmd , it will display the
error 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 = xCAT::Utils - > runxcmd ( $ cmd , $ sub_req , - 2 , 1 ) ;
Comments:
If refoutput is true , then the output will be returned as a
reference to an array for efficiency .
2008-10-22 15:56:46 +00:00
Do not use the scalar string input for xdsh unless you are running
a simple single - word command . When building your request hash ,
the entire command string xdsh runs needs to be a single entry
in the arg array .
2010-02-02 19:47:52 +00:00
The caller to the runxcmd is responsible for filename expansion , that
would have been done if the command was run on the command line .
For example , the xdcp node1 /tmp/ testfile * / tmp command needs to
have the /tmp/ testfile * argument expanded before call xdcp with
runxcmd . The easy way to do this is to use the perl glob function .
@ files = glob "/tmp/testfile*" ;
2008-10-06 14:51:33 +00:00
= cut
#-------------------------------------------------------------------------------
sub runxcmd
{
2009-02-04 17:18:44 +00:00
my $ save_CALLBACK = $ ::CALLBACK ;
2008-10-06 14:51:33 +00:00
my ( $ class , $ cmd , $ subreq , $ exitcode , $ refoutput ) = @ _ ;
$ ::RUNCMD_RC = 0 ;
2010-02-05 16:17:28 +00:00
2008-10-06 14:51:33 +00:00
if ( $ ::VERBOSE )
{
2009-02-04 17:18:44 +00:00
if ( ref ( $ cmd ) eq "HASH" )
{
2010-02-05 16:17:28 +00:00
if ( $ ::CALLBACK ) {
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Running internal xCAT command: $cmd->{command}->[0] ... \n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::CALLBACK ) ;
} else {
xCAT::MsgUtils - > message ( "I" , "Running internal xCAT command: $cmd->{command}->[0] ... \n" ) ;
}
2009-02-04 17:18:44 +00:00
}
else
{
2010-02-05 16:17:28 +00:00
if ( $ ::CALLBACK ) {
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Running Command: $cmd\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::CALLBACK ) ;
} else {
xCAT::MsgUtils - > message ( "I" , "Running Command: $cmd\n" ) ;
}
2008-10-27 17:11:23 +00:00
}
2008-10-06 14:51:33 +00:00
}
2010-02-05 16:17:28 +00:00
2008-10-06 14:51:33 +00:00
$ ::xcmd_outref = [] ;
2009-02-04 17:18:44 +00:00
my $ req ;
if ( ref ( $ cmd ) eq "HASH" )
{
$ req = $ cmd ;
}
else
{ # assume scalar, build request hash the way we do in xcatclient
my @ cmdargs = split ( /\s+/ , $ cmd ) ;
my $ cmdname = shift ( @ cmdargs ) ;
$ req - > { command } = [ $ cmdname ] ;
my $ arg = shift ( @ cmdargs ) ;
while ( $ arg =~ /^-/ )
{
push ( @ { $ req - > { arg } } , $ arg ) ;
$ arg = shift ( @ cmdargs ) ;
}
if ( $ arg ne "NO_NODE_RANGE" )
{
my @ nodes = split ( "," , $ arg ) ;
$ req - > { node } = \ @ nodes ;
}
push ( @ { $ req - > { arg } } , @ cmdargs ) ;
}
$ subreq - > ( $ req , \ & runxcmd_output ) ;
$ ::CALLBACK = $ save_CALLBACK ; # in case the subreq call changed it
my $ outref = $ ::xcmd_outref ;
2008-10-06 14:51:33 +00:00
if ( $ ::RUNCMD_RC )
{
my $ displayerror = 1 ;
my $ rc ;
if ( defined ( $ exitcode ) && length ( $ exitcode ) && $ exitcode != - 2 )
{
if ( $ exitcode > 0 )
{
$ rc = $ exitcode ;
2009-02-04 17:18:44 +00:00
} # if not zero, exit with specified code
2008-10-06 14:51:33 +00:00
elsif ( $ exitcode <= 0 )
{
2009-02-04 17:18:44 +00:00
$ rc = '' ; # if zero or negative, do not exit
2008-10-06 14:51:33 +00:00
if ( $ exitcode < 0 ) { $ displayerror = 0 ; }
}
}
else
{
$ rc = $ ::RUNCMD_RC ;
} # if exitcode not specified, use cmd exit code
if ( $ displayerror )
{
2009-02-04 17:18:44 +00:00
my $ rsp = { } ;
2008-10-06 14:51:33 +00:00
my $ errmsg = join ( '' , @$ outref ) ;
chomp $ errmsg ;
2009-02-04 17:18:44 +00:00
my $ displaycmd = $ cmd ;
if ( ref ( $ cmd ) eq "HASH" )
{
$ displaycmd = $ cmd - > { command } - > [ 0 ] ;
}
2008-10-06 14:51:33 +00:00
if ( $ ::CALLBACK )
{
$ rsp - > { data } - > [ 0 ] =
2008-10-22 15:56:46 +00:00
"Command failed: $displaycmd. Error message: $errmsg.\n" ;
2008-10-06 14:51:33 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
}
else
{
xCAT::MsgUtils - > message ( "E" ,
2009-02-04 17:18:44 +00:00
"Command failed: $displaycmd. Error message: $errmsg.\n" ) ;
2008-10-06 14:51:33 +00:00
}
$ xCAT:: Utils:: errno = 29 ;
}
}
if ( $ refoutput )
{
chomp ( @$ outref ) ;
return $ outref ;
}
elsif ( wantarray )
{
chomp ( @$ outref ) ;
return @$ outref ;
}
else
{
my $ line = join ( '' , @$ outref ) ;
chomp $ line ;
return $ line ;
}
}
2009-02-04 17:18:44 +00:00
2008-10-06 14:51:33 +00:00
# runxcmd_output -- Internal subroutine for runxcmd to capture the output
# from the xCAT daemon subrequest call
# Note - only basic info, data, and error responses returned
# For more complex node or other return structures, you will need
# to write your own wrapper to subreq instead of using runxcmd.
2009-02-04 17:18:44 +00:00
sub runxcmd_output
{
my $ resp = shift ;
if ( defined ( $ resp - > { info } ) )
{
push @$ ::xcmd_outref , @ { $ resp - > { info } } ;
}
if ( defined ( $ resp - > { sinfo } ) )
{
push @$ ::xcmd_outref , @ { $ resp - > { sinfo } } ;
}
if ( defined ( $ resp - > { data } ) )
{
push @$ ::xcmd_outref , @ { $ resp - > { data } } ;
}
if ( defined ( $ resp - > { node } ) )
{
my $ node = $ resp - > { node } - > [ 0 ] ;
my $ desc = $ node - > { name } - > [ 0 ] ;
if ( defined ( $ node - > { data } ) )
{
if ( ref ( \ ( $ node - > { data } - > [ 0 ] ) ) eq 'SCALAR' )
{
$ desc = $ desc . ": " . $ node - > { data } - > [ 0 ] ;
}
else
{
if ( defined ( $ node - > { data } - > [ 0 ] - > { desc } ) )
{
$ desc = $ desc . ": " . $ node - > { data } - > [ 0 ] - > { desc } - > [ 0 ] ;
}
if ( defined ( $ node - > { data } - > [ 0 ] - > { contents } ) )
{
$ desc = "$desc: " . $ node - > { data } - > [ 0 ] - > { contents } - > [ 0 ] ;
}
}
}
push @$ ::xcmd_outref , $ desc ;
}
if ( defined ( $ resp - > { error } ) )
{
push @$ ::xcmd_outref , @ { $ resp - > { error } } ;
$ ::RUNCMD_RC = 1 ;
}
if ( defined ( $ resp - > { errorcode } ) )
{
if ( ref ( $ resp - > { errorcode } ) eq 'ARRAY' )
{
foreach my $ ecode ( @ { $ resp - > { errorcode } } )
{
$ ::RUNCMD_RC |= $ ecode ;
}
}
else
{
2008-10-06 14:51:33 +00:00
2009-02-04 17:18:44 +00:00
# assume it is a non-reference scalar
$ ::RUNCMD_RC |= $ resp - > { errorcode } ;
}
}
# my $i=0;
# foreach my $line ($resp->{info}->[$i]) {
# push (@dshresult, $line);
# $i++;
# }
return 0 ;
}
2008-10-06 14:51:33 +00:00
2007-12-20 19:02:45 +00:00
#--------------------------------------------------------------------------------
2010-02-24 06:51:25 +00:00
= head3 getInstallDir
Get location of the directory , used to hold the node deployment packages .
Arguments:
none
Returns:
path to install directory defined at site . installdir .
Globals:
none
Error:
none
Example:
$ installdir = xCAT::Utils - > getInstallDir ( ) ;
Comments:
none
= cut
#--------------------------------------------------------------------------------
sub getInstallDir
{
# Default installdir location. Used by default in most Linux distros.
my $ installdir = "/install" ;
# Try to lookup real installdir place.
2010-03-01 19:06:09 +00:00
my @ installdir1 = xCAT::Utils - > get_site_attribute ( "installdir" ) ;
2010-02-24 06:51:25 +00:00
# Use fetched value, incase successful database lookup.
if ( $ installdir1 [ 0 ] )
{
$ installdir = $ installdir1 [ 0 ] ;
}
return $ installdir ;
}
#--------------------------------------------------------------------------------
2010-02-24 08:49:37 +00:00
= head3 getTftpDir
Get location of the directory , used to hold network boot files .
Arguments:
none
Returns:
path to TFTP directory defined at site . tftpdir .
Globals:
none
Error:
none
Example:
$ tftpdir = xCAT::Utils - > getTftpDir ( ) ;
Comments:
none
= cut
#--------------------------------------------------------------------------------
sub getTftpDir
{
# Default tftpdir location. Used by default in most Linux distros.
my $ tftpdir = "/tftpboot" ;
# Try to lookup real tftpdir place.
2010-02-24 09:31:50 +00:00
my @ tftpdir1 = xCAT::Utils - > get_site_attribute ( "tftpdir" ) ;
2010-02-24 08:49:37 +00:00
# Use fetched value, incase successful database lookup.
if ( $ tftpdir1 [ 0 ] )
{
$ tftpdir = $ tftpdir1 [ 0 ] ;
}
return $ tftpdir ;
}
#--------------------------------------------------------------------------------
2007-12-20 19:02:45 +00:00
= head3 getHomeDir
Get the path the user home directory from /etc/ passwd .
2011-10-03 19:03:03 +00:00
If /etc/ passwd returns nothing ( id maybe in LDAP ) then
su - userid - c pwd to figure out where home is
2007-12-20 19:02:45 +00:00
Arguments:
none
Returns:
path to user home directory .
Globals:
none
Error:
none
Example:
$ myHome = xCAT::Utils - > getHomeDir ( ) ;
2011-10-03 19:03:03 +00:00
$ myHome = xCAT::Utils - > getHomeDir ( $ userid ) ;
2007-12-20 19:02:45 +00:00
Comments:
none
= cut
#--------------------------------------------------------------------------------
sub getHomeDir
{
my ( $ class , $ username ) = @ _ ;
2009-03-30 14:13:09 +00:00
my @ user ;
2011-10-03 19:03:03 +00:00
my $ homedir ;
2009-04-03 15:42:59 +00:00
if ( $ username )
{
2009-03-30 14:13:09 +00:00
@ user = getpwnam ( $ username ) ;
2009-04-03 15:42:59 +00:00
}
else
{
2009-03-30 14:13:09 +00:00
@ user = getpwuid ( $> ) ;
2011-10-03 19:03:03 +00:00
$ username = $ user [ 0 ] ;
}
if ( $ user [ 7 ] ) { # if homedir
$ homedir = $ user [ 7 ] ;
} else { # no home
$ homedir = `su - $username -c pwd` ;
chop $ homedir ;
2009-03-30 14:13:09 +00:00
}
2011-10-03 19:03:03 +00:00
return $ homedir ;
2007-12-20 19:02:45 +00:00
}
#--------------------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3 setupSSH
2007-12-20 19:02:45 +00:00
2009-02-04 17:18:44 +00:00
Generates if needed and Transfers the ssh keys
fOr a userid to setup ssh to the input nodes .
2007-12-20 19:02:45 +00:00
Arguments:
2008-04-05 14:53:35 +00:00
Array of nodes
2007-12-20 19:02:45 +00:00
Returns:
2008-04-05 14:53:35 +00:00
2009-02-04 17:18:44 +00:00
Env Variables: $ DSH_FROM_USERID , $ DSH_TO_USERID , $ DSH_REMOTE_PASSWORD
the ssh keys are transferred from the $ DSH_FROM_USERID to the $ DSH_TO_USERID
on the node ( s ) . The DSH_REMOTE_PASSWORD and the DSH_FROM_USERID
must be obtained by
the calling script or from the xdsh client
2007-12-20 19:02:45 +00:00
Globals:
2008-04-05 14:53:35 +00:00
$ ::XCATROOT , $ ::CALLBACK
2007-12-20 19:02:45 +00:00
Error:
2008-04-05 14:53:35 +00:00
0 = good , 1 = error
2007-12-20 19:02:45 +00:00
Example:
xCAT::Utils - > setupSSH ( @ target_nodes ) ;
Comments:
Does not setup known_hosts . Assumes automatically
setup by SSH ( ssh config option StrictHostKeyChecking no should
be set in the ssh config file ) .
= cut
#--------------------------------------------------------------------------------
sub setupSSH
{
my ( $ class , $ ref_nodes ) = @ _ ;
my @ nodes = $ ref_nodes ;
my @ badnodes = ( ) ;
2009-04-05 12:18:17 +00:00
my $ n_str = $ nodes [ 0 ] ;
2010-02-24 06:41:20 +00:00
my $ SSHdir = getInstallDir ( ) . "/postscripts/_ssh" ;
2009-02-04 17:18:44 +00:00
if ( ! ( $ ENV { 'DSH_REMOTE_PASSWORD' } ) )
{
my $ rsp = ( ) ;
$ rsp - > { data } - > [ 0 ] =
"User password for the ssh key exchange has not been input. xdsh -K cannot complete.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK , 1 ) ;
return ;
}
# setup who the keys are coming from and who they are going to
my $ from_userid ;
my $ to_userid ;
if ( ! ( $ ENV { 'DSH_FROM_USERID' } ) )
{
my $ rsp = ( ) ;
$ rsp - > { data } - > [ 0 ] =
"DSH From Userid has not been input. xdsh -K cannot complete.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK , 1 ) ;
return ;
}
else
{
$ from_userid = $ ENV { 'DSH_FROM_USERID' } ;
}
if ( ! ( $ ENV { 'DSH_TO_USERID' } ) )
{
my $ rsp = ( ) ;
$ rsp - > { data } - > [ 0 ] =
"DSH to Userid has not been input. xdsh -K cannot complete.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK , 1 ) ;
return ;
}
else
{
$ to_userid = $ ENV { 'DSH_TO_USERID' } ;
}
2007-12-20 19:02:45 +00:00
2009-04-03 15:42:59 +00:00
#
# if we are running as root
# for non-root users, keys were generated in the xdsh client code
#
2007-12-20 19:02:45 +00:00
2011-10-17 13:09:20 +00:00
$ ::REMOTE_SHELL = "/usr/bin/ssh" ;
2009-02-04 17:18:44 +00:00
my $ rsp = { } ;
2009-01-14 15:54:57 +00:00
2009-02-04 17:18:44 +00:00
# Get the home directory
my $ home = xCAT::Utils - > getHomeDir ( $ from_userid ) ;
$ ENV { 'DSH_FROM_USERID_HOME' } = $ home ;
2007-12-20 19:02:45 +00:00
2009-04-03 15:42:59 +00:00
if ( $ from_userid eq "root" )
{
# make the directory to hold keys to transfer to the nodes
if ( ! - d $ SSHdir )
{
2010-02-24 06:41:20 +00:00
mkpath ( "$SSHdir" , { mode = > 0755 } ) ;
2009-04-03 15:42:59 +00:00
}
# generates new keys for root, if they do not already exist
2011-10-17 13:09:20 +00:00
my $ rc =
xCAT::RemoteShellExp - > remoteshellexp ( "k" , $ ::CALLBACK , $ ::REMOTE_SHELL ) ;
if ( $ rc != 0 ) {
2011-10-17 13:19:25 +00:00
$ rsp - > { data } - > [ 0 ] = "remoteshellexp failed generating keys." ;
2009-04-03 15:42:59 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
2011-10-17 13:09:20 +00:00
}
2007-12-20 19:02:45 +00:00
}
2010-01-25 18:51:12 +00:00
2009-04-03 15:42:59 +00:00
# build the shell copy script, needed Perl not always there
# for root and non-root ids
2009-02-11 17:33:58 +00:00
open ( FILE , ">$home/.ssh/copy.sh" )
or die "cannot open file $home/.ssh/copy.sh\n" ;
print FILE " #!/bin/sh
umask 0077
2009-09-09 14:44:42 +00:00
home = `egrep \"^$to_userid:\" /etc/passwd | cut -f6 -d :`
2011-09-29 18:51:11 +00:00
if [ $ home ] ; then
dest_dir = \ " \ $ home / . ssh \ "
else
home = `su - root -c pwd`
dest_dir = \ " \ $ home / . ssh \ "
fi
2009-02-11 17:33:58 +00:00
mkdir - p \ $ dest_dir
cat /tmp/ $ to_userid /.ssh/ authorized_keys >> \ $ home /.ssh/ authorized_keys 2 > & 1
cp /tmp/ $ to_userid /.ssh/i d_rsa \ $ home /.ssh/i d_rsa 2 > & 1
chmod 0600 \ $ home /.ssh/i d_ * 2 > & 1
2010-02-21 18:00:44 +00:00
rm - f /tmp/ $ to_userid /.ssh/ * 2 > & 1
rmdir \ " /tmp/ $ to_userid / . ssh \ "
2011-11-17 17:10:20 +00:00
rmdir \ "/tmp/$to_userid\" \n" ;
2009-02-11 17:33:58 +00:00
2007-12-20 19:02:45 +00:00
close FILE ;
2009-04-03 15:42:59 +00:00
chmod 0777 , "$home/.ssh/copy.sh" ;
2009-11-10 18:34:51 +00:00
my $ auth_key = 0 ;
my $ auth_key2 = 0 ;
2010-03-17 13:05:46 +00:00
if ( $ from_userid eq "root" )
{
my $ rc = xCAT::Utils - > cpSSHFiles ( $ SSHdir ) ;
if ( $ rc != 0 )
{ # error
2009-02-18 19:03:45 +00:00
$ rsp - > { data } - > [ 0 ] = "Error running cpSSHFiles.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
return 1 ;
2009-02-04 17:18:44 +00:00
2010-03-17 13:05:46 +00:00
}
if ( xCAT::Utils - > isMN ( ) ) { # if on Management Node
2009-02-18 19:03:45 +00:00
# copy the copy install file to the install directory, if from and
# to userid are root
if ( $ to_userid eq "root" )
2009-02-04 17:18:44 +00:00
{
2009-02-18 19:03:45 +00:00
my $ cmd = " cp $home/.ssh/copy.sh $SSHdir/copy.sh" ;
xCAT::Utils - > runcmd ( $ cmd , 0 ) ;
my $ rsp = { } ;
if ( $ ::RUNCMD_RC != 0 )
{
$ rsp - > { data } - > [ 0 ] = "$cmd failed.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
return ( 1 ) ;
}
2009-02-04 17:18:44 +00:00
}
2010-03-17 13:05:46 +00:00
} # end is MN
}
else { # from_userid is not root
2009-04-03 15:42:59 +00:00
# build the authorized key files for non-root user
xCAT::Utils - > bldnonrootSSHFiles ( $ from_userid ) ;
2007-12-20 19:02:45 +00:00
}
2009-02-04 17:18:44 +00:00
# send the keys to the nodes for root or some other id
2007-12-20 19:02:45 +00:00
#
2010-11-03 11:55:29 +00:00
# This environment variable determines whether to setup
# node to node ssh
# The nodes must be checked against the site.sshbetweennodes attribute
# For root user and not to devices only to nodes
if ( ( $ from_userid eq "root" ) && ( ! ( $ ENV { 'DEVICETYPE' } ) ) ) {
my $ enablenodes ;
my $ disablenodes ;
my @ nodelist = split ( "," , $ n_str ) ;
foreach my $ n ( @ nodelist )
{
my $ enablessh = xCAT::Utils - > enablessh ( $ n ) ;
if ( $ enablessh == 1 ) {
$ enablenodes . = $ n ;
$ enablenodes . = "," ;
} else {
$ disablenodes . = $ n ;
$ disablenodes . = "," ;
}
}
my $ cmd ;
if ( $ enablenodes ) { # node on list to setup nodetonodessh
chop $ enablenodes ; # remove last comma
$ ENV { 'DSH_ENABLE_SSH' } = "YES" ;
2011-10-17 13:09:20 +00:00
my $ rc = xCAT::RemoteShellExp - > remoteshellexp ( "s" , $ ::CALLBACK , "/usr/bin/ssh" , $ enablenodes ) ;
if ( $ rc != 0 )
2010-11-03 11:55:29 +00:00
{
2011-10-17 13:19:25 +00:00
$ rsp - > { data } - > [ 0 ] = "remoteshellexp failed sending keys to enablenodes." ;
2010-11-03 11:55:29 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
}
}
if ( $ disablenodes ) { # node on list to setup nodetonodessh
chop $ disablenodes ; # remove last comma
2011-10-17 13:09:20 +00:00
my $ rc = xCAT::RemoteShellExp - > remoteshellexp ( "s" , $ ::CALLBACK , "/usr/bin/ssh" , $ disablenodes ) ;
if ( $ rc != 0 )
2010-11-03 11:55:29 +00:00
{
2011-10-17 13:19:25 +00:00
$ rsp - > { data } - > [ 0 ] = "remoteshellexp failed sending keys to disablenodes." ;
2010-11-03 11:55:29 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
}
}
} else { # from user is not root or it is a device , always send private key
$ ENV { 'DSH_ENABLE_SSH' } = "YES" ;
2011-10-17 13:09:20 +00:00
my $ rc = xCAT::RemoteShellExp - > remoteshellexp ( "s" , $ ::CALLBACK , "/usr/bin/ssh" , $ n_str ) ;
if ( $ rc != 0 )
2010-11-03 11:55:29 +00:00
{
2011-10-17 13:19:25 +00:00
$ rsp - > { data } - > [ 0 ] = "remoteshellexp failed sending keys." ;
2010-11-03 11:55:29 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
2007-12-20 19:02:45 +00:00
2010-11-03 11:55:29 +00:00
}
2007-12-20 19:02:45 +00:00
}
2009-02-18 19:03:45 +00:00
2007-12-20 19:02:45 +00:00
# must always check to see if worked, run test
2009-04-05 12:18:17 +00:00
my @ testnodes = split ( "," , $ nodes [ 0 ] ) ;
foreach my $ n ( @ testnodes )
2007-12-20 19:02:45 +00:00
{
2011-10-17 13:09:20 +00:00
my $ rc =
xCAT::RemoteShellExp - > remoteshellexp ( "t" , $ ::CALLBACK , "/usr/bin/ssh" , $ n ) ;
if ( $ rc != 0 )
2007-12-20 19:02:45 +00:00
{
push @ badnodes , $ n ;
}
}
if ( @ badnodes )
{
my $ nstring = join ',' , @ badnodes ;
$ rsp - > { data } - > [ 0 ] =
2008-04-05 14:53:35 +00:00
"SSH setup failed for the following nodes: $nstring." ;
2007-12-20 19:02:45 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
return @ badnodes ;
}
else
{
2008-04-05 14:53:35 +00:00
$ rsp - > { data } - > [ 0 ] = "$::REMOTE_SHELL setup is complete." ;
2007-12-20 19:02:45 +00:00
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::CALLBACK ) ;
return 0 ;
}
}
2007-11-28 19:44:47 +00:00
2007-12-20 19:02:45 +00:00
#--------------------------------------------------------------------------------
2007-11-28 19:44:47 +00:00
2007-12-20 19:02:45 +00:00
= head3 cpSSHFiles
2007-11-28 19:44:47 +00:00
2010-03-17 13:05:46 +00:00
Builds authorized_keyfiles for root
2007-11-28 19:44:47 +00:00
2007-12-20 19:02:45 +00:00
Arguments:
2009-04-03 15:42:59 +00:00
install directory path
2007-12-20 19:02:45 +00:00
Returns:
2008-04-05 14:53:35 +00:00
2007-12-20 19:02:45 +00:00
Globals:
2008-04-05 14:53:35 +00:00
$ ::CALLBACK
2007-12-20 19:02:45 +00:00
Error:
2007-11-28 19:44:47 +00:00
2007-12-20 19:02:45 +00:00
Example:
2009-04-03 15:42:59 +00:00
xCAT::Utils - > cpSSHFiles ( $ dir ) ;
2007-11-28 19:44:47 +00:00
2007-12-20 19:02:45 +00:00
Comments:
none
2007-11-28 19:44:47 +00:00
2007-12-20 19:02:45 +00:00
= cut
2007-11-28 19:44:47 +00:00
2007-12-20 19:02:45 +00:00
#--------------------------------------------------------------------------------
2009-11-25 16:24:08 +00:00
2007-12-20 19:02:45 +00:00
sub cpSSHFiles
{
my ( $ class , $ SSHdir ) = @ _ ;
my ( $ cmd , $ rc ) ;
2009-02-04 17:18:44 +00:00
my $ rsp = { } ;
2007-12-20 19:02:45 +00:00
if ( $ ::VERBOSE )
{
$ rsp - > { data } - > [ 0 ] = "Copying SSH Keys" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::CALLBACK ) ;
}
my $ home = xCAT::Utils - > getHomeDir ( "root" ) ;
2009-04-03 15:42:59 +00:00
2010-03-17 13:05:46 +00:00
if ( xCAT::Utils - > isMN ( ) ) { # if on Management Node
if ( ! ( - e "$home/.ssh/id_rsa.pub" ) ) # only using rsa
{
$ rsp - > { data } - > [ 0 ] = "Public key id_rsa.pub was missing in the .ssh directory." ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
return 1 ;
}
# copy to id_rsa public key to authorized_keys in the install directory
my $ authorized_keys = "$SSHdir/authorized_keys" ;
# changed from identity.pub
$ cmd = " cp $home/.ssh/id_rsa.pub $authorized_keys" ;
xCAT::Utils - > runcmd ( $ cmd , 0 ) ;
$ rsp = { } ;
if ( $ ::RUNCMD_RC != 0 )
{
2009-02-04 17:18:44 +00:00
$ rsp - > { data } - > [ 0 ] = "$cmd failed.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
return ( 1 ) ;
2010-03-17 13:05:46 +00:00
}
else
{
2009-02-04 17:18:44 +00:00
if ( $ ::VERBOSE )
{
$ rsp - > { data } - > [ 0 ] = "$cmd succeeded.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::CALLBACK ) ;
}
2010-03-17 13:05:46 +00:00
}
} # end is MN
2009-04-03 15:42:59 +00:00
2010-03-17 13:05:46 +00:00
# on MN and SN
2010-02-21 17:46:20 +00:00
# make tmp directory to hold authorized_keys for node transfer
2010-02-21 18:00:44 +00:00
if ( ! ( - e "$home/.ssh/tmp" ) ) {
$ cmd = " mkdir $home/.ssh/tmp" ;
xCAT::Utils - > runcmd ( $ cmd , 0 ) ;
$ rsp = { } ;
if ( $ ::RUNCMD_RC != 0 )
{
2010-02-21 17:46:20 +00:00
$ rsp - > { data } - > [ 0 ] = "$cmd failed.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
return ( 1 ) ;
2010-02-21 18:00:44 +00:00
}
2010-02-21 17:46:20 +00:00
}
# create authorized_keys file
2010-03-17 13:05:46 +00:00
if ( xCAT::Utils - > isMN ( ) ) { # if on Management Node
$ cmd = " cp $home/.ssh/id_rsa.pub $home/.ssh/tmp/authorized_keys" ;
} else { # SN
$ cmd = " cp $home/.ssh/authorized_keys $home/.ssh/tmp/authorized_keys" ;
}
2009-02-04 17:18:44 +00:00
xCAT::Utils - > runcmd ( $ cmd , 0 ) ;
2010-02-04 13:40:09 +00:00
$ rsp = { } ;
2007-12-20 19:02:45 +00:00
if ( $ ::RUNCMD_RC != 0 )
{
$ rsp - > { data } - > [ 0 ] = "$cmd failed.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
return ( 1 ) ;
}
else
{
2010-02-21 17:46:20 +00:00
chmod 0600 , "$home/.ssh/tmp/authorized_keys" ;
2007-12-20 19:02:45 +00:00
if ( $ ::VERBOSE )
{
$ rsp - > { data } - > [ 0 ] = "$cmd succeeded.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::CALLBACK ) ;
}
}
return ( 0 ) ;
}
2008-02-04 20:02:15 +00:00
2009-04-03 15:42:59 +00:00
#--------------------------------------------------------------------------------
= head3 bldnonrootSSHFiles
Builds authorized_keyfiles for the non - root id
It must not only contain the public keys for the non - root id
but also the public keys for root
Arguments:
from_userid - current id running xdsh from the command line
Returns:
Globals:
$ ::CALLBACK
Error:
Example:
xCAT::Utils - > bldnonrootSSHFiles ;
Comments:
none
= cut
#--------------------------------------------------------------------------------
sub bldnonrootSSHFiles
{
my ( $ class , $ from_userid ) = @ _ ;
my ( $ cmd , $ rc ) ;
my $ rsp = { } ;
if ( $ ::VERBOSE )
{
$ rsp - > { data } - > [ 0 ] = "Building SSH Keys for $from_userid" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::CALLBACK ) ;
}
my $ home = xCAT::Utils - > getHomeDir ( $ from_userid ) ;
2011-09-29 18:51:11 +00:00
# Handle non-root userid may not be in /etc/passwd maybe LDAP
if ( ! $ home ) {
$ home = `su - $from_userid -c pwd` ;
chop $ home ;
}
2009-04-03 15:42:59 +00:00
my $ roothome = xCAT::Utils - > getHomeDir ( "root" ) ;
2010-03-17 13:05:46 +00:00
if ( xCAT::Utils - > isMN ( ) ) { # if on Management Node
if ( ! ( - e "$home/.ssh/id_rsa.pub" ) )
{
return 1 ;
}
2009-04-03 15:42:59 +00:00
}
2010-02-21 17:46:20 +00:00
# make tmp directory to hold authorized_keys for node transfer
2010-02-21 18:00:44 +00:00
if ( ! ( - e "$home/.ssh/tmp" ) ) {
$ cmd = " mkdir $home/.ssh/tmp" ;
xCAT::Utils - > runcmd ( $ cmd , 0 ) ;
$ rsp = { } ;
if ( $ ::RUNCMD_RC != 0 )
{
2010-02-21 17:46:20 +00:00
$ rsp - > { data } - > [ 0 ] = "$cmd failed.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
return ( 1 ) ;
2010-02-21 18:00:44 +00:00
}
2010-02-21 17:46:20 +00:00
}
2010-03-17 13:05:46 +00:00
# create authorized_key file in tmp directory for transfer
if ( xCAT::Utils - > isMN ( ) ) { # if on Management Node
$ cmd = " cp $home/.ssh/id_rsa.pub $home/.ssh/tmp/authorized_keys" ;
} else { # SN
$ cmd = " cp $home/.ssh/authorized_keys $home/.ssh/tmp/authorized_keys" ;
}
2009-04-03 15:42:59 +00:00
xCAT::Utils - > runcmd ( $ cmd , 0 ) ;
2010-02-04 13:40:09 +00:00
$ rsp = { } ;
2009-04-03 15:42:59 +00:00
if ( $ ::RUNCMD_RC != 0 )
{
$ rsp - > { data } - > [ 0 ] = "$cmd failed.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::CALLBACK ) ;
return ( 1 ) ;
}
else
{
2010-03-17 13:05:46 +00:00
chmod 0600 , "$home/.ssh/tmp/authorized_keys" ;
2009-04-03 15:42:59 +00:00
if ( $ ::VERBOSE )
{
$ rsp - > { data } - > [ 0 ] = "$cmd succeeded.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::CALLBACK ) ;
}
}
2010-03-17 13:05:46 +00:00
if ( xCAT::Utils - > isMN ( ) ) { # if on Management Node
# if cannot access, warn and continue
$ rsp = { } ;
$ cmd = "cat $roothome/.ssh/id_rsa.pub >> $home/.ssh/tmp/authorized_keys" ;
xCAT::Utils - > runcmd ( $ cmd , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
2009-04-03 15:42:59 +00:00
$ rsp - > { data } - > [ 0 ] = "Warning: Cannot give $from_userid root ssh authority. \n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::CALLBACK ) ;
2010-03-17 13:05:46 +00:00
}
else
{
2009-04-03 15:42:59 +00:00
if ( $ ::VERBOSE )
{
$ rsp - > { data } - > [ 0 ] = "$cmd succeeded.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::CALLBACK ) ;
}
2010-03-17 13:05:46 +00:00
}
2009-04-03 15:42:59 +00:00
}
2010-02-21 18:00:44 +00:00
2009-04-03 15:42:59 +00:00
return ( 0 ) ;
}
2008-01-22 14:59:14 +00:00
#-------------------------------------------------------------------------------
= head3 isServiceNode
2008-04-05 14:53:35 +00:00
checks for the /etc/x CATSN file
2008-01-22 14:59:14 +00:00
Arguments:
none
Returns:
2008-04-05 14:53:35 +00:00
1 - localHost is ServiceNode
0 - localHost is not ServiceNode
2008-01-22 14:59:14 +00:00
Globals:
none
Error:
none
Example:
% ::XCATMasterPort defined in the caller .
2008-04-05 14:53:35 +00:00
$ return = ( xCAT::Utils - > isServiceNode ( ) )
2008-01-22 14:59:14 +00:00
Comments:
none
= cut
#-------------------------------------------------------------------------------
sub isServiceNode
{
my $ value ;
2008-02-18 15:10:31 +00:00
if ( - e "/etc/xCATSN" )
2008-01-22 14:59:14 +00:00
{
2008-02-06 17:19:13 +00:00
return 1 ;
2008-02-18 15:10:31 +00:00
}
else
{
2008-02-06 17:19:13 +00:00
return 0 ;
2008-02-18 15:10:31 +00:00
}
2008-02-07 20:11:52 +00:00
}
2008-03-26 18:20:05 +00:00
2008-03-13 12:08:34 +00:00
#-------------------------------------------------------------------------------
2008-03-31 15:52:36 +00:00
= head3 isMN
checks for the /etc/x CATMN file , if it exists it is a Management Server
2008-04-05 14:53:35 +00:00
2008-03-13 12:08:34 +00:00
Arguments:
none
Returns:
2008-07-21 18:03:47 +00:00
1 - localHost is Management Node
0 - localHost is not a Management Node
2008-03-13 12:08:34 +00:00
Globals:
none
Error:
none
Example:
2008-04-05 14:53:35 +00:00
$ return = ( xCAT::Utils - > isMN ( ) )
2008-03-13 12:08:34 +00:00
Comments:
none
= cut
#-------------------------------------------------------------------------------
2008-03-31 15:52:36 +00:00
sub isMN
2008-03-13 12:08:34 +00:00
{
my $ value ;
2008-03-31 15:52:36 +00:00
if ( - e "/etc/xCATMN" )
2008-03-13 12:08:34 +00:00
{
return 1 ;
}
else
{
return 0 ;
}
}
#-------------------------------------------------------------------------------
2008-03-19 15:22:03 +00:00
= head3 classful_networks_for_net_and_mask
2008-04-05 14:53:35 +00:00
2008-03-19 15:22:03 +00:00
Arguments:
network and mask
Returns:
a list of classful subnets that constitute the entire potentially classless arguments
Globals:
none
Error:
none
Example:
Comments:
none
= cut
#-------------------------------------------------------------------------------
2008-03-26 18:20:05 +00:00
sub classful_networks_for_net_and_mask
2008-03-19 15:22:03 +00:00
{
2008-03-26 18:20:05 +00:00
my $ network = shift ;
my $ mask = shift ;
2008-03-19 15:22:03 +00:00
my $ given_mask = 0 ;
2008-03-26 18:20:05 +00:00
if ( $ mask =~ /\./ )
{
$ given_mask = 1 ;
my $ masknumber = unpack ( "N" , inet_aton ( $ mask ) ) ;
$ mask = 32 ;
until ( $ masknumber % 2 )
{
$ masknumber = $ masknumber >> 1 ;
$ mask - - ;
}
}
2008-03-19 15:22:03 +00:00
my @ results ;
my $ bitstoeven = ( 8 - ( $ mask % 8 ) ) ;
if ( $ bitstoeven eq 8 ) { $ bitstoeven = 0 ; }
my $ resultmask = $ mask + $ bitstoeven ;
2008-03-26 18:20:05 +00:00
if ( $ given_mask )
{
$ resultmask =
inet_ntoa ( pack ( "N" , ( 2 ** $ resultmask - 1 ) << ( 32 - $ resultmask ) ) ) ;
2008-03-19 15:22:03 +00:00
}
2008-03-26 18:20:05 +00:00
push @ results , $ resultmask ;
2008-03-19 15:22:03 +00:00
my $ padbits = ( 32 - ( $ bitstoeven + $ mask ) ) ;
my $ numchars = int ( ( $ mask + $ bitstoeven ) / 4 ) ;
my $ curmask = 2 ** $ mask - 1 << ( 32 - $ mask ) ;
my $ nown = unpack ( "N" , inet_aton ( $ network ) ) ;
$ nown = $ nown & $ curmask ;
my $ highn = $ nown + ( ( 2 ** $ bitstoeven - 1 ) << ( 32 - $ mask - $ bitstoeven ) ) ;
while ( $ nown <= $ highn )
{
2008-03-26 18:20:05 +00:00
push @ results , inet_ntoa ( pack ( "N" , $ nown ) ) ;
#$rethash->{substr($nowhex, 0, $numchars)} = $network;
$ nown += 1 << ( 32 - $ mask - $ bitstoeven ) ;
2008-03-19 15:22:03 +00:00
}
return @ results ;
}
#-------------------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3 my_hexnets
2008-03-13 12:08:34 +00:00
Arguments:
none
Returns:
Globals:
none
Error:
none
Example:
Comments:
none
= cut
2008-02-07 20:11:52 +00:00
2008-03-13 12:08:34 +00:00
#-------------------------------------------------------------------------------
2008-02-25 14:18:18 +00:00
sub my_hexnets
{
2008-02-26 19:57:10 +00:00
my $ rethash ;
2008-02-25 14:18:18 +00:00
my @ nets = split /\n/ , `/sbin/ip addr` ;
foreach ( @ nets )
{
my @ elems = split /\s+/ ;
unless ( /^\s*inet\s/ )
{
next ;
}
( my $ curnet , my $ maskbits ) = split /\// , $ elems [ 2 ] ;
2008-02-26 19:57:10 +00:00
my $ bitstoeven = ( 4 - ( $ maskbits % 4 ) ) ;
2008-02-25 14:18:18 +00:00
if ( $ bitstoeven eq 4 ) { $ bitstoeven = 0 ; }
2008-02-26 19:57:10 +00:00
my $ padbits = ( 32 - ( $ bitstoeven + $ maskbits ) ) ;
my $ numchars = int ( ( $ maskbits + $ bitstoeven ) / 4 ) ;
my $ curmask = 2 ** $ maskbits - 1 << ( 32 - $ maskbits ) ;
my $ nown = unpack ( "N" , inet_aton ( $ curnet ) ) ;
2008-02-25 14:18:18 +00:00
$ nown = $ nown & $ curmask ;
2008-02-26 19:57:10 +00:00
my $ highn =
$ nown + ( ( 2 ** $ bitstoeven - 1 ) << ( 32 - $ maskbits - $ bitstoeven ) ) ;
while ( $ nown <= $ highn )
{
my $ nowhex = sprintf ( "%08x" , $ nown ) ;
$ rethash - > { substr ( $ nowhex , 0 , $ numchars ) } = $ curnet ;
$ nown += 1 << ( 32 - $ maskbits - $ bitstoeven ) ;
2008-02-25 14:18:18 +00:00
}
}
return $ rethash ;
}
2008-02-26 19:57:10 +00:00
2009-07-23 20:02:39 +00:00
#-------------------------------------------------------------------------------
= head3 get_host_from_ip
Description:
Get the hostname of an IP addresses . First from hosts table , and then try system resultion .
If there is a shortname , it will be returned . Otherwise it will return long name . If the IP cannot be resolved , return undef ;
Arguments:
$ ip: the IP to get ;
Returns:
Return: the hostname .
For an example
Globals:
none
Error:
none
Example:
xCAT::Utils:: get_host_from_ip ( '192.168.200.1' )
Comments:
= cut
#-----------------------------------------------------------------------
sub get_host_from_ip
{
my $ ip = shift ;
}
#-------------------------------------------------------------------------------
= head3 isPingable
Description:
Check if an IP address can be pinged
Arguments:
$ ip: the IP to ping ;
Returns:
Return: 1 indicates yes ; 0 indicates no .
For an example
Globals:
none
Error:
none
Example:
xCAT::Utils:: isPingable ( '192.168.200.1' )
Comments:
none
= cut
#-----------------------------------------------------------------------
2010-02-04 18:29:12 +00:00
my % PING_CACHE ;
2009-07-23 20:02:39 +00:00
sub isPingable
{
my $ ip = shift ;
my $ rc ;
2010-02-04 18:29:12 +00:00
if ( exists $ PING_CACHE { $ ip } )
2009-07-23 20:02:39 +00:00
{
2010-02-04 18:29:12 +00:00
$ rc = $ PING_CACHE { $ ip } ;
2009-07-23 20:02:39 +00:00
}
else
{
my $ res = `LANG=C ping -c 1 -w 5 $ip 2>&1` ;
if ( $ res =~ /100% packet loss/g )
{
$ rc = 1 ;
}
else
{
$ rc = 0 ;
}
2010-02-04 18:29:12 +00:00
$ PING_CACHE { $ ip } = $ rc ;
2009-07-23 20:02:39 +00:00
}
return ! $ rc ;
}
#-------------------------------------------------------------------------------
= head3 my_nets
Description:
Return a hash ref that contains all subnet and netmask on the mn ( or sn ) . This subroutine can be invoked on both Linux and AIX .
Arguments:
none .
Returns:
Return a hash ref . Each entry will be: <subnet/mask> = > < existing ip > ;
For an example:
'192.168.200.0/255.255.255.0' = > '192.168.200.246' ;
For an example
Globals:
none
Error:
none
Example:
xCAT::Utils:: my_nets ( ) .
Comments:
none
= cut
#-----------------------------------------------------------------------
2009-06-26 19:29:01 +00:00
sub my_nets
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2009-06-26 19:29:01 +00:00
my $ rethash ;
2009-07-23 20:02:39 +00:00
my @ nets ;
2010-05-10 09:49:53 +00:00
my $ v6net ;
my $ v6ip ;
2009-07-23 20:02:39 +00:00
if ( $^O eq 'aix' )
{
@ nets = split /\n/ , `/usr/sbin/ifconfig -a` ;
}
else
{
@ nets = split /\n/ , `/sbin/ip addr` ; #could use ip route, but to match hexnets...
}
2009-06-26 19:29:01 +00:00
foreach ( @ nets )
{
2010-05-10 09:49:53 +00:00
$ v6net = '' ;
2009-06-26 19:29:01 +00:00
my @ elems = split /\s+/ ;
2010-05-10 09:49:53 +00:00
unless ( /^\s*inet/ )
2009-06-26 19:29:01 +00:00
{
next ;
}
2009-07-23 20:02:39 +00:00
my $ curnet ; my $ maskbits ;
if ( $^O eq 'aix' )
{
2010-05-10 09:49:53 +00:00
if ( $ elems [ 1 ] eq 'inet6' )
{
$ v6net = $ elems [ 2 ] ;
$ v6ip = $ elems [ 2 ] ;
$ v6ip =~ s/\/.*// ; # ipv6 address 4000::99/64
$ v6ip =~ s/\%.*// ; # ipv6 address ::1%1/128
}
else
{
$ curnet = $ elems [ 2 ] ;
$ maskbits = formatNetmask ( $ elems [ 4 ] , 2 , 1 ) ;
}
2009-07-23 20:02:39 +00:00
}
else
{
2010-06-03 01:33:33 +00:00
if ( $ elems [ 1 ] eq 'inet6' )
{
next ; #Linux IPv6 TODO, do not return IPv6 networks on Linux for now
}
2009-07-23 20:02:39 +00:00
( $ curnet , $ maskbits ) = split /\// , $ elems [ 2 ] ;
}
2010-05-10 09:49:53 +00:00
if ( ! $ v6net )
{
my $ curmask = 2 ** $ maskbits - 1 << ( 32 - $ maskbits ) ;
my $ nown = unpack ( "N" , inet_aton ( $ curnet ) ) ;
$ nown = $ nown & $ curmask ;
my $ textnet = inet_ntoa ( pack ( "N" , $ nown ) ) ;
$ textnet . = "/$maskbits" ;
$ rethash - > { $ textnet } = $ curnet ;
}
else
{
$ rethash - > { $ v6net } = $ v6ip ;
}
2009-06-26 19:29:01 +00:00
}
2010-01-18 20:36:08 +00:00
2010-05-10 09:49:53 +00:00
2010-01-20 02:14:46 +00:00
# now get remote nets
2010-01-18 20:36:08 +00:00
my $ nettab = xCAT::Table - > new ( "networks" ) ;
2010-01-20 02:14:46 +00:00
my $ sitetab = xCAT::Table - > new ( "site" ) ;
my $ master = $ sitetab - > getAttribs ( { key = > 'master' } , 'value' ) ;
$ master = $ master - > { value } ;
2010-01-18 20:36:08 +00:00
my @ vnets = $ nettab - > getAllAttribs ( 'net' , 'mgtifname' , 'mask' ) ;
2010-01-20 02:14:46 +00:00
2010-01-18 20:36:08 +00:00
foreach ( @ vnets ) {
my $ n = $ _ - > { net } ;
my $ if = $ _ - > { mgtifname } ;
2010-01-20 02:14:46 +00:00
my $ nm = $ _ - > { mask } ;
2011-03-27 12:18:38 +00:00
if ( ! $ n || ! $ if || $ nm )
2010-06-03 01:33:33 +00:00
{
next ; #incomplete network
}
2010-01-18 20:36:08 +00:00
if ( $ if =~ /!remote!/ ) { #only take in networks with special interface
$ nm = formatNetmask ( $ nm , 0 , 1 ) ;
2010-01-20 02:14:46 +00:00
$ n . = "/$nm" ;
#$rethash->{$n} = $if;
$ rethash - > { $ n } = $ master ;
}
2010-01-18 20:36:08 +00:00
}
2009-06-26 19:29:01 +00:00
return $ rethash ;
}
2008-03-21 20:00:07 +00:00
#-------------------------------------------------------------------------------
= head3 my_if_netmap
Arguments:
none
Returns:
hash of networks to interface names
Globals:
none
Error:
none
Comments:
none
= cut
2008-03-26 18:20:05 +00:00
2008-03-21 20:00:07 +00:00
#-------------------------------------------------------------------------------
2008-03-26 18:20:05 +00:00
sub my_if_netmap
{
2008-07-18 12:30:22 +00:00
my $ net ;
2008-03-26 18:20:05 +00:00
if ( scalar ( @ _ ) )
{ #called with the other syntax
$ net = shift ;
}
my @ rtable = split /\n/ , `netstat -rn` ;
if ( $? )
{
return "Unable to run netstat, $?" ;
}
my % retmap ;
foreach ( @ rtable )
{
if ( /^\D/ ) { next ; } #skip headers
if ( /^\S+\s+\S+\s+\S+\s+\S*G/ )
{
next ;
} #Skip networks that require gateways to get to
/^(\S+)\s.*\s(\S+)$/ ;
$ retmap { $ 1 } = $ 2 ;
}
return \ % retmap ;
2008-03-21 20:00:07 +00:00
}
2008-02-04 20:02:15 +00:00
#-------------------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3 my_ip_facing
2009-03-12 15:41:11 +00:00
Returns my ip address
Linux only
2008-02-04 20:02:15 +00:00
Arguments:
2009-03-12 15:41:11 +00:00
nodename
2008-02-04 20:02:15 +00:00
Returns:
Globals:
none
Error:
none
Example:
Comments:
none
= cut
2008-02-18 15:10:31 +00:00
#-------------------------------------------------------------------------------
sub my_ip_facing
{
my $ peer = shift ;
if ( @ _ )
{
$ peer = shift ;
}
2009-07-07 02:07:30 +00:00
return my_ip_facing_aix ( $ peer ) if ( $^O eq 'aix' ) ;
2011-10-04 15:57:15 +00:00
my $ peernumber = inet_aton ( $ peer ) ; #TODO: IPv6 support
unless ( $ peernumber ) { return undef ; }
2008-02-18 15:10:31 +00:00
my $ noden = unpack ( "N" , inet_aton ( $ peer ) ) ;
my @ nets = split /\n/ , `/sbin/ip addr` ;
foreach ( @ nets )
{
my @ elems = split /\s+/ ;
unless ( /^\s*inet\s/ )
{
next ;
}
( my $ curnet , my $ maskbits ) = split /\// , $ elems [ 2 ] ;
my $ curmask = 2 ** $ maskbits - 1 << ( 32 - $ maskbits ) ;
my $ curn = unpack ( "N" , inet_aton ( $ curnet ) ) ;
if ( ( $ noden & $ curmask ) == ( $ curn & $ curmask ) )
{
return $ curnet ;
}
}
return undef ;
}
#-------------------------------------------------------------------------------
2009-07-07 02:07:30 +00:00
= head3 my_ip_facing_aix
Returns my ip address
AIX only
Arguments:
nodename
Returns:
Globals:
none
Error:
none
Example:
Comments:
none
= cut
#-------------------------------------------------------------------------------
sub my_ip_facing_aix
{
my $ peer = shift ;
my @ nets = `ifconfig -a` ;
chomp @ nets ;
foreach my $ net ( @ nets )
{
2010-05-11 01:56:26 +00:00
my ( $ curnet , $ netmask ) ;
2009-07-07 02:07:30 +00:00
if ( $ net =~ /^\s*inet\s+([\d\.]+)\s+netmask\s+(\w+)\s+broadcast/ )
{
2010-05-11 01:56:26 +00:00
( $ curnet , $ netmask ) = ( $ 1 , $ 2 ) ;
}
elsif ( $ net =~ /^\s*inet6\s+(.*)$/ )
{
( $ curnet , $ netmask ) = split ( '/' , $ 1 ) ;
}
else
{
next ;
}
if ( isInSameSubnet ( $ peer , $ curnet , $ netmask , 2 ) )
{
return $ curnet ;
2009-07-07 02:07:30 +00:00
}
}
return undef ;
}
#-------------------------------------------------------------------------------
= head3 formatNetmask
Description:
Transform netmask to one of 3 formats ( 255.255 .255 .0 , 24 , 0xffffff00 ) .
Arguments:
$ netmask: the original netmask
$ origType: the original netmask type . The valid value can be 0 , 1 , 2 :
Type 0 : 255.255 .255 .0
Type 1 : 24
Type 2 : 0xffffff00
$ newType: the new netmask type , valid values can be 0 , 1 , 2 , as above .
Returns:
Return undef if any error . Otherwise return the netmask in new format .
Globals:
none
Error:
none
Example:
xCAT::Utils:: formatNetmask ( '24' , 1 , 0 ) ; #return '255.255.255.0'.
Comments:
none
= cut
#-----------------------------------------------------------------------
sub formatNetmask
{
my $ mask = shift ;
my $ origType = shift ;
my $ newType = shift ;
my $ maskn ;
if ( $ origType == 0 )
{
$ maskn = unpack ( "N" , inet_aton ( $ mask ) ) ;
}
elsif ( $ origType == 1 )
{
$ maskn = 2 ** $ mask - 1 << ( 32 - $ mask ) ;
}
elsif ( $ origType == 2 )
{
$ maskn = hex $ mask ;
}
else
{
return undef ;
}
if ( $ newType == 0 )
{
return inet_ntoa ( pack ( 'N' , $ maskn ) ) ;
}
if ( $ newType == 1 )
{
my $ bin = unpack ( "B32" , pack ( "N" , $ maskn ) ) ;
my @ dup = ( $ bin =~ /(1{1})0*/g ) ;
return scalar ( @ dup ) ;
}
if ( $ newType == 2 )
{
return sprintf "0x%1x" , $ maskn ;
}
return undef ;
}
#-------------------------------------------------------------------------------
= head3 isInSameSubnet
Description:
Check if 2 given IP addresses are in same subnet
Arguments:
$ ip1: the first IP
$ ip2: the second IP
$ mask: the netmask , here are 3 possible netmask types , following are examples for these 3 types:
Type 0 : 255.255 .255 .0
Type 1 : 24
Type 2 : 0xffffff00
$ masktype: the netmask type , 3 possible values : 0 , 1 , 2 , as indicated above
Returns:
1 : they are in same subnet
2 : not in same subnet
Globals:
none
Error:
none
Example:
xCAT::Utils:: isInSameSubnet ( '192.168.10.1' , '192.168.10.2' , '255.255.255.0' , 0 ) ;
Comments:
none
= cut
#-----------------------------------------------------------------------
sub isInSameSubnet
{
my $ ip1 = shift ;
my $ ip2 = shift ;
my $ mask = shift ;
my $ maskType = shift ;
2010-05-11 01:56:26 +00:00
$ ip1 = xCAT::NetworkUtils - > getipaddr ( $ ip1 ) ;
$ ip2 = xCAT::NetworkUtils - > getipaddr ( $ ip2 ) ;
2011-02-21 07:20:14 +00:00
if ( ! defined ( $ ip1 ) || ! defined ( $ ip2 ) )
{
return undef ;
}
2010-05-11 01:56:26 +00:00
if ( ( ( $ ip1 =~ /\d+\.\d+\.\d+\.\d+/ ) && ( $ ip2 !~ /\d+\.\d+\.\d+\.\d+/ ) )
|| ( ( $ ip1 !~ /\d+\.\d+\.\d+\.\d+/ ) && ( $ ip2 =~ /\d+\.\d+\.\d+\.\d+/ ) ) )
2009-07-07 02:07:30 +00:00
{
2010-05-11 01:56:26 +00:00
#ipv4 and ipv6 can not be in the same subnet
return undef ;
2009-07-07 02:07:30 +00:00
}
2010-05-11 01:56:26 +00:00
if ( ( $ ip1 =~ /\d+\.\d+\.\d+\.\d+/ ) && ( $ ip2 =~ /\d+\.\d+\.\d+\.\d+/ ) )
2009-07-07 02:07:30 +00:00
{
2010-05-11 01:56:26 +00:00
my $ maskn ;
if ( $ maskType == 0 )
{
$ maskn = unpack ( "N" , inet_aton ( $ mask ) ) ;
}
elsif ( $ maskType == 1 )
{
$ maskn = 2 ** $ mask - 1 << ( 32 - $ mask ) ;
}
elsif ( $ maskType == 2 )
{
$ maskn = hex $ mask ;
}
else
{
return undef ;
}
my $ ip1n = unpack ( "N" , inet_aton ( $ ip1 ) ) ;
my $ ip2n = unpack ( "N" , inet_aton ( $ ip2 ) ) ;
return ( ( $ ip1n & $ maskn ) == ( $ ip2n & $ maskn ) ) ;
2009-07-07 02:07:30 +00:00
}
else
{
2010-05-11 01:56:26 +00:00
#ipv6
if ( ( $ ip1 =~ /\%/ ) || ( $ ip2 =~ /\%/ ) )
{
return undef ;
}
my $ netipmodule = eval { require Net::IP ; } ;
if ( $ netipmodule ) {
my $ eip1 = Net::IP:: ip_expand_address ( $ ip1 , 6 ) ;
my $ eip2 = Net::IP:: ip_expand_address ( $ ip2 , 6 ) ;
my $ bmask = Net::IP:: ip_get_mask ( $ mask , 6 ) ;
my $ bip1 = Net::IP:: ip_iptobin ( $ eip1 , 6 ) ;
my $ bip2 = Net::IP:: ip_iptobin ( $ eip2 , 6 ) ;
if ( ( $ bip1 & $ bmask ) == ( $ bip2 & $ bmask ) ) {
return 1 ;
}
} # else, can not check without Net::IP module
return undef ;
}
2009-07-07 02:07:30 +00:00
}
#-------------------------------------------------------------------------------
2009-04-17 16:35:54 +00:00
= head3 nodeonmynet - checks to see if node is on any network this server is attached to or remote network potentially managed by this system
2008-02-18 15:10:31 +00:00
Arguments:
2008-04-05 14:53:35 +00:00
Node name
2008-02-18 15:10:31 +00:00
Returns: 1 if node is on the network
Globals:
none
Error:
none
Example:
Comments:
none
= cut
2008-02-04 20:02:15 +00:00
#-------------------------------------------------------------------------------
sub nodeonmynet
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2008-02-04 20:02:15 +00:00
my $ nodetocheck = shift ;
if ( scalar ( @ _ ) )
{
$ nodetocheck = shift ;
}
2010-02-04 08:29:06 +00:00
my $ nodeip = getNodeIPaddress ( $ nodetocheck ) ;
2010-05-12 01:45:48 +00:00
if ( ! $ nodeip )
{
return 0 ;
}
2008-02-04 20:02:15 +00:00
unless ( $ nodeip =~ /\d+\.\d+\.\d+\.\d+/ )
{
2010-05-12 01:45:48 +00:00
#IPv6
if ( $^O eq 'aix' )
{
my @ subnets = get_subnet_aix ( ) ;
for my $ net_ent ( @ subnets )
{
if ( $ net_ent !~ /-/ )
{
#ipv4
next ;
}
my ( $ net , $ interface , $ mask , $ flag ) = split /-/ , $ net_ent ;
if ( xCAT::NetworkUtils - > ishostinsubnet ( $ nodeip , $ mask , $ net ) )
{
return 1 ;
}
}
2011-01-17 20:24:28 +00:00
} else {
my @ v6routes = split /\n/ , `ip -6 route` ;
foreach ( @ v6routes ) {
2011-11-04 17:55:35 +00:00
if ( /via/ or /^unreachable/ or /^fe80::\/64/ ) {
#only count local ones, remote ones can be caught in next loop
#also, link-local would be a pitfall,
#since more context than address is
#needed to determine locality
2011-01-17 20:24:28 +00:00
next ;
}
s/ .*// ; #remove all after the space
if ( xCAT::NetworkUtils - > ishostinsubnet ( $ nodeip , '' , $ _ ) ) { #bank on CIDR support
return 1 ;
}
}
2010-05-12 01:45:48 +00:00
}
my $ nettab = xCAT::Table - > new ( "networks" ) ;
my @ vnets = $ nettab - > getAllAttribs ( 'net' , 'mgtifname' , 'mask' ) ;
foreach ( @ vnets ) {
if ( ( defined $ _ - > { mgtifname } ) && ( $ _ - > { mgtifname } eq '!remote!' ) )
{
if ( xCAT::NetworkUtils - > ishostinsubnet ( $ nodeip , $ _ - > { mask } , $ _ - > { net } ) )
{
return 1 ;
}
}
}
return 0 ;
2008-02-04 20:02:15 +00:00
}
my $ noden = unpack ( "N" , inet_aton ( $ nodeip ) ) ;
2009-04-17 16:35:54 +00:00
my @ nets ;
if ( $ utildata - > { nodeonmynetdata } and $ utildata - > { nodeonmynetdata } - > { pid } == $$ ) {
2009-04-17 20:29:52 +00:00
@ nets = @ { $ utildata - > { nodeonmynetdata } - > { nets } } ;
2009-04-17 16:35:54 +00:00
} else {
2009-07-07 02:07:30 +00:00
if ( $^O eq 'aix' )
{
my @ subnets = get_subnet_aix ( ) ;
for my $ net_ent ( @ subnets )
{
2010-05-12 01:45:48 +00:00
if ( $ net_ent =~ /-/ )
{
#ipv6
next ;
}
2009-07-07 02:07:30 +00:00
my @ ents = split /:/ , $ net_ent ;
push @ nets , $ ents [ 0 ] . '/' . $ ents [ 2 ] . ' dev ' . $ ents [ 1 ] ;
}
}
else
{
@ nets = split /\n/ , `/sbin/ip route` ;
}
2009-04-17 16:35:54 +00:00
my $ nettab = xCAT::Table - > new ( "networks" ) ;
my @ vnets = $ nettab - > getAllAttribs ( 'net' , 'mgtifname' , 'mask' ) ;
foreach ( @ vnets ) {
2010-03-31 12:45:48 +00:00
if ( ( defined $ _ - > { mgtifname } ) && ( $ _ - > { mgtifname } eq '!remote!' ) )
{ #global scoped network
2009-04-17 16:35:54 +00:00
my $ curm = unpack ( "N" , inet_aton ( $ _ - > { mask } ) ) ;
my $ bits = 32 ;
until ( $ curm & 1 ) {
$ bits - - ;
$ curm = $ curm >> 1 ;
}
2009-04-17 20:29:52 +00:00
push @ nets , $ _ - > { 'net' } . "/" . $ bits . " dev remote" ;
2009-04-17 16:35:54 +00:00
}
}
$ utildata - > { nodeonmynetdata } - > { pid } = $$ ;
2009-04-17 20:29:52 +00:00
$ utildata - > { nodeonmynetdata } - > { nets } = \ @ nets ;
}
2008-02-04 20:02:15 +00:00
foreach ( @ nets )
{
my @ elems = split /\s+/ ;
unless ( $ elems [ 1 ] =~ /dev/ )
{
next ;
}
( my $ curnet , my $ maskbits ) = split /\// , $ elems [ 0 ] ;
my $ curmask = 2 ** $ maskbits - 1 << ( 32 - $ maskbits ) ;
my $ curn = unpack ( "N" , inet_aton ( $ curnet ) ) ;
if ( ( $ noden & $ curmask ) == $ curn )
{
return 1 ;
}
}
return 0 ;
}
2010-02-04 13:25:45 +00:00
#-------------------------------------------------------------------------------
2010-02-04 08:29:06 +00:00
= head3 getNodeIPaddress
2011-11-04 17:55:35 +00:00
Arguments:
Node name only one at a time
Returns: ip address ( s )
Globals:
none
Error:
none
Example: my $ c1 = xCAT::Utils:: getNodeIPaddress ( $ nodetocheck ) ;
2010-02-04 08:29:06 +00:00
= cut
#-------------------------------------------------------------------------------
sub getNodeIPaddress
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2010-02-04 08:29:06 +00:00
my $ nodetocheck = shift ;
2010-12-29 02:20:29 +00:00
my $ port = shift ;
2010-02-04 08:29:06 +00:00
my $ nodeip ;
2010-05-12 01:45:48 +00:00
$ nodeip = xCAT::NetworkUtils - > getipaddr ( $ nodetocheck ) ;
if ( ! $ nodeip )
{
2010-02-04 08:29:06 +00:00
my $ hoststab = xCAT::Table - > new ( 'hosts' ) ;
my $ ent = $ hoststab - > getNodeAttribs ( $ nodetocheck , [ 'ip' ] ) ;
if ( $ ent - > { 'ip' } ) {
$ nodeip = $ ent - > { 'ip' } ;
}
}
2011-12-15 07:28:02 +00:00
if ( $ nodeip ) {
return $ nodeip ;
} else {
return undef ;
}
}
#-------------------------------------------------------------------------------
2010-02-04 08:29:06 +00:00
2011-12-15 07:28:02 +00:00
= head3 getIPaddress - Used by DFM related functions to support service vlan redundancy .
2011-06-07 09:52:45 +00:00
2011-12-15 07:28:02 +00:00
Arguments:
Node name only one at a time
Returns: ip address ( s )
Globals:
none
Error:
none
Example: my $ c1 = xCAT::Utils:: getIPaddress ( $ nodetocheck ) ;
= cut
#-------------------------------------------------------------------------------
sub getIPaddress
{
require xCAT::Table ;
my $ nodetocheck = shift ;
my $ port = shift ;
2012-03-06 06:38:47 +00:00
if ( isIpaddr ( $ nodetocheck ) ) {
return $ nodetocheck ;
}
2011-12-15 07:28:02 +00:00
my $ side = "[A|B]" ;
if ( ! defined ( $ port ) ) {
$ port = "[0|1]" ;
}
# only need to parse IP addresses for Frame/CEC/BPA/FSP
my $ type = xCAT::DBobjUtils - > getnodetype ( $ nodetocheck ) ;
if ( $ type ) {
my @ children ;
my % node_side_pairs = ( ) ;
my $ children_num = 0 ;
my $ parent ;
my $ ppctab = xCAT::Table - > new ( 'ppc' ) ;
my $ vpdtab = xCAT::Table - > new ( 'vpd' ) ;
2012-01-16 06:40:55 +00:00
my $ mptab = xCAT::Table - > new ( 'mp' ) ;
2011-12-15 07:28:02 +00:00
if ( $ type eq "bpa" or $ type eq "fsp" ) {
my $ tmp_p = $ ppctab - > getNodeAttribs ( $ nodetocheck , [ 'parent' ] ) ;
if ( $ tmp_p and $ tmp_p - > { parent } ) {
$ parent = $ tmp_p - > { parent } ;
} else {
return undef ;
}
2012-01-16 06:40:55 +00:00
if ( $ mptab ) {
my $ tmp_p_type = $ mptab - > getNodeAttribs ( $ parent , [ 'nodetype' ] ) ;
if ( $ tmp_p_type && $ tmp_p_type - > { nodetype } =~ /^(cmm|mp)$/ ) {
return getNodeIPaddress ( $ nodetocheck ) ;
} else {
my $ p_type = xCAT::DBobjUtils - > getnodetype ( $ parent ) ;
if ( $ p_type && $ p_type =~ /^(cmm|mp)$/ ) {
return getNodeIPaddress ( $ nodetocheck ) ;
}
}
}
2011-12-15 07:28:02 +00:00
my $ tmp_s = $ vpdtab - > getNodeAttribs ( $ nodetocheck , [ 'side' ] ) ;
if ( $ tmp_s - > { side } and ( $ tmp_s - > { side } =~ /(A|B)-\d/i ) ) {
$ side = $ 1 ; # get side for the fsp, in order to get its brothers
} else {
return - 3 ;
}
} elsif ( $ type eq "frame" or $ type eq "cec" ) {
$ parent = $ nodetocheck ;
} else {
return undef ;
}
my @ ps = $ ppctab - > getAllNodeAttribs ( [ 'node' , 'parent' , 'nodetype' ] ) ;
my $ tmp_parent ;
my $ tmp_node ;
my $ tmp_type ;
#search for $nodetocheck's children or brothers
for my $ entry ( @ ps ) {
$ tmp_parent = $ entry - > { parent } ;
$ tmp_node = $ entry - > { node } ;
$ tmp_type = $ entry - > { nodetype } ;
if ( $ tmp_parent and ( $ tmp_parent eq $ parent ) ) {
if ( ! defined ( $ tmp_type ) ) {
$ tmp_type = xCAT::DBobjUtils - > getnodetype ( $ tmp_node ) ;
}
if ( $ tmp_type and ( $ tmp_type eq 'fsp' or $ tmp_type eq 'bpa' ) ) {
push @ children , $ tmp_node ;
2011-06-07 09:52:45 +00:00
}
2011-12-15 07:28:02 +00:00
}
}
foreach my $ tmp_n ( @ children ) {
my $ ent = $ vpdtab - > getNodeAttribs ( $ tmp_n , [ 'side' ] ) ;
if ( $ ent - > { side } and $ ent - > { side } =~ /^$side-$port$/i ) {
my $ tmp_s = $ ent - > { side } ;
$ tmp_s =~ s/a/A/ ;
$ tmp_s =~ s/b/B/ ;
if ( isIpaddr ( $ tmp_n ) ) {
$ node_side_pairs { $ tmp_s } = $ tmp_n ;
$ children_num + + ;
} else {
my $ tmpip = xCAT::NetworkUtils - > getipaddr ( $ tmp_n ) ;
if ( ! $ tmpip ) {
my $ hoststab = xCAT::Table - > new ( 'hosts' ) ;
my $ tmp = $ hoststab - > getNodeAttribs ( $ tmp_n , [ 'ip' ] ) ;
if ( $ tmp - > { ip } ) {
$ tmpip = $ tmp - > { ip } ;
2011-04-02 07:29:50 +00:00
}
2011-06-07 09:52:45 +00:00
}
2011-12-15 07:28:02 +00:00
if ( $ tmpip ) {
$ node_side_pairs { $ tmp_s } = $ tmpip ;
$ children_num + + ;
2011-06-07 09:52:45 +00:00
}
2011-12-15 07:28:02 +00:00
} # end of parse IP address for a fsp/bpa
} # end of parse a child's side
} #end of loop for children
if ( $ children_num == 0 ) {
return undef ; #no children or brothers for this node.
}
my @ keys = qw( A-0 A-1 B-0 B-1 ) ;
my $ out_strings = undef ;
foreach my $ tmp ( @ keys ) {
if ( ! $ node_side_pairs { $ tmp } ) {
$ node_side_pairs { $ tmp } = '' ;
2010-12-07 08:11:14 +00:00
}
}
2011-01-13 10:42:26 +00:00
2011-12-15 07:28:02 +00:00
$ out_strings = $ node_side_pairs { "A-0" } . ',' . $ node_side_pairs { "A-1" } . ',' . $ node_side_pairs { "B-0" } . ',' . $ node_side_pairs { "B-1" } ;
return $ out_strings ;
2010-02-04 08:29:06 +00:00
} else {
return undef ;
}
}
2011-12-15 07:28:02 +00:00
2011-01-13 10:42:26 +00:00
2008-02-04 20:02:15 +00:00
#-------------------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3 thishostisnot
2008-02-18 15:10:31 +00:00
returns 0 if host is not the same
2008-02-04 20:02:15 +00:00
Arguments:
2008-04-05 14:53:35 +00:00
hostname
2008-02-04 20:02:15 +00:00
Returns:
Globals:
none
Error:
none
Example:
Comments:
none
= cut
#-------------------------------------------------------------------------------
sub thishostisnot
{
my $ comparison = shift ;
if ( scalar ( @ _ ) )
{
$ comparison = shift ;
}
2009-07-07 02:07:30 +00:00
my @ ips ;
if ( $^O eq 'aix' )
{
@ ips = split /\n/ , `/usr/sbin/ifconfig -a` ;
}
else
{
@ ips = split /\n/ , `/sbin/ip addr` ;
}
2010-05-07 10:30:16 +00:00
my $ comp = xCAT::NetworkUtils - > getipaddr ( $ comparison ) ;
2009-02-04 17:18:44 +00:00
if ( $ comp )
{
foreach ( @ ips )
2008-02-04 20:02:15 +00:00
{
2010-05-07 10:28:30 +00:00
if ( /^\s*inet.?\s+/ )
2008-02-04 20:02:15 +00:00
{
2009-02-04 17:18:44 +00:00
my @ ents = split ( /\s+/ ) ;
my $ ip = $ ents [ 2 ] ;
$ ip =~ s/\/.*// ;
2010-05-07 10:28:30 +00:00
$ ip =~ s/\%.*// ;
if ( $ ip eq $ comp )
2009-02-04 17:18:44 +00:00
{
return 0 ;
}
}
2008-02-04 20:02:15 +00:00
}
}
return 1 ;
}
#-------------------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3 GetMasterNodeName
2008-02-04 20:02:15 +00:00
Reads the database for the Master node name for the input node
Arguments:
Node
Returns:
2008-04-05 14:53:35 +00:00
MasterHostName
2008-02-04 20:02:15 +00:00
Globals:
none
Error:
none
Example:
2008-04-05 14:53:35 +00:00
$ master = ( xCAT::Utils - > GetMasterNodeName ( $ node ) )
2008-02-04 20:02:15 +00:00
Comments:
none
= cut
#-------------------------------------------------------------------------------
sub GetMasterNodeName
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2008-02-04 20:02:15 +00:00
my ( $ class , $ node ) = @ _ ;
my $ master ;
my $ noderestab = xCAT::Table - > new ( 'noderes' ) ;
my $ typetab = xCAT::Table - > new ( 'nodetype' ) ;
unless ( $ noderestab and $ typetab )
{
xCAT::MsgUtils - > message ( 'S' ,
"Unable to open noderes or nodetype table.\n" ) ;
return 1 ;
}
my $ sitetab = xCAT::Table - > new ( 'site' ) ;
( my $ et ) = $ sitetab - > getAttribs ( { key = > "master" } , 'value' ) ;
if ( $ et and $ et - > { value } )
{
$ master = $ et - > { value } ;
}
$ et = $ noderestab - > getNodeAttribs ( $ node , [ 'xcatmaster' ] ) ;
if ( $ et and $ et - > { 'xcatmaster' } )
{
$ master = $ et - > { 'xcatmaster' } ;
}
unless ( $ master )
{
xCAT::MsgUtils - > message ( 'S' , "Unable to identify master for $node.\n" ) ;
2008-04-22 13:24:38 +00:00
$ sitetab - > close ;
$ noderestab - > close ;
$ typetab - > close ;
2008-02-04 20:02:15 +00:00
return 1 ;
}
2008-04-22 13:24:38 +00:00
$ sitetab - > close ;
$ noderestab - > close ;
$ typetab - > close ;
2008-02-04 20:02:15 +00:00
return $ master ;
2008-02-02 19:39:33 +00:00
}
2008-02-04 20:02:15 +00:00
#-------------------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3 GetNodeOSARCH
2008-02-04 20:02:15 +00:00
Reads the database for the OS and Arch of the input Node
Arguments:
Node
Returns:
$ et - > { 'os' }
$ et - > { 'arch' }
Globals:
none
Error:
none
Example:
2008-04-05 14:53:35 +00:00
$ master = ( xCAT::Utils - > GetNodeOSARCH ( $ node ) )
2008-02-04 20:02:15 +00:00
Comments:
none
= cut
#-------------------------------------------------------------------------------
sub GetNodeOSARCH
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2008-02-04 20:02:15 +00:00
my ( $ class , $ node ) = @ _ ;
my $ noderestab = xCAT::Table - > new ( 'noderes' ) ;
my $ typetab = xCAT::Table - > new ( 'nodetype' ) ;
unless ( $ noderestab and $ typetab )
{
xCAT::MsgUtils - > message ( 'S' ,
"Unable to open noderes or nodetype table.\n" ) ;
return 1 ;
2008-02-02 19:39:33 +00:00
}
2008-02-04 20:02:15 +00:00
my $ et = $ typetab - > getNodeAttribs ( $ node , [ 'os' , 'arch' ] ) ;
unless ( $ et and $ et - > { 'os' } and $ et - > { 'arch' } )
{
xCAT::MsgUtils - > message ( 'S' ,
"No os/arch setting in nodetype table for $node.\n" ) ;
return 1 ;
}
return $ et ;
2008-02-18 15:10:31 +00:00
}
#-----------------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3 exportDBConfig
2008-04-22 13:24:38 +00:00
Reads the /etc/xc at / cfgloc file for the DB configuration and exports it
2008-02-18 15:10:31 +00:00
in $ XCATCFG
= cut
#-----------------------------------------------------------------------------
sub exportDBConfig
{
# export the xcat database configuration
2008-04-22 13:24:38 +00:00
my $ configfile = "/etc/xcat/cfgloc" ;
2008-02-18 15:10:31 +00:00
if ( ! ( $ ENV { 'XCATCFG' } ) )
{
if ( - e ( $ configfile ) )
{
open ( CFGFILE , "<$configfile" )
or xCAT::MsgUtils - > message ( 'S' ,
"Cannot open $configfile for DB access. \n" ) ;
foreach my $ line ( <CFGFILE> )
{
2008-04-22 13:24:38 +00:00
chop $ line ;
2008-07-18 12:30:22 +00:00
my $ exp . = $ line ;
2008-04-22 13:24:38 +00:00
$ ENV { 'XCATCFG' } = $ exp ;
close CFGFILE ;
last ;
2008-02-18 15:10:31 +00:00
}
}
}
return 0 ;
}
#-----------------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3 readSNInfo
2008-02-18 15:10:31 +00:00
Read resource , NFS server , Master node , OS an ARCH from the database
for the service node
Input: service nodename
Output: Masternode , OS and ARCH
= cut
#-----------------------------------------------------------------------------
sub readSNInfo
{
my ( $ class , $ nodename ) = @ _ ;
my $ rc = 0 ;
my $ et ;
my $ masternode ;
my $ os ;
my $ arch ;
$ rc = xCAT::Utils - > exportDBConfig ( ) ;
if ( $ rc == 0 )
{
if ( $ nodename )
{
$ masternode = xCAT::Utils - > GetMasterNodeName ( $ nodename ) ;
if ( ! ( $ masternode ) )
{
xCAT::MsgUtils - > message ( 'S' ,
2008-02-25 13:03:17 +00:00
"Could not get Master for node $nodename\n" ) ;
2008-02-18 15:10:31 +00:00
return 1 ;
}
$ et = xCAT::Utils - > GetNodeOSARCH ( $ nodename ) ;
2009-02-04 17:18:44 +00:00
if ( $ et == 1 )
{
2008-11-21 12:44:39 +00:00
xCAT::MsgUtils - > message ( 'S' ,
"Could not get OS/ARCH for node $nodename\n" ) ;
return 1 ;
2009-02-04 17:18:44 +00:00
}
2008-02-18 15:10:31 +00:00
if ( ! ( $ et - > { 'os' } || $ et - > { 'arch' } ) )
{
xCAT::MsgUtils - > message ( 'S' ,
2008-02-25 13:03:17 +00:00
"Could not get OS/ARCH for node $nodename\n" ) ;
2008-02-18 15:10:31 +00:00
return 1 ;
}
}
$ et - > { 'master' } = $ masternode ;
return $ et ;
}
return $ rc ;
}
#-----------------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3 isServiceReq
2008-02-18 15:10:31 +00:00
2008-02-28 19:46:39 +00:00
2008-05-06 15:41:58 +00:00
Checks the service node table in the database to see
2009-03-02 14:27:10 +00:00
if input Service should be setup on the
2008-02-18 15:10:31 +00:00
input service node
2008-04-05 14:53:35 +00:00
2009-03-02 14:27:10 +00:00
Input:servicenodename , ipaddres ( s ) and hostnames of service node
2008-04-05 14:53:35 +00:00
Output:
2009-03-02 14:27:10 +00:00
array of services to setup for this service node
2008-02-18 15:10:31 +00:00
Globals:
2009-03-02 14:27:10 +00:00
$ ::RUNCMD_RC = 0 ; good
$ ::RUNCMD_RC = 1 ; error
2008-02-18 15:10:31 +00:00
Error:
none
Example:
2009-03-02 14:27:10 +00:00
@ servicestosetup = xCAT::Utils - > isServiceReq ( $ servicenodename , @ serviceip ) { blah ; }
2008-02-18 15:10:31 +00:00
= cut
#-----------------------------------------------------------------------------
sub isServiceReq
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2009-03-02 14:27:10 +00:00
my ( $ class , $ servicenodename , $ serviceip ) = @ _ ;
# list of all services from service node table
# note this must be updated if more services added
my @ services = (
"nameserver" , "dhcpserver" , "tftpserver" , "nfsserver" ,
"conserver" , "monserver" , "ldapserver" , "ntpserver" ,
2010-05-18 20:38:50 +00:00
"ftpserver" , "ipforward"
2009-03-02 14:27:10 +00:00
) ;
2008-04-22 13:24:38 +00:00
my @ ips = @$ serviceip ; # list of service node ip addresses and names
2008-03-26 18:20:05 +00:00
my $ rc = 0 ;
2008-03-06 18:42:32 +00:00
$ rc = xCAT::Utils - > exportDBConfig ( ) ; # export DB env
if ( $ rc != 0 )
2008-02-28 19:46:39 +00:00
{
2008-03-06 18:42:32 +00:00
xCAT::MsgUtils - > message ( 'S' , "Unable export DB environment.\n" ) ;
2009-03-02 14:27:10 +00:00
$ ::RUNCMD_RC = 1 ;
return ;
2008-03-06 18:42:32 +00:00
2008-02-29 14:06:01 +00:00
}
2008-02-28 19:46:39 +00:00
2008-05-06 15:41:58 +00:00
# get handle to servicenode table
my $ servicenodetab = xCAT::Table - > new ( 'servicenode' ) ;
unless ( $ servicenodetab )
2008-02-28 19:46:39 +00:00
{
2008-05-06 15:41:58 +00:00
xCAT::MsgUtils - > message ( 'S' , "Unable to open servicenode table.\n" ) ;
2009-03-02 14:27:10 +00:00
$ ::RUNCMD_RC = 1 ;
return ; # do not setup anything
2008-02-28 19:46:39 +00:00
}
2008-05-07 17:35:14 +00:00
2009-03-02 14:27:10 +00:00
my @ process_service_list = ( ) ;
# read all the nodes from the table, for each service
foreach my $ service ( @ services )
2008-02-28 19:46:39 +00:00
{
2009-03-02 14:27:10 +00:00
my @ snodelist = $ servicenodetab - > getAllNodeAttribs ( [ $ service ] ) ;
2008-05-07 17:35:14 +00:00
2009-03-02 14:27:10 +00:00
foreach $ serviceip ( @ ips ) # check the table for this servicenode
2008-02-18 19:00:29 +00:00
{
2009-03-02 14:27:10 +00:00
foreach my $ node ( @ snodelist )
{
if ( $ serviceip eq $ node - > { 'node' } )
{ # match table entry
if ( $ node - > { $ service } )
{ # returns service, only if set
my $ value = $ node - > { $ service } ;
$ value =~ tr /a-z/ A - Z / ; # convert to upper
# value 1 or yes then we setup the service
if ( ( $ value eq "1" ) || ( $ value eq "YES" ) )
{
push @ process_service_list ,
$ service ; # found service to setup
}
2008-05-13 12:36:13 +00:00
}
2008-05-07 17:35:14 +00:00
}
2008-02-18 19:00:29 +00:00
}
2008-02-26 19:57:10 +00:00
}
2008-02-18 15:10:31 +00:00
}
2009-03-02 14:27:10 +00:00
$ servicenodetab - > close ;
2008-02-18 15:10:31 +00:00
2009-03-02 14:27:10 +00:00
$ ::RUNCMD_RC = 0 ;
return @ process_service_list ;
2008-05-06 15:41:58 +00:00
2008-02-02 19:39:33 +00:00
}
2008-02-18 19:00:29 +00:00
2008-02-21 18:21:41 +00:00
#-----------------------------------------------------------------------------
2008-03-06 18:42:32 +00:00
= head3 determinehostname and ip address ( s )
2008-04-05 14:53:35 +00:00
2008-03-06 18:42:32 +00:00
Used on the service node to figure out what hostname and ip address ( s )
2008-04-22 13:24:38 +00:00
are valid names and addresses
2008-04-05 14:53:35 +00:00
Input: None
Output: ipaddress ( s ) , nodename
2008-02-21 18:21:41 +00:00
= cut
#-----------------------------------------------------------------------------
sub determinehostname
{
my $ hostname ;
my $ hostnamecmd = "/bin/hostname" ;
2008-03-06 18:42:32 +00:00
my @ thostname = xCAT::Utils - > runcmd ( $ hostnamecmd , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
2008-02-21 18:21:41 +00:00
{ # could not get hostname
2008-03-06 18:42:32 +00:00
xCAT::MsgUtils - > message ( "S" ,
"Error $::RUNCMD_RC from $hostnamecmd command\n" ) ;
exit $ ::RUNCMD_RC ;
2008-02-21 18:21:41 +00:00
}
$ hostname = $ thostname [ 0 ] ;
2008-03-06 18:42:32 +00:00
2009-07-29 17:43:04 +00:00
#get all potentially valid abbreviations, and pick the one that is ok
#by 'noderange'
my @ hostnamecandidates ;
my $ nodename ;
while ( $ hostname =~ /\./ ) {
push @ hostnamecandidates , $ hostname ;
$ hostname =~ s/\.[^\.]*// ;
}
push @ hostnamecandidates , $ hostname ;
my $ checkhostnames = join ( ',' , @ hostnamecandidates ) ;
my @ validnodenames = xCAT::NodeRange:: noderange ( $ checkhostnames ) ;
unless ( scalar @ validnodenames ) { #If the node in question is not in table, take output literrally.
push @ validnodenames , $ hostnamecandidates [ 0 ] ;
}
#now, noderange doesn't guarantee the order, so we search the preference order, most to least specific.
2010-04-07 10:33:24 +00:00
foreach my $ host ( @ hostnamecandidates ) {
if ( grep /^$host$/ , @ validnodenames ) {
$ nodename = $ host ;
2009-07-29 17:43:04 +00:00
last ;
}
}
2008-03-06 18:42:32 +00:00
my @ ips = xCAT::Utils - > gethost_ips ;
2009-07-29 17:43:04 +00:00
my @ hostinfo = ( @ ips , $ nodename ) ;
2008-03-06 18:42:32 +00:00
2008-02-21 18:21:41 +00:00
return @ hostinfo ;
}
2008-02-25 13:03:17 +00:00
#-----------------------------------------------------------------------------
= head3 update_xCATSN
Will add the input service string to /etc/x CATSN to indicate that
the service has been setup by the service node
2008-04-05 14:53:35 +00:00
Input: service ( e . g . tftp , nfs , etc )
2008-02-25 13:03:17 +00:00
Output: 0 = added , 1 = already there
= cut
#-----------------------------------------------------------------------------
sub update_xCATSN
{
my ( $ class , $ service ) = @ _ ;
my $ file = "/etc/xCATSN" ;
my $ rc = 0 ;
my $ cmd = " grep $service $file" ;
xCAT::Utils - > runcmd ( $ cmd , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 )
{ # need to add
`echo $service >> /etc/xCATSN` ;
}
else
{
$ rc = 1 ;
}
return $ rc ;
}
2008-03-06 18:42:32 +00:00
#-----------------------------------------------------------------------------
2009-03-02 14:27:10 +00:00
= head3 gethost_ips ( AIX and Linux )
2008-04-05 14:53:35 +00:00
Will use ifconfig to determine all possible ip addresses for the
2008-04-22 13:24:38 +00:00
host it is running on and then gethostbyaddr to get all possible hostnames
2008-03-06 18:42:32 +00:00
2008-04-05 14:53:35 +00:00
input:
2008-04-22 13:24:38 +00:00
output: array of ipaddress ( s ) and hostnames
2008-03-06 18:42:32 +00:00
example: @ ips = xCAT:: gethost_ips ( ) ;
= cut
#-----------------------------------------------------------------------------
sub gethost_ips
{
my ( $ class ) = @ _ ;
my $ cmd ;
my @ ipaddress ;
$ cmd = "ifconfig" . " -a" ;
2010-05-12 02:39:41 +00:00
$ cmd = $ cmd . "| grep \"inet\"" ;
2008-03-06 18:42:32 +00:00
my @ result = xCAT::Utils - > runcmd ( $ cmd , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
xCAT::MsgUtils - > message ( "S" , "Error from $cmd\n" ) ;
exit $ ::RUNCMD_RC ;
}
foreach my $ addr ( @ result )
{
2009-03-02 14:27:10 +00:00
my @ ip ;
if ( xCAT::Utils - > isLinux ( ) )
{
2010-05-12 02:30:25 +00:00
if ( $ addr =~ /inet6/ )
{
#TODO, Linux ipv6
}
else
{
my ( $ inet , $ addr1 , $ Bcast , $ Mask ) = split ( " " , $ addr ) ;
@ ip = split ( ":" , $ addr1 ) ;
push @ ipaddress , $ ip [ 1 ] ;
}
2009-03-02 14:27:10 +00:00
}
else
{ #AIX
2010-05-12 02:30:25 +00:00
if ( $ addr =~ /inet6/ )
{
$ addr =~ /\s*inet6\s+([\da-fA-F:]+).*\/(\d+)/ ;
my $ v6ip = $ 1 ;
my $ v6mask = $ 2 ;
if ( $ v6ip )
{
push @ ipaddress , $ v6ip ;
}
}
else
{
my ( $ inet , $ addr1 , $ netmask , $ mask1 , $ Bcast , $ bcastaddr ) =
split ( " " , $ addr ) ;
push @ ipaddress , $ addr1 ;
}
2009-03-02 14:27:10 +00:00
}
2008-03-06 18:42:32 +00:00
}
2008-04-22 13:24:38 +00:00
my @ names = @ ipaddress ;
foreach my $ ipaddr ( @ names )
{
2010-05-12 02:30:25 +00:00
my $ hostname = xCAT::NetworkUtils - > gethostname ( $ ipaddr ) ;
2008-04-22 13:24:38 +00:00
if ( $ hostname )
{
my @ shorthost = split ( /\./ , $ hostname ) ;
push @ ipaddress , $ shorthost [ 0 ] ;
}
}
2008-03-06 18:42:32 +00:00
return @ ipaddress ;
}
2008-03-26 18:20:05 +00:00
2008-03-12 19:16:44 +00:00
#-----------------------------------------------------------------------------
= head3 create_postscripts_tar
2008-04-05 14:53:35 +00:00
2008-03-12 19:16:44 +00:00
This routine will tar and compress the /install/ postscripts directory
and place in /install/ autoinst / xcat_postscripts . Z
2008-04-05 14:53:35 +00:00
input: none
output:
2008-03-12 19:16:44 +00:00
example: $ rc = xCAT:: create_postscripts_tar ( ) ;
= cut
#-----------------------------------------------------------------------------
2008-03-26 18:20:05 +00:00
sub create_postscripts_tar
2008-03-12 19:16:44 +00:00
{
my ( $ class ) = @ _ ;
2010-02-24 06:41:20 +00:00
my $ installdir = getInstallDir ( ) ;
2008-03-12 19:16:44 +00:00
my $ cmd ;
2010-02-24 06:41:20 +00:00
if ( ! ( - e "$installdir/autoinst" ) )
2008-03-26 18:20:05 +00:00
{
2010-02-24 06:41:20 +00:00
mkdir ( "$installdir/autoinst" ) ;
2008-03-19 21:09:38 +00:00
}
2008-04-22 13:24:38 +00:00
$ cmd =
2010-02-24 06:41:20 +00:00
"cd $installdir/postscripts; tar -cf $installdir/autoinst/xcatpost.tar * .ssh/* _xcat/*; gzip -f $installdir/autoinst/xcatpost.tar" ;
2008-03-12 19:16:44 +00:00
my @ result = xCAT::Utils - > runcmd ( $ cmd , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
xCAT::MsgUtils - > message ( "S" , "Error from $cmd\n" ) ;
2008-03-26 18:20:05 +00:00
return $ ::RUNCMD_RC ;
2008-03-12 19:16:44 +00:00
}
2008-03-06 18:42:32 +00:00
2008-05-06 17:22:15 +00:00
# for AIX add an entry to the /etc/tftpaccess.ctrl file so
# we can tftp the tar file from the node
if ( xCAT::Utils - > isAIX ( ) )
{
my $ tftpctlfile = "/etc/tftpaccess.ctl" ;
2010-02-24 06:41:20 +00:00
my $ entry = "allow:$installdir/autoinst/xcatpost.tar.gz" ;
2008-05-03 13:01:21 +00:00
2008-05-06 17:22:15 +00:00
# see if there is already an entry
my $ cmd = "cat $tftpctlfile | grep xcatpost" ;
my @ result = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
2008-05-03 13:01:21 +00:00
2008-05-06 17:22:15 +00:00
# not found so add it
unless ( open ( TFTPFILE , ">>$tftpctlfile" ) )
{
xCAT::MsgUtils - > message ( "S" , "Could not open $tftpctlfile.\n" ) ;
return $ ::RUNCMD_RC ;
}
2008-05-03 13:01:21 +00:00
2008-05-06 17:22:15 +00:00
print TFTPFILE $ entry ;
2008-05-03 13:01:21 +00:00
2008-05-06 17:22:15 +00:00
close ( TFTPFILE ) ;
}
}
2008-05-03 13:01:21 +00:00
return 0 ;
2008-03-12 19:16:44 +00:00
}
2008-03-26 18:20:05 +00:00
#-----------------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3 get_site_Master
2008-03-26 18:20:05 +00:00
Reads the site table for the Master attribute and returns it .
input: none
output : value of site . Master attribute , blank is an error
example: $ Master = xCAT:: get_site_Master ( ) ;
= cut
#-----------------------------------------------------------------------------
sub get_site_Master
{
2011-06-23 12:54:41 +00:00
if ( $ ::XCATSITEVALS { master } ) {
return $ ::XCATSITEVALS { master } ;
2011-06-22 17:29:43 +00:00
}
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2008-03-26 18:20:05 +00:00
my $ Master ;
my $ sitetab = xCAT::Table - > new ( 'site' ) ;
( my $ et ) = $ sitetab - > getAttribs ( { key = > "master" } , 'value' ) ;
if ( $ et and $ et - > { value } )
{
$ Master = $ et - > { value } ;
}
else
{
2011-01-12 13:10:59 +00:00
# this msg can be missleading
# xCAT::MsgUtils->message('E',
2011-01-12 13:59:53 +00:00
# "Unable to read site table for Master attribute.\n");
2008-03-26 18:20:05 +00:00
}
return $ Master ;
}
#-----------------------------------------------------------------------------
2008-04-05 14:53:35 +00:00
= head3 get_ServiceNode
2008-03-26 18:20:05 +00:00
Will get the Service node ( name or ipaddress ) as known by the Management
2011-09-29 13:32:05 +00:00
Node or Node for the input nodename or ipadress of the node
which can be a Service Node .
If the input node is a Service Node then it ' s Service node
is always the Management Node .
2008-03-26 18:20:05 +00:00
2008-04-15 14:37:26 +00:00
input: list of nodenames and / or node ipaddresses ( array ref )
2008-04-05 14:53:35 +00:00
service name
2008-03-31 15:52:36 +00:00
"MN" or "Node" determines if you want the Service node as known
by the Management Node or by the node .
2008-03-26 18:20:05 +00:00
recognized service names: xcat , tftpserver ,
nfsserver , conserver , monserver
service "xcat" is used by command like xdsh that need to know the
2008-04-05 14:53:35 +00:00
service node that will process the command but are not tied to a
2008-03-26 18:20:05 +00:00
specific service like tftp
Todo: Handle dhcpserver and nameserver from the networks table
2008-04-24 17:28:35 +00:00
output: A hash ref of arrays , the key is the service node pointing to
2008-04-05 14:53:35 +00:00
an array of nodes that are serviced by that service node
2008-03-26 18:20:05 +00:00
Globals:
2008-04-05 14:53:35 +00:00
$ ::ERROR_RC
2008-03-26 18:20:05 +00:00
Error:
2008-04-05 14:53:35 +00:00
$ ::ERROR_RC = 0 no error $ ::ERROR_RC = 1 error
2008-03-26 18:20:05 +00:00
2008-04-15 14:37:26 +00:00
example: $ sn = xCAT::Utils - > get_ServiceNode ( \ @ nodes , $ service , "MN" ) ;
2009-03-03 19:39:17 +00:00
$ sn = xCAT::Utils - > get_ServiceNode ( \ @ nodes , $ service , "Node" ) ;
2011-10-19 10:24:34 +00:00
Note: this rountine is important to hierarchical support in xCAT
and used in many places . Any changes to the logic should be
reviewed by xCAT architecture
2008-03-26 18:20:05 +00:00
= cut
#-----------------------------------------------------------------------------
2008-03-31 15:19:42 +00:00
sub get_ServiceNode
2008-03-26 18:20:05 +00:00
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2011-10-19 05:27:07 +00:00
my ( $ class , $ node , $ service , $ request ) = @ _ ;
2008-03-26 18:20:05 +00:00
my @ node_list = @$ node ;
my $ cmd ;
my % snhash ;
2009-03-03 19:39:17 +00:00
my $ nodehash ;
2008-03-26 18:20:05 +00:00
my $ sn ;
my $ nodehmtab ;
my $ noderestab ;
my $ snattribute ;
2011-09-29 13:32:05 +00:00
my $ oshash ;
my $ nodetab ;
2008-03-26 18:20:05 +00:00
$ ::ERROR_RC = 0 ;
2008-03-31 15:52:36 +00:00
# determine if the request is for the service node as known by the MN
2008-03-27 12:35:01 +00:00
# or the node
2008-03-26 18:20:05 +00:00
2008-03-31 15:52:36 +00:00
if ( $ request eq "MN" )
2008-03-27 12:35:01 +00:00
{
2011-10-19 05:27:07 +00:00
$ snattribute = "servicenode" ;
2011-10-14 05:43:26 +00:00
2008-03-26 18:20:05 +00:00
}
2008-03-27 12:35:01 +00:00
else # Node
{
2008-03-26 18:20:05 +00:00
$ snattribute = "xcatmaster" ;
}
2011-09-29 13:32:05 +00:00
# get site.master this will be the default
my $ master = xCAT::Utils - > get_site_Master ( ) ;
2008-03-26 18:20:05 +00:00
$ noderestab = xCAT::Table - > new ( 'noderes' ) ;
2009-11-25 16:24:08 +00:00
2008-03-26 18:20:05 +00:00
unless ( $ noderestab ) # no noderes table, use default site.master
{
xCAT::MsgUtils - > message ( 'I' ,
"Unable to open noderes table. Using site->Master.\n" ) ;
2009-11-25 16:24:08 +00:00
2008-03-26 18:20:05 +00:00
if ( $ master ) # use site Master value
{
2009-11-25 16:24:08 +00:00
2008-03-26 18:20:05 +00:00
foreach my $ node ( @ node_list )
2009-11-25 16:24:08 +00:00
{
push @ { $ snhash { $ master } } , $ node ;
2008-03-26 18:20:05 +00:00
}
}
else
{
xCAT::MsgUtils - > message ( 'E' , "Unable to read site Master value.\n" ) ;
$ ::ERROR_RC = 1 ;
}
2009-11-25 16:24:08 +00:00
2008-03-26 18:20:05 +00:00
return \ % snhash ;
}
if ( $ service eq "xcat" )
2008-03-27 12:35:01 +00:00
{ # find all service nodes for the nodes in the list
2009-03-03 19:39:17 +00:00
$ nodehash = $ noderestab - > getNodesAttribs ( \ @ node_list , [ $ snattribute ] ) ;
2009-11-25 16:24:08 +00:00
2008-03-26 18:20:05 +00:00
foreach my $ node ( @ node_list )
{
2009-03-03 19:39:17 +00:00
foreach my $ rec ( @ { $ nodehash - > { $ node } } )
{
2011-09-29 13:32:05 +00:00
if ( $ rec and $ rec - > { $ snattribute } ) # use noderes.servicenode
2009-03-03 19:39:17 +00:00
{
my $ key = $ rec - > { $ snattribute } ;
push @ { $ snhash { $ key } } , $ node ;
}
2011-09-29 13:32:05 +00:00
else # use site.master
2009-11-25 16:24:08 +00:00
{
2011-09-29 13:32:05 +00:00
push @ { $ snhash { $ master } } , $ node ;
2009-03-03 19:39:17 +00:00
}
2008-03-26 18:20:05 +00:00
}
}
2009-03-03 19:39:17 +00:00
2008-04-22 13:24:38 +00:00
$ noderestab - > close ;
2008-03-26 18:20:05 +00:00
return \ % snhash ;
}
else
{
if (
( $ service eq "tftpserver" ) # all from noderes table
|| ( $ service eq "nfsserver" ) || ( $ service eq "monserver" )
)
{
2009-03-03 19:39:17 +00:00
$ nodehash =
$ noderestab - > getNodesAttribs ( \ @ node_list ,
[ $ service , $ snattribute ] ) ;
2008-03-26 18:20:05 +00:00
foreach my $ node ( @ node_list )
{
2009-03-03 19:39:17 +00:00
foreach my $ rec ( @ { $ nodehash - > { $ node } } )
2008-03-26 18:20:05 +00:00
{
2009-03-03 19:39:17 +00:00
if ( $ rec and $ rec - > { $ service } )
2008-03-27 12:35:01 +00:00
{
2009-03-03 19:39:17 +00:00
# see if both MN and Node address in attribute
2009-03-09 17:37:21 +00:00
my ( $ msattr , $ nodeattr ) = split ':' , $ rec - > { $ service } ;
2009-03-03 19:39:17 +00:00
my $ key = $ msattr ;
if ( $ request eq "Node" )
2008-03-27 12:35:01 +00:00
{
2009-03-03 19:39:17 +00:00
if ( $ nodeattr ) # override with Node, if it exists
{
$ key = $ nodeattr ;
}
2008-03-27 12:35:01 +00:00
}
2008-03-26 18:20:05 +00:00
push @ { $ snhash { $ key } } , $ node ;
}
else
2009-03-03 19:39:17 +00:00
{
if ( $ rec and $ rec - > { $ snattribute } ) # if it exists
{
my $ key = $ rec - > { $ snattribute } ;
push @ { $ snhash { $ key } } , $ node ;
}
else
{ # use site.master
push @ { $ snhash { $ master } } , $ node ;
}
2008-03-26 18:20:05 +00:00
}
}
}
2009-03-03 19:39:17 +00:00
2008-04-22 13:24:38 +00:00
$ noderestab - > close ;
2008-03-26 18:20:05 +00:00
return \ % snhash ;
}
else
{
if ( $ service eq "conserver" )
{
2009-03-03 19:39:17 +00:00
# read the nodehm table
2008-03-26 18:20:05 +00:00
$ nodehmtab = xCAT::Table - > new ( 'nodehm' ) ;
2009-03-03 19:39:17 +00:00
unless ( $ nodehmtab ) # no nodehm table
2008-03-26 18:20:05 +00:00
{
xCAT::MsgUtils - > message ( 'I' ,
"Unable to open nodehm table.\n" ) ;
2009-03-03 19:39:17 +00:00
# use servicenode
$ nodehash =
$ noderestab - > getNodesAttribs ( \ @ node_list , [ $ snattribute ] ) ;
2008-03-26 18:20:05 +00:00
foreach my $ node ( @ node_list )
{
2009-03-03 19:39:17 +00:00
foreach my $ rec ( @ { $ nodehash - > { $ node } } )
2008-03-26 18:20:05 +00:00
{
2009-03-03 19:39:17 +00:00
if ( $ rec and $ rec - > { $ snattribute } )
{
my $ key = $ rec - > { $ snattribute } ;
push @ { $ snhash { $ key } } , $ node ;
}
else
{ # use site.master
push @ { $ snhash { $ master } } , $ node ;
}
2008-03-26 18:20:05 +00:00
}
}
2009-03-03 19:39:17 +00:00
$ noderestab - > close ;
2008-03-26 18:20:05 +00:00
return \ % snhash ;
}
2008-03-27 12:35:01 +00:00
# can read the nodehm table
2009-03-03 19:39:17 +00:00
$ nodehash =
$ nodehmtab - > getNodesAttribs ( \ @ node_list , [ 'conserver' ] ) ;
2008-03-26 18:20:05 +00:00
foreach my $ node ( @ node_list )
{
2009-03-03 19:39:17 +00:00
foreach my $ rec ( @ { $ nodehash - > { $ node } } )
2008-03-26 18:20:05 +00:00
{
2009-03-03 19:39:17 +00:00
if ( $ rec and $ rec - > { 'conserver' } )
2008-03-27 12:35:01 +00:00
{
2009-03-03 19:39:17 +00:00
# see if both MN and Node address in attribute
2009-03-09 17:37:21 +00:00
my ( $ msattr , $ nodeattr ) = split ':' ,
2009-03-03 19:39:17 +00:00
$ rec - > { 'conserver' } ;
my $ key = $ msattr ;
if ( $ request eq "Node" )
2008-03-27 12:35:01 +00:00
{
2009-03-03 19:39:17 +00:00
if ( $ nodeattr
) # override with Node, if it exists
{
$ key = $ nodeattr ;
}
2008-03-27 12:35:01 +00:00
}
2008-03-26 18:20:05 +00:00
push @ { $ snhash { $ key } } , $ node ;
}
else
2009-03-03 19:39:17 +00:00
{ # use service node for this node
$ sn =
$ noderestab - > getNodeAttribs ( $ node ,
[ $ snattribute ] ) ;
if ( $ sn and $ sn - > { $ snattribute } )
{
my $ key = $ sn - > { $ snattribute } ;
push @ { $ snhash { $ key } } , $ node ;
}
else
{ # no service node use master
push @ { $ snhash { $ master } } , $ node ;
}
2008-03-26 18:20:05 +00:00
}
}
}
2008-04-22 13:24:38 +00:00
$ noderestab - > close ;
$ nodehmtab - > close ;
2008-03-26 18:20:05 +00:00
return \ % snhash ;
}
else
{
xCAT::MsgUtils - > message ( 'E' ,
"Invalid service=$service input.\n" ) ;
$ ::ERROR_RC = 1 ;
}
}
}
return \ % snhash ;
}
2008-04-23 18:14:57 +00:00
#-----------------------------------------------------------------------------
2009-08-05 11:53:05 +00:00
= head3 getSNformattedhash
Will call get_ServiceNode to get the Service node ( name or ipaddress )
as known by the Management
Server or Node for the input nodename or ipadress of the node
It will then format the output into a single servicenode key with values
the list of nodes service by that service node . This routine will
break up pools of service nodes into individual node in the hash unlike
get_ServiceNode which leaves the pool as the key .
input: Same as get_ServiceNode to call get_ServiceNode
list of nodenames and / or node ipaddresses ( array ref )
service name
"MN" or "Node" determines if you want the Service node as known
by the Management Node or by the node .
recognized service names: xcat , tftpserver ,
nfsserver , conserver , monserver
service "xcat" is used by command like xdsh that need to know the
service node that will process the command but are not tied to a
specific service like tftp
output: A hash ref of arrays , the key is a single service node
pointing to
a list of nodes that are serviced by that service node
'rra000-m' = > [ 'blade01' , 'testnode' ]
'sn1' = > [ 'blade01' , 'testnode' ]
'sn2' = > [ 'blade01' ]
'sn3' = > [ 'testnode' ]
Globals:
$ ::ERROR_RC
Error:
$ ::ERROR_RC = 0 no error $ ::ERROR_RC = 1 error
2011-01-07 20:42:31 +00:00
example: $ sn = xCAT::Utils - > getSNformattedhash ( \ @ nodes , $ service , "MN" , $ type ) ;
$ sn = xCAT::Utils - > getSNformattedhash ( \ @ nodes , $ service , "Node" , "primary" ) ;
2009-08-05 11:53:05 +00:00
= cut
#-----------------------------------------------------------------------------
sub getSNformattedhash
{
2011-01-17 12:50:11 +00:00
my ( $ class , $ node , $ service , $ request , $ btype ) = @ _ ;
2009-08-05 11:53:05 +00:00
my @ node_list = @$ node ;
my $ cmd ;
my % newsnhash ;
2011-01-07 20:42:31 +00:00
2011-01-17 12:50:11 +00:00
my $ type = "" ;
if ( $ btype ) {
$ type = $ btype ;
}
2011-01-07 20:42:31 +00:00
# get the values of either the servicenode or xcatmaster attributes
2009-08-05 11:53:05 +00:00
my $ sn = xCAT::Utils - > get_ServiceNode ( \ @ node_list , $ service , $ request ) ;
# get the keys which are the service nodes and break apart any pool lists
# format into individual service node keys pointing to node lists
2011-01-07 20:42:31 +00:00
if ( $ sn )
{
foreach my $ snkey ( keys %$ sn )
{
# split the key if pool of service nodes
push my @ tmpnodes , $ sn - > { $ snkey } ;
my @ nodes ;
for my $ i ( 0 .. $# tmpnodes ) {
for my $ j ( 0 .. $# { $ tmpnodes [ $ i ] } ) {
my $ check = $ tmpnodes [ $ i ] [ $ j ] ;
push @ nodes , $ check ;
}
}
2009-08-05 11:53:05 +00:00
2011-01-07 20:42:31 +00:00
# for SN backup we might only want the primary or backup
my @ servicenodes ;
my ( $ primary , $ backup ) = split /,/ , $ snkey ;
if ( ( $ primary ) && ( $ type eq "primary" ) ) {
push @ servicenodes , $ primary ;
} elsif ( ( $ backup ) && ( $ type eq "backup" ) ) {
push @ servicenodes , $ backup ;
} else {
@ servicenodes = split /,/ , $ snkey ;
}
2009-08-05 11:53:05 +00:00
2011-01-07 20:42:31 +00:00
# now build new hash of individual service nodes
foreach my $ newsnkey ( @ servicenodes ) {
push @ { $ newsnhash { $ newsnkey } } , @ nodes ;
}
}
}
2009-08-05 11:53:05 +00:00
return \ % newsnhash ;
}
#-----------------------------------------------------------------------------
2008-04-23 18:14:57 +00:00
= head3 toIP
IPv4 function to convert hostname to IP address
= cut
#-----------------------------------------------------------------------------
2008-04-22 13:24:38 +00:00
sub toIP
{
2009-02-04 17:18:44 +00:00
2010-06-02 08:01:31 +00:00
if ( ( $ _ [ 0 ] =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/ ) || ( $ _ [ 0 ] =~ /:/ ) )
2008-04-22 13:24:38 +00:00
{
return ( [ 0 , $ _ [ 0 ] ] ) ;
}
2010-06-02 08:01:31 +00:00
my $ ip = xCAT::NetworkUtils - > getipaddr ( $ _ [ 0 ] ) ;
if ( ! $ ip )
2008-04-22 13:24:38 +00:00
{
return ( [ 1 , "Cannot Resolve: $_[0]\n" ] ) ;
}
2010-06-02 08:01:31 +00:00
return ( [ 0 , $ ip ] ) ;
2008-04-22 13:24:38 +00:00
}
2008-04-02 19:39:39 +00:00
2008-04-23 18:14:57 +00:00
#-----------------------------------------------------------------------------
= head3 isSN
Determines if the input node name is a service node
2008-05-06 15:41:58 +00:00
Reads the servicenode table . nodename must be service node name as
known by the Management node .
2008-04-23 18:14:57 +00:00
returns 1 if input host is a service node
Arguments:
hostname
Returns:
1 - is Service Node
0 - is not a Service Node
Globals:
none
Error:
none
Example:
if ( xCAT::Utils - > isSN ( $ nodename ) ) { blah ; }
Comments:
none
= cut
#-----------------------------------------------------------------------------
sub isSN
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2008-04-23 18:14:57 +00:00
my ( $ class , $ node ) = @ _ ;
2008-05-06 15:41:58 +00:00
# reads all nodes from the service node table
my @ servicenodes ;
my $ servicenodetab = xCAT::Table - > new ( 'servicenode' ) ;
unless ( $ servicenodetab ) # no servicenode table
{
xCAT::MsgUtils - > message ( 'I' , "Unable to open servicenode table.\n" ) ;
return 0 ;
}
2008-07-18 12:30:22 +00:00
my @ nodes = $ servicenodetab - > getAllNodeAttribs ( [ 'tftpserver' ] ) ;
2008-05-06 15:41:58 +00:00
$ servicenodetab - > close ;
foreach my $ nodes ( @ nodes )
2008-04-23 18:14:57 +00:00
{
2008-05-06 15:41:58 +00:00
if ( $ node eq $ nodes - > { node } )
2008-04-23 18:14:57 +00:00
{
2008-05-07 17:35:14 +00:00
return 1 ; # match
2008-04-23 18:14:57 +00:00
}
}
2008-05-06 15:41:58 +00:00
2008-04-23 18:14:57 +00:00
return 0 ;
}
2008-04-23 19:11:16 +00:00
#-----------------------------------------------------------------------------
2008-04-24 17:28:35 +00:00
= head3 getAllSN
2008-04-23 19:11:16 +00:00
2008-05-06 15:41:58 +00:00
Returns an array of all service nodes from service node table
2008-04-23 19:11:16 +00:00
Arguments:
none
Returns:
array of Service Nodes or empty array , if none
Globals:
none
Error:
1 - error
Example:
@ allSN = xCAT::Utils - > get_AllSN
Comments:
none
= cut
#-----------------------------------------------------------------------------
2008-04-24 17:28:35 +00:00
sub getAllSN
2008-04-23 19:11:16 +00:00
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2008-05-06 15:41:58 +00:00
# reads all nodes from the service node table
2008-04-23 19:11:16 +00:00
my @ servicenodes ;
2008-05-06 15:41:58 +00:00
my $ servicenodetab = xCAT::Table - > new ( 'servicenode' ) ;
2008-05-07 17:35:14 +00:00
unless ( $ servicenodetab ) # no servicenode table
2008-04-23 19:11:16 +00:00
{
2008-05-07 17:35:14 +00:00
xCAT::MsgUtils - > message ( 'I' , "Unable to open servicenode table.\n" ) ;
$ servicenodetab - > close ;
return @ servicenodes ;
}
my @ nodes = $ servicenodetab - > getAllNodeAttribs ( [ 'tftpserver' ] ) ;
foreach my $ nodes ( @ nodes )
{
push @ servicenodes , $ nodes - > { node } ;
2008-04-23 19:11:16 +00:00
}
2008-05-06 15:41:58 +00:00
$ servicenodetab - > close ;
2008-04-23 19:11:16 +00:00
return @ servicenodes ;
}
2008-04-24 17:28:35 +00:00
#-----------------------------------------------------------------------------
2008-05-06 15:41:58 +00:00
= head3 getSNandNodes
Returns an hash - array of all service nodes and the nodes they service
Arguments:
none
#-----------------------------------------------------------------------------
2008-04-24 17:28:35 +00:00
= head3 getSNandNodes
Returns an hash - array of all service nodes and the nodes they service
Arguments:
none
Returns:
Service Nodes and the nodes they service or empty , if none
Globals:
none
Error:
1 - error
Example:
$ sn = xCAT::Utils - > getSNandNodes ( )
Comments:
none
= cut
#-----------------------------------------------------------------------------
sub getSNandNodes
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2008-04-24 17:28:35 +00:00
# read all the nodes from the nodelist table
# call get_ServiceNode to find which Service Node
# the node belongs to.
my % sn ;
my @ nodes ;
my $ nodelisttab = xCAT::Table - > new ( 'nodelist' ) ;
my $ recs = $ nodelisttab - > getAllEntries ( ) ;
foreach ( @$ recs )
{
push @ nodes , $ _ - > { node } ;
}
$ nodelisttab - > close ;
2008-07-18 12:30:22 +00:00
my $ sn = xCAT::Utils - > get_ServiceNode ( \ @ nodes , "xcat" , "MN" ) ;
2008-04-24 17:28:35 +00:00
return $ sn ;
}
2008-05-06 17:22:15 +00:00
#-----------------------------------------------------------------------------
= head3 getSNList
2008-05-07 17:35:14 +00:00
Reads the servicenode table . Will return all the enabled Service Nodes
2008-05-06 17:22:15 +00:00
that will setup the input Service ( e . g tftpserver , nameserver , etc )
If service is blank , then will return the list of all enabled Service
Nodes .
Arguments:
Servicename ( xcat , tftpserver , dhcpserver , conserver , etc )
Returns:
Array of service node names
Globals:
none
Error:
1 - error
Example:
$ sn = xCAT::Utils - > getSNList ( $ servicename ) { blah ; }
$ sn = xCAT::Utils - > getSNList ( ) { blah ; }
Comments:
none
= cut
#-----------------------------------------------------------------------------
sub getSNList
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2008-05-06 17:22:15 +00:00
my ( $ class , $ service ) = @ _ ;
# reads all nodes from the service node table
my @ servicenodes ;
2009-02-04 17:18:44 +00:00
my $ servicenodetab = xCAT::Table - > new ( 'servicenode' , - create = > 1 ) ;
2008-05-06 17:22:15 +00:00
unless ( $ servicenodetab ) # no servicenode table
{
xCAT::MsgUtils - > message ( 'I' , "Unable to open servicenode table.\n" ) ;
2008-05-20 17:56:53 +00:00
return ( ) ;
2008-05-06 17:22:15 +00:00
}
2008-05-07 17:35:14 +00:00
my @ nodes = $ servicenodetab - > getAllNodeAttribs ( [ $ service ] ) ;
2008-05-06 17:22:15 +00:00
$ servicenodetab - > close ;
foreach my $ node ( @ nodes )
{
2008-05-07 17:35:14 +00:00
if ( $ service eq "" ) # want all the service nodes
2008-05-06 17:22:15 +00:00
{
push @ servicenodes , $ node - > { node } ;
}
else
2008-05-07 17:35:14 +00:00
{ # looking for a particular service
if ( $ node - > { $ service } )
{ # if null then do not add node
my $ value = $ node - > { $ service } ;
$ value =~ tr /a-z/ A - Z / ; # convert to upper
# value 1 or yes or blank then we setup the service
if ( ( $ value == 1 ) || ( $ value eq "YES" ) )
{
push @ servicenodes , $ node - > { node } ;
2008-05-06 17:22:15 +00:00
2008-05-07 17:35:14 +00:00
}
2008-05-06 17:22:15 +00:00
}
}
}
return @ servicenodes ;
}
2008-05-13 12:36:13 +00:00
2008-05-12 19:49:41 +00:00
#-------------------------------------------------------------------------------
2009-04-28 09:10:19 +00:00
= head3 validate_ip
Validate list of IPs
Arguments:
List of IPs
Returns:
1 - Invalid IP address in the list
0 - IP addresses are all valid
Globals:
none
Error:
none
Example:
if ( xCAT::Utils - > validate_ip ( $ IP ) ) { }
Comments:
none
= cut
#-------------------------------------------------------------------------------
sub validate_ip
{
my ( $ class , @ IPs ) = @ _ ;
foreach ( @ IPs ) {
my $ ip = $ _ ;
2010-05-31 08:15:32 +00:00
#TODO need more check for IPv6 address
if ( $ ip =~ /:/ )
{
return ( [ 0 ] ) ;
}
2009-04-28 09:10:19 +00:00
###################################
# Length is 4 for IPv4 addresses
###################################
my ( @ octets ) = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ ;
if ( scalar ( @ octets ) != 4 ) {
return ( [ 1 , "Invalid IP address1: $ip" ] ) ;
}
foreach my $ octet ( @ octets ) {
if ( ( $ octet < 0 ) or ( $ octet > 255 ) ) {
return ( [ 1 , "Invalid IP address2: $ip" ] ) ;
}
}
}
return ( [ 0 ] ) ;
}
#-------------------------------------------------------------------------------
2008-05-12 19:49:41 +00:00
= head3 isMounted
Checks if the input directory is already mounted
Arguments:
directory
Returns:
1 - directory is mounted
0 - directory is not mounted
Globals:
none
Error:
- 1 error
Example:
if ( xCAT::Utils - > isMounted ( $ directory ) ) { blah ; }
2011-04-20 19:31:39 +00:00
Comments:
2008-05-12 19:49:41 +00:00
none
= cut
#-------------------------------------------------------------------------------
sub isMounted
{
my ( $ class , $ directory ) = @ _ ;
2011-04-20 19:20:53 +00:00
my $ cmd ;
my @ output ;
if ( - e $ directory ) { # does the directory exist
if ( xCAT::Utils - > isLinux ( ) ) {
$ cmd = "df -T -P $directory" ;
@ output = xCAT::Utils - > runcmd ( $ cmd , - 1 ) ;
foreach my $ line ( @ output ) {
my ( $ file_sys , $ type , $ blocks , $ used , $ avail , $ per , $ mount_point ) =
split ( ' ' , $ line ) ;
$ type =~ s/\s*//g ; # remove blanks
if ( $ type =~ /^nfs/ )
{
return 1 ;
}
2008-05-12 19:49:41 +00:00
}
2011-04-20 19:20:53 +00:00
} else { #AIX
$ cmd = "/usr/sysv/bin/df -n $directory" ;
@ output = xCAT::Utils - > runcmd ( $ cmd , - 1 ) ;
foreach my $ line ( @ output ) {
my ( $ dir , $ colon , $ type ) =
split ( ' ' , $ line ) ;
$ type =~ s/\s*//g ; # remove blanks
if ( $ type =~ /^nfs/ )
{
return 1 ;
}
}
}
2008-05-12 19:49:41 +00:00
}
return 0 ;
}
2009-02-04 17:18:44 +00:00
2008-06-10 16:39:20 +00:00
#-------------------------------------------------------------------------------
2008-05-06 17:22:15 +00:00
2008-09-15 18:15:42 +00:00
= head3 runxcatd
Stops or starts xcatd
Arguments:
xcatstart - start the daemon , restart if already running
xcatstop - stop the daemon
Returns:
0 = not error , 1 = error
Globals:
none
Error:
Example:
my $ rc = xCAT:: runxcatd ( "xcatstart" ) ; ( starts xcatd )
my $ rc = xCAT:: runxcatd ( "xcatstop" ) ; ( stops xcatd )
= cut
#-------------------------------------------------------------------------------
2009-02-04 17:18:44 +00:00
sub runxcatd
2008-09-15 18:15:42 +00:00
{
2009-02-04 17:18:44 +00:00
my ( $ class , $ cmd ) = @ _ ;
if ( ! ( xCAT::Utils - > isAIX ( ) ) )
{ # only runs on AIX
xCAT::MsgUtils - > message ( "E" ,
"This command should only be run on AIX.\n" ) ;
return 1 ;
}
#
# if xcatd already running
# Get the xcatd processes and stop them
#
my @ xpids = xCAT::Utils - > runcmd ( "ps -ef\|grep \"xcatd\"" , 0 ) ;
if ( $# xpids >= 1 )
{ # will have at least "0" for the grep
xCAT::MsgUtils - > message ( 'I' , "Stopping xcatd processes....\n" ) ;
foreach my $ ps ( @ xpids )
2008-09-15 18:15:42 +00:00
{
2009-02-04 17:18:44 +00:00
$ ps =~ s/^\s+// ; # strip any leading spaces
my ( $ uid , $ pid , $ ppid , $ desc ) = split /\s+/ , $ ps ;
# if $ps contains "grep" then it's not one of the daemon processes
if ( $ ps !~ /grep/ )
2008-09-15 18:15:42 +00:00
{
2009-02-04 17:18:44 +00:00
# print "pid=$pid\n";
#my $cmd = "/bin/kill -9 $pid";
my $ cmd = "/bin/kill $pid" ;
xCAT::Utils - > runcmd ( $ cmd , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
xCAT::MsgUtils - > message ( 'E' ,
"Could not stop xcatd process $pid.\n" ) ;
return 1 ;
}
2008-09-15 18:15:42 +00:00
}
}
}
2009-02-04 17:18:44 +00:00
if ( $ cmd eq "xcatstart" )
{ # start xcatd
xCAT::MsgUtils - > message ( 'I' , "Starting xcatd.....\n" ) ;
my $ xcmd = "$::XCATROOT/sbin/xcatd &" ;
my $ outref = xCAT::Utils - > runcmd ( "$xcmd" , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
xCAT::MsgUtils - > message ( 'E' , "Could not start xcatd process.\n" ) ;
return 1 ;
}
2008-09-15 18:15:42 +00:00
}
2009-02-04 17:18:44 +00:00
return 0 ;
2008-09-15 18:15:42 +00:00
}
2008-09-26 23:07:45 +00:00
2008-10-27 16:07:21 +00:00
#-------------------------------------------------------------------------------
= head3 get_image_name
get a name for the install image on AIX and Linux , to be used
by xdsh and sinv for the nodename
Arguments:
path to image .
Returns:
imagename
= cut
#-------------------------------------------------------------------------------
2009-02-04 17:18:44 +00:00
sub get_image_name
{
my ( $ class , $ imagepath ) = @ _ ;
my $ imagename ;
if ( xCAT::Utils - > isLinux ( ) )
{
my @ fields = split ( '/' , $ imagepath ) ;
$ imagename . = $ fields [ 5 ] ;
$ imagename . = "-" ;
$ imagename . = $ fields [ 3 ] ;
$ imagename . = "-" ;
$ imagename . = $ fields [ 4 ] ;
}
else
{ # AIX
my @ fields = split ( '/' , $ imagepath ) ;
my $ name = pop @ fields ;
$ imagename = $ name ;
}
2008-10-27 16:07:21 +00:00
2009-02-04 17:18:44 +00:00
return $ imagename ;
}
2008-09-26 23:07:45 +00:00
2009-01-28 18:49:02 +00:00
#-------------------------------------------------------------------------------
= head3 logEventsToDatabase
Logs the given events info to the xCAT 's ' eventlog ' database
Arguments:
arrayref - - A pointer to an array . Each element is a hash that contains an events .
The hash should contain the at least one of the following keys :
2011-03-27 12:18:38 +00:00
eventtime - - The format is "yyyy-mm-dd hh:mm:ss" .
2009-01-28 18:49:02 +00:00
If omitted , the current date and time will be used .
monitor - - The name of the monitor that monitors this event .
monnode - - The node that monitors this event .
node - - The node where the event occurred .
application - - The application that reports the event .
component - - The component where the event occurred .
id - - The location or the resource name where the event occurred .
severity - - The severity of the event . Valid values are: informational , warning , critical .
message - - The full description of the event .
rawdata - - The data that associated with the event .
Returns:
( ret code , error message )
2009-01-29 02:41:02 +00:00
Example:
my @ a = ( ) ;
my $ event = {
2011-03-27 12:18:38 +00:00
eventtime = > "2009-07-28 23:02:03" ,
2009-01-29 02:41:02 +00:00
node = > 'node1' ,
rawdata = > 'kjdlkfajlfjdlksaj' ,
} ;
push ( @ a , $ event ) ;
my $ event1 = {
node = > 'cu03cp' ,
monnode = > 'cu03sv' ,
application = > 'RMC' ,
component = > 'IBM.Sensor' ,
id = > 'AIXErrorLogSensor' ,
severity = > 'warning' ,
} ;
push ( @ a , $ event1 ) ;
xCAT::Utils - > logEventsToDatabase ( \ @ a ) ;
2009-01-28 18:49:02 +00:00
= cut
#-------------------------------------------------------------------------------
2009-02-04 17:18:44 +00:00
sub logEventsToDatabase
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2009-02-04 17:18:44 +00:00
my $ pEvents = shift ;
if ( ( $ pEvents ) && ( $ pEvents =~ /xCAT::Utils/ ) )
{
$ pEvents = shift ;
}
2009-02-03 17:13:20 +00:00
2009-02-04 17:18:44 +00:00
if ( ( $ pEvents ) && ( @$ pEvents > 0 ) )
{
my $ currtime ;
my $ tab = xCAT::Table - > new ( "eventlog" , - create = > 1 , - autocommit = > 0 ) ;
if ( ! $ tab )
{
return ( 1 , "The evnetlog table cannot be opened." ) ;
}
2009-02-03 17:13:20 +00:00
2009-02-04 17:18:44 +00:00
foreach my $ event ( @$ pEvents )
{
2009-02-03 17:13:20 +00:00
2009-02-04 17:18:44 +00:00
#create event time if it does not exist
if ( ! exists ( $ event - > { eventtime } ) )
{
if ( ! $ currtime )
{
my (
$ sec , $ min , $ hour , $ mday , $ mon ,
$ year , $ wday , $ yday , $ isdst
)
= localtime ( time ) ;
2011-03-27 12:18:38 +00:00
$ currtime = sprintf ( "%04d-%02d-%02d %02d:%02d:%02d" ,
$ year + 1900 , $ mon + 1 , $ mday ,
2009-02-04 17:18:44 +00:00
$ hour , $ min , $ sec ) ;
}
$ event - > { eventtime } = $ currtime ;
}
my @ ret = $ tab - > setAttribs ( undef , $ event ) ;
if ( @ ret > 1 ) { return ( 1 , $ ret [ 1 ] ) ; }
}
$ tab - > commit ;
}
2009-02-03 17:13:20 +00:00
2009-02-04 17:18:44 +00:00
return ( 0 , "" ) ;
2009-02-03 17:13:20 +00:00
}
2011-01-21 19:49:32 +00:00
#-------------------------------------------------------------------------------
= head3 logEventsToTealDatabase
Logs the given events info to the TEAL 's ' x_tealeventlog ' database
Arguments:
arrayref - - A pointer to an array . Each element is a hash that contains an events .
Returns:
( ret code , error message )
= cut
#-------------------------------------------------------------------------------
sub logEventsToTealDatabase
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2011-01-21 19:49:32 +00:00
my $ pEvents = shift ;
if ( ( $ pEvents ) && ( $ pEvents =~ /xCAT::Utils/ ) )
{
$ pEvents = shift ;
}
if ( ( $ pEvents ) && ( @$ pEvents > 0 ) )
{
my $ currtime ;
my $ tab = xCAT::Table - > new ( "x_tealeventlog" , - create = > 1 , - autocommit = > 0 ) ;
if ( ! $ tab )
{
return ( 1 , "The x_tealeventlog table cannot be opened." ) ;
}
foreach my $ event ( @$ pEvents )
{
my @ ret = $ tab - > setAttribs ( undef , $ event ) ;
if ( @ ret > 1 ) { return ( 1 , $ ret [ 1 ] ) ; }
}
$ tab - > commit ;
}
return ( 0 , "" ) ;
}
2009-02-28 17:05:34 +00:00
#-------------------------------------------------------------------------------
2009-03-16 12:50:22 +00:00
= head3 StartService
2009-03-02 14:27:10 +00:00
Supports AIX and Linux as long as the service is registered with
lssrc or startsrc .
Used by the service node plugin ( AAsn . pm ) to start requested services .
Checks to see if the input service is already started . If it is started
2009-03-16 12:50:22 +00:00
it stops and starts the service . Otherwise
it just starts the service .
2009-03-02 14:27:10 +00:00
Note we are using the system command on the start of the services to see
the output when the xcatd is started on Service Nodes . Do not change this .
Arguments:
servicename
force flag
Returns:
2009-03-16 12:50:22 +00:00
0 - ok
2009-03-02 14:27:10 +00:00
1 - could not start the service
Globals:
none
Error:
1 error
Example:
2009-03-16 12:50:22 +00:00
if ( xCAT::Utils - > startService ( "named" ) { ... }
2009-03-02 14:27:10 +00:00
Comments:
none
= cut
#-------------------------------------------------------------------------------
sub startService
{
2009-03-16 12:50:22 +00:00
my ( $ class , $ service ) = @ _ ;
2009-03-02 14:27:10 +00:00
my $ rc = 0 ;
my @ output ;
my $ cmd ;
if ( xCAT::Utils - > isAIX ( ) )
{
2009-03-16 12:50:22 +00:00
@ output = xCAT::Utils - > runcmd ( "LANG=C /usr/bin/lssrc -s $service" , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{ # error so start it
$ cmd = "/usr/bin/stopsrc -s $service" ;
system $ cmd ; # note using system here to see output when
# daemon comes up
if ( $? > 0 )
{ # error
xCAT::MsgUtils - > message ( "S" , "Error on command: $cmd\n" ) ;
}
$ cmd = "/usr/bin/startsrc -s $service" ;
system $ cmd ;
if ( $? > 0 )
{ # error
xCAT::MsgUtils - > message ( "S" , "Error on command: $cmd\n" ) ;
return 1 ;
}
}
else
{
# check to see if running
my ( $ subsys , $ group , $ pid , $ status ) = split ( ' ' , $ output [ 1 ] ) ;
if ( defined ( $ status ) && $ status eq 'active' )
{
# already running, stop and start
2009-03-02 14:27:10 +00:00
$ cmd = "/usr/bin/stopsrc -s $service" ;
system $ cmd ; # note using system here to see output when
# daemon comes up
if ( $? > 0 )
{ # error
xCAT::MsgUtils - > message ( "S" , "Error on command: $cmd\n" ) ;
}
$ cmd = "/usr/bin/startsrc -s $service" ;
system $ cmd ;
if ( $? > 0 )
{ # error
xCAT::MsgUtils - > message ( "S" , "Error on command: $cmd\n" ) ;
return 1 ;
}
2009-03-16 12:50:22 +00:00
return 0 ;
2009-03-02 14:27:10 +00:00
}
2009-03-16 12:50:22 +00:00
else
2009-03-02 14:27:10 +00:00
{
2009-03-16 12:50:22 +00:00
# not running, start it
$ cmd = "/usr/bin/startsrc -s $service" ;
system $ cmd ; # note using system here to see output when
# daemon comes up
if ( $? > 0 )
{
xCAT::MsgUtils - > message ( "S" , "Error on command: $cmd\n" ) ;
return 1 ;
2009-03-02 14:27:10 +00:00
}
2009-03-16 12:50:22 +00:00
2009-03-02 14:27:10 +00:00
}
}
2009-03-16 12:50:22 +00:00
}
else # linux
{
my @ output = xCAT::Utils - > runcmd ( "service $service status" , - 1 ) ;
if ( $ ::RUNCMD_RC == 0 )
2009-03-02 14:27:10 +00:00
{
2009-03-24 19:25:31 +00:00
# whether or not an error is returned varies by service
2009-03-16 12:50:22 +00:00
# stop and start the service for those running
if ( ( $ service ne "conserver" ) && ( $ service ne "nfs" ) )
2009-03-02 14:27:10 +00:00
{
2009-03-16 12:50:22 +00:00
$ cmd = "service $service stop" ;
2009-09-23 14:09:12 +00:00
print ' ' ; # indent service output to separate it from the xcatd service output
2009-03-16 12:50:22 +00:00
system $ cmd ;
if ( $? > 0 )
{ # error
xCAT::MsgUtils - > message ( "S" , "Error on command: $cmd\n" ) ;
}
$ cmd = "service $service start" ;
2009-09-23 14:09:12 +00:00
print ' ' ; # indent service output to separate it from the xcatd service output
2009-03-16 12:50:22 +00:00
system $ cmd ;
if ( $? > 0 )
{ # error
xCAT::MsgUtils - > message ( "S" , "Error on command: $cmd\n" ) ;
return 1 ;
}
return 0 ;
2009-03-02 14:27:10 +00:00
}
2009-03-16 12:50:22 +00:00
if ( ( $ service eq "conserver" ) || ( $ service eq "nfs" ) )
{
# must check output
if ( grep ( /running/ , @ output ) )
2009-03-02 14:27:10 +00:00
{
2009-03-16 12:50:22 +00:00
$ cmd = "service $service stop" ;
2009-09-23 14:09:12 +00:00
print ' ' ; # indent service output to separate it from the xcatd service output
2009-03-16 12:50:22 +00:00
system $ cmd ;
if ( $? > 0 )
{ # error
xCAT::MsgUtils - > message ( "S" ,
"Error on command: $cmd\n" ) ;
}
$ cmd = "service $service start" ;
2009-09-23 14:09:12 +00:00
print ' ' ; # indent service output to separate it from the xcatd service output
2009-03-16 12:50:22 +00:00
system $ cmd ;
if ( $? > 0 )
{ # error
xCAT::MsgUtils - > message ( "S" ,
"Error on command: $cmd\n" ) ;
return 1 ;
}
2009-03-02 14:27:10 +00:00
return 0 ;
}
2009-03-16 12:50:22 +00:00
else
2009-03-02 14:27:10 +00:00
{
2009-03-16 12:50:22 +00:00
# not running , just start
$ cmd = "service $service start" ;
2009-09-23 14:09:12 +00:00
print ' ' ; # indent service output to separate it from the xcatd service output
2009-03-16 12:50:22 +00:00
system $ cmd ;
if ( $? > 0 )
{ # error
2009-03-02 14:27:10 +00:00
xCAT::MsgUtils - > message ( "S" ,
"Error on command: $cmd\n" ) ;
return 1 ;
}
2009-03-16 12:50:22 +00:00
return 0 ;
2009-03-02 14:27:10 +00:00
}
}
}
else
2009-03-16 12:50:22 +00:00
{
2009-03-24 19:25:31 +00:00
# error getting status, check output
2009-03-16 12:50:22 +00:00
# must check output
2009-03-24 19:25:31 +00:00
if ( grep ( /stopped/ , @ output ) ) # stopped
2009-03-16 12:50:22 +00:00
{
$ cmd = "service $service start" ;
2009-09-23 14:09:12 +00:00
print ' ' ; # indent service output to separate it from the xcatd service output
2009-03-16 12:50:22 +00:00
system $ cmd ;
if ( $? > 0 )
2009-03-24 19:25:31 +00:00
{ # error
xCAT::MsgUtils - > message ( "S" , "Error on command: $cmd\n" ) ;
return 1 ;
2009-03-16 12:50:22 +00:00
}
2009-03-24 19:25:31 +00:00
}
else
{ # not sure
2009-03-16 12:50:22 +00:00
$ cmd = "service $service stop" ;
2009-09-23 14:09:12 +00:00
print ' ' ; # indent service output to separate it from the xcatd service output
2009-03-16 12:50:22 +00:00
system $ cmd ;
if ( $? > 0 )
2009-03-24 19:25:31 +00:00
{ # error
xCAT::MsgUtils - > message ( "S" , "Error on command: $cmd\n" ) ;
2009-03-16 12:50:22 +00:00
}
$ cmd = "service $service start" ;
2009-09-23 14:09:12 +00:00
print ' ' ; # indent service output to separate it from the xcatd service output
2009-03-16 12:50:22 +00:00
system $ cmd ;
if ( $? > 0 )
2009-03-24 19:25:31 +00:00
{ # error
xCAT::MsgUtils - > message ( "S" , "Error on command: $cmd\n" ) ;
return 1 ;
2009-03-16 12:50:22 +00:00
}
2009-03-02 14:27:10 +00:00
}
}
}
2009-03-16 12:50:22 +00:00
2009-03-02 14:27:10 +00:00
return $ rc ;
}
2009-03-03 19:39:17 +00:00
2009-03-02 14:27:10 +00:00
#-------------------------------------------------------------------------------
2009-02-28 17:05:34 +00:00
= head3 CheckVersion
Checks the two versions numbers to see which one is greater .
Arguments:
ver_a the version number in format of d . d . d . d ...
ver_b the version number in format of d . d . d . d ...
Returns:
1 if ver_a is greater than ver_b
0 if ver_a is eaqual to ver_b
- 1 if ver_a is smaller than ver_b
= cut
#-------------------------------------------------------------------------------
2009-03-03 19:39:17 +00:00
sub CheckVersion
{
my $ ver_a = shift ;
if ( $ ver_a =~ /xCAT::Utils/ )
{
$ ver_a = shift ;
}
my $ ver_b = shift ;
my @ a = split ( /\./ , $ ver_a ) ;
my @ b = split ( /\./ , $ ver_b ) ;
my $ len_a = @ a ;
my $ len_b = @ b ;
my $ index = 0 ;
my $ max_index = ( $ len_a > $ len_b ) ? $ len_a : $ len_b ;
for ( $ index = 0 ; $ index <= $ max_index ; $ index + + )
{
my $ val_a = ( $ len_a < $ index ) ? 0 : $ a [ $ index ] ;
my $ val_b = ( $ len_b < $ index ) ? 0 : $ b [ $ index ] ;
if ( $ val_a > $ val_b ) { return 1 ; }
if ( $ val_a < $ val_b ) { return - 1 ; }
}
2009-02-28 17:05:34 +00:00
return 0 ;
}
2009-03-11 17:22:43 +00:00
#-------------------------------------------------------------------------------
= head3 getFacingIP
Gets the ip address of the adapter of the localhost that is facing the
the given node .
2010-05-12 02:39:41 +00:00
Assume it is the same as my_ip_facing ...
2009-03-11 17:22:43 +00:00
Arguments:
The name of the node that is facing the localhost .
Returns:
The ip address of the adapter that faces the node .
= cut
#-------------------------------------------------------------------------------
2009-03-16 12:50:22 +00:00
sub getFacingIP
{
2009-03-11 17:22:43 +00:00
my ( $ class , $ node ) = @ _ ;
my $ ip ;
my $ cmd ;
my @ ipaddress ;
my $ nodeip = inet_ntoa ( inet_aton ( $ node ) ) ;
unless ( $ nodeip =~ /\d+\.\d+\.\d+\.\d+/ )
{
return 0 ; #Not supporting IPv6 here IPV6TODO
}
$ cmd = "ifconfig" . " -a" ;
$ cmd = $ cmd . "| grep \"inet \"" ;
my @ result = xCAT::Utils - > runcmd ( $ cmd , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
xCAT::MsgUtils - > message ( "S" , "Error from $cmd\n" ) ;
exit $ ::RUNCMD_RC ;
}
2009-03-16 12:50:22 +00:00
2009-03-11 17:22:43 +00:00
# split node address
my ( $ n1 , $ n2 , $ n3 , $ n4 ) = split ( '\.' , $ nodeip ) ;
foreach my $ addr ( @ result )
{
my $ ip ;
my $ mask ;
if ( xCAT::Utils - > isLinux ( ) )
{
my ( $ inet , $ addr1 , $ Bcast , $ Mask ) = split ( " " , $ addr ) ;
2009-03-16 12:50:22 +00:00
if ( ( ! $ addr1 ) || ( ! $ Mask ) ) { next ; }
my @ ips = split ( ":" , $ addr1 ) ;
my @ masks = split ( ":" , $ Mask ) ;
$ ip = $ ips [ 1 ] ;
$ mask = $ masks [ 1 ] ;
2009-03-11 17:22:43 +00:00
}
else
{ #AIX
2009-03-16 12:50:22 +00:00
my ( $ inet , $ addr1 , $ netmask , $ mask1 , $ Bcast , $ bcastaddr ) =
split ( " " , $ addr ) ;
if ( ( ! $ addr1 ) && ( ! $ mask1 ) ) { next ; }
$ ip = $ addr1 ;
$ mask1 =~ s/0x// ;
$ mask =
`printf "%d.%d.%d.%d" \$(echo "$mask1" | sed 's/../0x& /g')` ;
}
if ( $ ip && $ mask )
{
# split interface IP
my ( $ h1 , $ h2 , $ h3 , $ h4 ) = split ( '\.' , $ ip ) ;
# split mask
my ( $ m1 , $ m2 , $ m3 , $ m4 ) = split ( '\.' , $ mask ) ;
# AND this interface IP with the netmask of the network
my $ a1 = ( ( int $ h1 ) & ( int $ m1 ) ) ;
my $ a2 = ( ( int $ h2 ) & ( int $ m2 ) ) ;
my $ a3 = ( ( int $ h3 ) & ( int $ m3 ) ) ;
my $ a4 = ( ( int $ h4 ) & ( int $ m4 ) ) ;
# AND node IP with the netmask of the network
my $ b1 = ( ( int $ n1 ) & ( int $ m1 ) ) ;
my $ b2 = ( ( int $ n2 ) & ( int $ m2 ) ) ;
my $ b3 = ( ( int $ n3 ) & ( int $ m3 ) ) ;
my $ b4 = ( ( int $ n4 ) & ( int $ m4 ) ) ;
if ( ( $ b1 == $ a1 ) && ( $ b2 == $ a2 ) && ( $ b3 == $ a3 ) && ( $ b4 == $ a4 ) )
{
return $ ip ;
}
}
2009-03-11 17:22:43 +00:00
}
xCAT::MsgUtils - > message ( "S" , "Cannot find master for the node $node\n" ) ;
2009-03-16 12:50:22 +00:00
return 0 ;
2009-03-11 17:22:43 +00:00
}
2009-03-24 19:25:31 +00:00
2009-03-18 12:07:50 +00:00
#-------------------------------------------------------------------------------
= head3 osver
Returns the os and version of the System you are running on
Arguments:
none
Returns:
0 - ok
Globals:
none
Error:
1 error
Example:
my $ os = ( xCAT::Utils - > osver { ... }
Comments:
none
= cut
#-------------------------------------------------------------------------------
sub osver
{
2009-03-24 19:25:31 +00:00
my $ osver = "unknown" ;
my $ os = '' ;
my $ ver = '' ;
my $ line = '' ;
my @ lines ;
2010-08-06 12:36:39 +00:00
my $ relfile ;
2009-03-24 19:25:31 +00:00
if ( - f "/etc/redhat-release" )
{
2010-08-06 12:36:39 +00:00
open ( $ relfile , "<" , "/etc/redhat-release" ) ;
$ line = <$relfile> ;
close ( $ relfile ) ;
chomp ( $ line ) ;
2009-03-24 19:25:31 +00:00
$ os = "rh" ;
2010-08-06 12:36:39 +00:00
$ ver = $ line ;
$ ver =~ tr /\./ / ;
2009-03-24 19:25:31 +00:00
$ ver =~ s/[^0-9]*([0-9]+).*/$1/ ;
if ( $ line =~ /AS/ ) { $ os = 'rhas' }
elsif ( $ line =~ /ES/ ) { $ os = 'rhes' }
elsif ( $ line =~ /WS/ ) { $ os = 'rhws' }
2009-03-18 12:07:50 +00:00
elsif ( $ line =~ /Server/ ) { $ os = 'rhserver' }
elsif ( $ line =~ /Client/ ) { $ os = 'rhclient' }
2009-03-24 19:25:31 +00:00
elsif ( - f "/etc/fedora-release" ) { $ os = 'rhfc' }
}
elsif ( - f "/etc/SuSE-release" )
{
2010-08-06 12:36:39 +00:00
open ( $ relfile , "<" , "/etc/SuSE-release" ) ;
@ lines = <$relfile> ;
close ( $ relfile ) ;
chomp ( @ lines ) ;
2009-03-24 19:25:31 +00:00
if ( grep /SLES|Enterprise Server/ , @ lines ) { $ os = "sles" }
if ( grep /SLEC/ , @ lines ) { $ os = "slec" }
2010-08-06 12:36:39 +00:00
$ ver = $ lines [ 0 ] ;
$ ver =~ tr /\./ / ;
2009-03-24 19:25:31 +00:00
$ ver =~ s/[^0-9]*([0-9]+).*/$1/ ;
#print "ver: $ver\n";
}
elsif ( - f "/etc/UnitedLinux-release" )
{
$ os = "ul" ;
2010-08-06 12:36:39 +00:00
open ( $ relfile , "<" , "/etc/UnitedLinux-release" ) ;
$ ver = <$relfile> ;
close ( $ relfile ) ;
$ ver =~ tr /\./ / ;
2009-03-24 19:25:31 +00:00
$ ver =~ s/[^0-9]*([0-9]+).*/$1/ ;
}
2011-10-06 17:45:08 +00:00
elsif ( - f "/etc/lsb-release" ) # Possibly Ubuntu
2011-08-15 00:30:40 +00:00
{
2011-10-06 17:45:08 +00:00
if ( open ( $ relfile , "<" , "/etc/lsb-release" ) ) {
my @ text = <$relfile> ;
close ( $ relfile ) ;
chomp ( @ text ) ;
my $ distrib_id = '' ;
my $ distrib_rel = '' ;
foreach ( @ text ) {
if ( $ _ =~ /^\s*DISTRIB_ID=(.*)$/ ) {
$ distrib_id = $ 1 ; # last DISTRIB_ID value in file used
} elsif ( $ _ =~ /^\s*DISTRIB_RELEASE=(.*)$/ ) {
$ distrib_rel = $ 1 ; # last DISTRIB_RELEASE value in file used
}
}
if ( $ distrib_id =~ /^(Ubuntu|"Ubuntu")\s*$/ ) {
$ os = "ubuntu" ;
if ( $ distrib_rel =~ /^(.*?)\s*$/ ) { # eliminate trailing blanks, if any
$ distrib_rel = $ 1 ;
}
if ( $ distrib_rel =~ /^"(.*?)"$/ ) { # eliminate enclosing quotes, if any
$ distrib_rel = $ 1 ;
}
$ ver = $ distrib_rel ;
}
2011-08-15 00:30:40 +00:00
}
}
2009-03-24 19:25:31 +00:00
$ os = "$os" . "$ver" ;
return ( $ os ) ;
2009-03-18 12:07:50 +00:00
}
2009-03-24 19:25:31 +00:00
#-------------------------------------------------------------------------------
2009-03-25 12:09:22 +00:00
= head3 checkCredFiles
2009-03-24 19:25:31 +00:00
Checks the various credential files on the Management Node to
make sure the permission are correct for using and transferring
to the nodes and service nodes .
Also removes /install/ postscripts /etc/xc at / cfgloc if found
Arguments:
$ callback
Returns:
0 - ok
Globals:
none
Error:
warnings of possible missing files and directories
Example:
my $ rc = xCAT::Utils - > checkCreds
Comments:
none
= cut
#-------------------------------------------------------------------------------
2009-03-25 12:09:22 +00:00
sub checkCredFiles
2009-03-24 19:25:31 +00:00
{
2009-03-25 12:09:22 +00:00
my $ lib = shift ;
2009-03-24 19:25:31 +00:00
my $ cb = shift ;
2010-02-24 06:41:20 +00:00
my $ installdir = getInstallDir ( ) ;
my $ dir = "$installdir/postscripts/_xcat" ;
2009-03-24 19:25:31 +00:00
if ( - d $ dir )
{
my $ file = "$dir/ca.pem" ;
if ( - e $ file )
{
my $ cmd = "/bin/chmod 0644 $file" ;
my $ outref = xCAT::Utils - > runcmd ( "$cmd" , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Error on command: $cmd" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
}
else
{ # ca.pem missing
my $ rsp = { } ;
2009-05-11 13:02:34 +00:00
$ rsp - > { data } - > [ 0 ] = "Error: $file is missing. Run xcatconfig (no force)" ;
2009-03-24 19:25:31 +00:00
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
}
else
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Error: $dir is missing." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
2009-03-25 12:09:22 +00:00
2010-02-24 06:41:20 +00:00
$ dir = "$installdir/postscripts/ca" ;
2009-03-24 19:25:31 +00:00
if ( - d $ dir )
{
my $ file = "$dir/ca-cert.pem" ;
if ( - e $ file )
{
my $ cmd = "/bin/chmod 0644 $file" ;
my $ outref = xCAT::Utils - > runcmd ( "$cmd" , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Error on command: $cmd" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
}
else
{ # ca_cert.pem missing
2009-03-25 12:09:22 +00:00
my $ rsp = { } ;
2009-05-11 13:02:34 +00:00
$ rsp - > { data } - > [ 0 ] = "Error: $file is missing. Run xcatconfig (no force)" ;
2009-03-25 12:09:22 +00:00
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
}
else
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Error: $dir is missing." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
2009-03-24 19:25:31 +00:00
# ssh hostkeys
2010-02-24 06:41:20 +00:00
$ dir = "$installdir/postscripts/hostkeys" ;
2009-03-24 19:25:31 +00:00
if ( - d $ dir )
{
my $ file = "$dir/ssh_host_key.pub" ;
if ( - e $ file )
{
my $ file2 = "$dir/*.pub" ; # all public keys
my $ cmd = "/bin/chmod 0644 $file2" ;
my $ outref = xCAT::Utils - > runcmd ( "$cmd" , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Error on command: $cmd" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
}
else
{ # hostkey missing
my $ rsp = { } ;
2009-05-11 13:02:34 +00:00
$ rsp - > { data } - > [ 0 ] = "Error: $file is missing. Run xcatconfig (no force)" ;
2009-03-24 19:25:31 +00:00
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
}
else
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Error: $dir is missing." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
2009-05-11 12:27:30 +00:00
# ssh hostkeys
2010-02-04 13:40:09 +00:00
$ dir = "/etc/xcat/hostkeys" ;
2009-05-11 12:27:30 +00:00
if ( - d $ dir )
{
my $ file = "$dir/ssh_host_key.pub" ;
if ( - e $ file )
{
my $ file2 = "$dir/*.pub" ; # all public keys
my $ cmd = "/bin/chmod 0644 $file2" ;
my $ outref = xCAT::Utils - > runcmd ( "$cmd" , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Error on command: $cmd" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
}
else
{ # hostkey missing
my $ rsp = { } ;
2009-05-11 13:02:34 +00:00
$ rsp - > { data } - > [ 0 ] = "Error: $file is missing. Run xcatconfig (no force)" ;
2009-05-11 12:27:30 +00:00
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
}
else
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Error: $dir is missing." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
# ssh directory
2010-02-24 06:41:20 +00:00
$ dir = "$installdir/postscripts/_ssh" ;
2009-03-24 19:25:31 +00:00
if ( - d $ dir )
{
my $ file = "$dir/authorized_keys" ;
if ( - e $ file )
{
my $ file2 = "$dir/authorized_keys*" ;
my $ cmd = "/bin/chmod 0644 $file2" ;
my $ outref = xCAT::Utils - > runcmd ( "$cmd" , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Error on command: $cmd" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
# make install script executable
$ file2 = "$dir/copy.sh" ;
if ( - e $ file2 )
{
my $ cmd = "/bin/chmod 0744 $file2" ;
my $ outref = xCAT::Utils - > runcmd ( "$cmd" , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Error on command: $cmd" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
}
}
else
{ # authorized keys missing
my $ rsp = { } ;
2009-05-11 13:02:34 +00:00
$ rsp - > { data } - > [ 0 ] = "Error: $file is missing. Run xcatconfig (no force)" ;
2009-03-24 19:25:31 +00:00
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
}
else
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Error: $dir is missing." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
# remove any old cfgloc files
2010-02-24 06:41:20 +00:00
my $ file = "$installdir/postscripts/etc/xcat/cfgloc" ;
2009-03-24 19:25:31 +00:00
if ( - e $ file )
{
my $ cmd = "/bin/rm $file" ;
my $ outref = xCAT::Utils - > runcmd ( "$cmd" , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Error on command: $cmd" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ cb ) ;
}
}
}
2009-03-11 17:22:43 +00:00
2009-06-26 14:45:50 +00:00
#-----------------------------------------------------------------------------
= head3 acquire_lock
Get a lock on an arbirtrary named resource . For now , this is only across the scope of one service node /master node, an argument may be added later if/ when 'global' locks are supported . This call will block until the lock is free .
Arguments:
A string name for the lock to acquire
Returns:
false on failure
A reference for the lock being held .
= cut
sub acquire_lock {
my $ lock_name = shift ;
use File::Path ;
mkpath ( "/var/lock/xcat/" ) ;
use Fcntl ":flock" ;
my $ tlock ;
$ tlock - > { path } = "/var/lock/xcat/" . $ lock_name ;
open ( $ tlock - > { fd } , ">" , $ tlock - > { path } ) or return undef ;
unless ( $ tlock - > { fd } ) { return undef ; }
flock ( $ tlock - > { fd } , LOCK_EX ) or return undef ;
return $ tlock ;
}
#---------------------
= head3 release_lock
Release an acquired lock
Arguments:
reference to lock
Returns:
false on failure , true on success
= cut
sub release_lock {
my $ tlock = shift ;
unlink ( $ tlock - > { path } ) ;
flock ( $ tlock - > { fd } , LOCK_UN ) ;
close ( $ tlock - > { fd } ) ;
}
2009-06-19 08:32:47 +00:00
#-----------------------------------------------------------------------------
= head3 getrootimage
Get the directory of root image for a node ;
Note: This subroutine only works for diskless node
Arguments:
$ node
Returns:
string - directory of the root image
undef - this is not a diskless node or the root image does not existed
Globals:
none
Error:
Example:
my $ node_syncfile = xCAT::Utils - > getrootimage ( $ node ) ;
= cut
#-----------------------------------------------------------------------------
sub getrootimage ()
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2009-06-19 08:32:47 +00:00
my $ node = shift ;
2010-02-24 06:41:20 +00:00
my $ installdir = getInstallDir ( ) ;
2009-06-19 08:32:47 +00:00
if ( ( $ node ) && ( $ node =~ /xCAT::Utils/ ) )
{
$ node = shift ;
}
# get the os,arch,profile attributes for the nodes
my $ nodetype_t = xCAT::Table - > new ( 'nodetype' ) ;
unless ( $ nodetype_t ) {
return ;
}
my $ nodetype_v = $ nodetype_t - > getNodeAttribs ( $ node , [ 'profile' , 'os' , 'arch' ] ) ;
my $ profile = $ nodetype_v - > { 'profile' } ;
my $ os = $ nodetype_v - > { 'os' } ;
my $ arch = $ nodetype_v - > { 'arch' } ;
if ( $^O eq "linux" ) {
2010-02-24 06:41:20 +00:00
my $ rootdir = "$installdir/netboot/$os/$arch/$profile/rootimg/" ;
2009-06-19 08:32:47 +00:00
if ( - d $ rootdir ) {
return $ rootdir ;
} else {
return undef ;
}
} else {
# For AIX
}
}
2009-06-04 15:33:44 +00:00
2009-06-30 09:47:48 +00:00
#----------------------------------------------------------------------------
= head3 parse_selection_string
Parse the selection string and
write the parsed result into % wherehash
Arguments:
$ ss_ref - selection string array from - w flag
\ % wherehash - selection string hash % ::WhereHash
Returns:
0 - parse successfully
1 - parse failed
Globals:
% wherehash
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
sub parse_selection_string ()
{
my ( $ class , $ ss_ref , $ wherehash_ref ) = @ _ ;
2009-07-06 09:45:22 +00:00
# selection string is specified with one or multiple -w flags
# stored in an array
2009-06-30 09:47:48 +00:00
foreach my $ m ( @ { $ ss_ref } )
{
my $ attr ;
my $ val ;
my $ matchtype ;
2009-07-06 09:45:22 +00:00
if ( $ m =~ /^[^=]*\==/ ) { #attr==val
2009-06-30 09:47:48 +00:00
( $ attr , $ val ) = split /==/ , $ m , 2 ;
$ matchtype = 'match' ;
2009-07-06 09:45:22 +00:00
} elsif ( $ m =~ /^[^=]*=~/ ) { #attr=~val
2009-06-30 09:47:48 +00:00
( $ attr , $ val ) = split /=~/ , $ m , 2 ;
$ val =~ s/^\/// ;
$ val =~ s/\/$// ;
$ matchtype = 'regex' ;
2009-07-06 09:45:22 +00:00
} elsif ( $ m =~ /^[^=]*\!=/ ) { #attr!=val
2009-06-30 09:47:48 +00:00
( $ attr , $ val ) = split /!=/ , $ m , 2 ;
$ matchtype = 'natch' ;
2009-07-06 09:45:22 +00:00
} elsif ( $ m =~ /[^=]*!~/ ) { #attr!~val
2009-06-30 09:47:48 +00:00
( $ attr , $ val ) = split /!~/ , $ m , 2 ;
$ val =~ s/^\/// ;
$ val =~ s/\/$// ;
$ matchtype = 'negex' ;
} elsif ( $ m =~ /^[^=]*=[^=]+$/ ) { # attr=val is the same as attr==val
( $ attr , $ val ) = split /=/ , $ m , 2 ;
$ matchtype = 'match' ;
} else {
return 1 ;
}
if ( ! defined ( $ attr ) || ! defined ( $ val ) )
{
return 1 ;
}
$ wherehash_ref - > { $ attr } - > { 'val' } = $ val ;
$ wherehash_ref - > { $ attr } - > { 'matchtype' } = $ matchtype ;
}
return 0 ;
}
#----------------------------------------------------------------------------
= head3 selection_string_match
Check whether a node matches the selection string
defined in hash % wherehash
Arguments:
\ % objhash - the hash contains the objects definition
$ objname - the object name
$ wherehash_ref - the selection string hash
Returns:
0 - NOT match
1 - match
Globals:
% wherehash
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
sub selection_string_match ()
{
my ( $ class , $ objhash_ref , $ objname , $ wherehash_ref ) = @ _ ;
my % wherehash = %$ wherehash_ref ;
my $ match = 1 ;
foreach my $ testattr ( keys % wherehash ) {
# access non-exists hash entry will create an empty one
# we should not modify the $objhash_ref
if ( exists ( $ objhash_ref - > { $ objname } ) && exists ( $ objhash_ref - > { $ objname } - > { $ testattr } ) ) {
if ( $ wherehash { $ testattr } { 'matchtype' } eq 'match' ) { #attr==val or attr=val
if ( $ objhash_ref - > { $ objname } - > { $ testattr } ne $ wherehash { $ testattr } { 'val' } ) {
$ match = 0 ;
last ;
}
}
2009-07-06 09:45:22 +00:00
if ( $ wherehash { $ testattr } { 'matchtype' } eq 'natch' ) { #attr!=val
2009-06-30 09:47:48 +00:00
if ( $ objhash_ref - > { $ objname } - > { $ testattr } eq $ wherehash { $ testattr } { 'val' } ) {
$ match = 0 ;
last ;
}
}
if ( $ wherehash { $ testattr } { 'matchtype' } eq 'regex' ) { #attr=~val
if ( $ objhash_ref - > { $ objname } - > { $ testattr } !~ $ wherehash { $ testattr } { 'val' } ) {
$ match = 0 ;
last ;
}
}
if ( $ wherehash { $ testattr } { 'matchtype' } eq 'negex' ) { #attr!~val
if ( $ objhash_ref - > { $ objname } - > { $ testattr } =~ $ wherehash { $ testattr } { 'val' } ) {
$ match = 0 ;
last ;
}
}
} else { #$objhash_ref->{$objname}->{$testattr} does not exist
$ match = 0 ;
last ;
}
}
return $ match ;
}
2009-07-03 08:56:14 +00:00
#-------------------------------------------------------------------------------
= head3 check_deployment_monitoring_settings
Check the deployment retry monitoring settings .
Arguments:
$ request: request hash
$ mstring: The monitoring setting string
specified with the - m flag for rpower or rnetboot
Returns:
0 - ok
1 - failed
Globals:
none
Example:
my $ rc = xCAT::Utils - > check_deployment_monitoring_settings ( $ opt ( m ) )
Comments:
none
= cut
#-------------------------------------------------------------------------------
sub check_deployment_monitoring_settings ()
{
my ( $ class , $ request , $ opt_ref ) = @ _ ;
my $ callback = $ request - > { callback } ;
my @ mstring = @ { $ opt_ref - > { 'm' } } ;
# -r flag is required with -m flag
if ( ! defined ( $ opt_ref - > { 't' } ) ) {
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Flag missing, the -t flag is required" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
foreach my $ m ( @ mstring ) {
if ( $ m eq '' ) {
#No value specified with -m flag
next ;
}
my $ attr ;
my $ val ;
if ( $ m =~ /[^=]*==/ ) {
( $ attr , $ val ) = split /==/ , $ m , 2 ;
} elsif ( $ m =~ /^[^=]*=~/ ) {
( $ attr , $ val ) = split /=~/ , $ m , 2 ;
$ val =~ s/^\/// ;
$ val =~ s/\/$// ;
} else {
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Invalid string \"$m\" specified with -m flag" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
# The attr is table.column
if ( $ attr !~ /\..*$/ ) {
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Invalid attribute \"$attr\" specified with -m flag, should be table.column" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
if ( $ val eq '' ) {
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "The value of attribute \"$attr\" can not be NULL" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
}
return 0 ;
}
#-------------------------------------------------------------------------------
= head3 generate_monsettings ( )
Generate installation monitoring settings hash .
Arguments:
$ request: request hash
\ @ monnodes: nodes to be monitored
Returns:
\ % monsettings - the ref of % monsettings hash
Globals:
none
Example:
my $ monsettings_ref = xCAT::Utils - > generate_monsettings ( $ request , \ @ monnodes )
Comments:
none
= cut
#-------------------------------------------------------------------------------
sub generate_monsettings ()
{
my ( $ class , $ request , $ monnodes_ref ) = @ _ ;
my @ monnodes = @$ monnodes_ref ;
my $ callback = $ request - > { callback } ;
my @ mstring = @ { $ request - > { opt } - > { m } } ;
my % monsettings = ( ) ;
#set default value for each attribute,
#to avoid ugly perl syntax error
my % defaultattrs = (
"timeout" = > "10" ,
"retrycount" = > "3"
) ;
#Monitoring settings check already done in parse_args,
#Assume it is correct.
foreach my $ m ( @ mstring ) {
if ( $ m eq '' ) {
# No value specified with -m flag
next ;
}
my $ attr ;
my $ val ;
my $ matchtype ;
if ( $ m =~ /^[^=]*\==/ ) {
( $ attr , $ val ) = split /==/ , $ m , 2 ;
$ matchtype = 'match' ;
} elsif ( $ m =~ /^[^=]*=~/ ) {
( $ attr , $ val ) = split /=~/ , $ m , 2 ;
$ val =~ s/^\/// ;
$ val =~ s/\/$// ;
$ matchtype = 'regex' ;
}
#This is a table.column
my ( $ tab , $ col ) = split '\.' , $ attr ;
$ monsettings { 'monattrs' } { $ tab } { $ col } { 'val' } = $ val ;
$ monsettings { 'monattrs' } { $ tab } { $ col } { 'matchtype' } = $ matchtype ;
}
if ( defined ( $ request - > { opt } - > { r } ) ) {
$ monsettings { 'retrycount' } = $ request - > { opt } - > { r } ;
}
if ( defined ( $ request - > { opt } - > { t } ) ) {
$ monsettings { 'timeout' } = $ request - > { opt } - > { t } ;
}
#Set the default values
foreach my $ attr ( keys % defaultattrs ) {
if ( ( ! defined ( $ monsettings { $ attr } ) ) || ( $ monsettings { $ attr } eq '' ) ) {
$ monsettings { $ attr } = $ defaultattrs { $ attr } ;
}
}
if ( ! defined ( $ monsettings { 'monattrs' } ) || ( scalar ( keys % { $ monsettings { 'monattrs' } } ) == 0 ) ) {
$ monsettings { 'monattrs' } { 'nodelist' } { 'status' } { 'val' } = "booted" ;
$ monsettings { 'monattrs' } { 'nodelist' } { 'status' } { 'matchtype' } = "match" ;
}
#Initialize the %{$monsettings{'nodes'}} hash
foreach my $ node ( @ monnodes ) {
foreach my $ tab ( keys % { $ monsettings { 'monattrs' } } ) {
foreach my $ col ( keys % { $ monsettings { 'monattrs' } { $ tab } } ) {
$ monsettings { 'nodes' } { $ node } { 'status' } { $ tab } { $ col } = '' ;
}
}
}
return \ % monsettings ;
}
#-------------------------------------------------------------------------------
= head3 monitor_installation
Monitoring os installation progress .
Arguments:
$ request: request hash
Returns:
0 - ok
1 - failed
Globals:
none
Example:
my $ rc = xCAT::Utils - > monitor_installation ( $ opt ( m ) )
Comments:
none
= cut
#-------------------------------------------------------------------------------
sub monitor_installation ()
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2009-07-03 08:56:14 +00:00
my ( $ class , $ request , $ monsettings ) = @ _ ;
my $ callback = $ request - > { callback } ;
my $ mstring = $ request - > { opt } - > { m } ;
#This is the first time the monitor_installation is called,
# my $rsp={};
# my $monnodes = join ',', @monitornodes;
# $rsp->{data}->[0] = "Start monitoring the installation progress with settings \"$mstring\" for nodes $monnodes";
# xCAT::MsgUtils->message("I", $rsp, $callback);
$ monsettings - > { 'timeelapsed' } = 0 ;
while ( ( $ monsettings - > { 'timeelapsed' } < $ monsettings - > { 'timeout' } ) && ( scalar ( keys % { $ monsettings - > { 'nodes' } } ) ) ) {
#polling interval is 1 minute,
#do not do the first check until 1 minute after the os installation starts
2009-07-03 09:09:00 +00:00
sleep 60 ;
2009-07-03 08:56:14 +00:00
#update the timeelapsed
$ monsettings - > { 'timeelapsed' } + + ;
my @ monitornodes = keys % { $ monsettings - > { 'nodes' } } ;
# Look up tables, do not look up the same table more than once
my % tabattrs = ( ) ;
foreach my $ tab ( keys % { $ monsettings - > { 'monattrs' } } ) {
foreach my $ col ( keys % { $ monsettings - > { 'monattrs' } - > { $ tab } } ) {
if ( ! grep ( /^$col$/ , @ { $ tabattrs { $ tab } } ) ) {
push @ { $ tabattrs { $ tab } } , $ col ;
}
}
}
foreach my $ node ( keys % { $ monsettings - > { 'nodes' } } ) {
foreach my $ montable ( keys % tabattrs ) {
#Get the new status of the node
my $ montab_ref = xCAT::Table - > new ( $ montable ) ;
if ( $ montab_ref ) {
my @ attrs = @ { $ tabattrs { $ montable } } ;
my $ tabdata = $ montab_ref - > getNodesAttribs ( \ @ monitornodes , \ @ attrs ) ;
foreach my $ attr ( @ { $ tabattrs { $ montable } } ) {
# nodestatus changed, print a message
if ( ( $ monsettings - > { 'nodes' } - > { $ node } - > { 'status' } - > { $ montable } - > { $ attr } ne '' )
&& ( $ monsettings - > { 'nodes' } - > { $ node } - > { 'status' } - > { $ montable } - > { $ attr } ne $ tabdata - > { $ node } - > [ 0 ] - > { $ attr } ) ) {
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "$node $montable.$attr: $monsettings->{'nodes'}->{$node}->{'status'}->{$montable}->{$attr} => $tabdata->{$node}->[0]->{$attr}" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
}
#set the new status
$ monsettings - > { 'nodes' } - > { $ node } - > { 'status' } - > { $ montable } - > { $ attr } = $ tabdata - > { $ node } - > [ 0 ] - > { $ attr } ;
}
$ montab_ref - > close ( ) ;
} else { #can not open the table
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Open table $montable failed" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return ( ) ;
}
}
#expected status??
my $ statusmatch = 1 ;
foreach my $ temptab ( keys % { $ monsettings - > { 'monattrs' } } ) {
foreach my $ tempcol ( keys % { $ monsettings - > { 'monattrs' } - > { $ temptab } } ) {
my $ currentstatus = $ monsettings - > { 'nodes' } - > { $ node } - > { 'status' } - > { $ temptab } - > { $ tempcol } ;
my $ expectedstatus = $ monsettings - > { 'monattrs' } - > { $ temptab } - > { $ tempcol } - > { 'val' } ;
my $ matchtype = $ monsettings - > { 'monattrs' } - > { $ temptab } - > { $ tempcol } - > { 'matchtype' } ;
#regular expression
if ( $ matchtype eq 'match' ) {
if ( $ currentstatus ne $ expectedstatus ) {
$ statusmatch = 0 ;
}
} elsif ( $ matchtype eq 'regex' ) {
if ( $ currentstatus !~ /$expectedstatus/ ) {
$ statusmatch = 0 ;
}
}
} #end foreach
} #end foreach
if ( $ statusmatch == 1 ) {
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "$node: Reached the expected status" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
delete $ monsettings - > { 'nodes' } - > { $ node } ;
}
} #end foreach my $node
} #end while
if ( scalar ( keys % { $ monsettings - > { 'nodes' } } ) > 0 )
{
foreach my $ n ( keys % { $ monsettings - > { 'nodes' } } ) {
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "$n: does not transit to the expected status" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
}
}
return $ monsettings ;
}
2009-07-07 02:07:30 +00:00
#-------------------------------------------------------------------------------
= head3 get_subnet_aix
Description:
To get present subnet configuration by parsing the output of 'netstat' . Only designed for AIX .
Arguments:
None
Returns:
@ aix_nrn : An array with entries in format "net:nic:netmask:flag" . Following is an example entry:
9.114 .47 .224 : en0:27:U
Globals:
none
Error:
none
Example:
my @ nrn = xCAT::Utils:: get_subnet_aix
Comments:
none
= cut
#-------------------------------------------------------------------------------
sub get_subnet_aix
{
my @ netstat_res = `/usr/bin/netstat -rn` ;
chomp @ netstat_res ;
my @ aix_nrn ;
for my $ entry ( @ netstat_res )
{
#We need to find entries like:
#Destination Gateway Flags Refs Use If Exp Groups
#9.114.47.192/27 9.114.47.205 U 1 1 en0
2010-05-12 01:45:48 +00:00
#4000::/64 link#4 UCX 1 0 en2 - -
my ( $ net , $ netmask , $ flag , $ nic ) ;
2009-07-07 02:07:30 +00:00
if ( $ entry =~ /^\s*([\d\.]+)\/(\d+)\s+[\d\.]+\s+(\w+)\s+\d+\s+\d+\s(\w+)/ )
{
2010-05-12 01:45:48 +00:00
( $ net , $ netmask , $ flag , $ nic ) = ( $ 1 , $ 2 , $ 3 , $ 4 ) ;
2009-07-07 02:07:30 +00:00
my @ dotsec = split /\./ , $ net ;
for ( my $ i = 4 ; $ i > scalar ( @ dotsec ) ; $ i - - )
{
$ net . = '.0' ;
}
push @ aix_nrn , "$net:$nic:$netmask:$flag" if ( $ net ne '127.0.0.0' ) ;
}
2010-05-12 01:45:48 +00:00
elsif ( $ entry =~ /^\s*([\dA-Fa-f\:]+)\/(\d+)\s+.*?\s+(\w+)\s+\d+\s+\d+\s(\w+)/ )
{
#print "=====$entry====\n";
( $ net , $ netmask , $ flag , $ nic ) = ( $ 1 , $ 2 , $ 3 , $ 4 ) ;
# for ipv6, can not use : as the delimiter
push @ aix_nrn , "$net-$nic-$netmask-$flag" if ( $ net ne '::' )
}
2009-07-07 02:07:30 +00:00
}
return @ aix_nrn ;
}
2009-07-23 20:02:39 +00:00
#-------------------------------------------------------------------------------
= head3 isIpaddr
returns 1 if parameter is has a valid IP address form .
Arguments:
dot qulaified IP address: e . g . 1.2 .3 .4
Returns:
1 - if legal IP address
0 - if not legal IP address .
Globals:
none
Error:
none
Example:
if ( $ ipAddr ) { blah ; }
Comments:
Doesn ' t test if the IP address is on the network ,
just tests its form .
= cut
#-------------------------------------------------------------------------------
sub isIpaddr
{
my $ addr = shift ;
2011-01-18 08:00:48 +00:00
if ( ( $ addr ) && ( $ addr =~ /xCAT::Utils/ ) )
{
$ addr = shift ;
}
2009-07-23 20:02:39 +00:00
2011-06-27 08:52:56 +00:00
unless ( $ addr )
{
return 0 ;
}
2009-07-23 20:02:39 +00:00
#print "addr=$addr\n";
if ( $ addr !~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ )
{
return 0 ;
}
if ( $ 1 > 255 || $ 1 == 0 || $ 2 > 255 || $ 3 > 255 || $ 4 > 255 )
{
return 0 ;
}
else
{
return 1 ;
}
}
2009-07-27 15:28:11 +00:00
#-------------------------------------------------------------------------------
= head3 getNodeNetworkCfg
Description:
Get node network configuration , including "IP, hostname(the nodename),and netmask" by this node ' s name .
Arguments:
node: the nodename
Returns:
Return an array , which contains ( IP , hostname , gateway , netmask ' ) .
undef - Failed to get the network configuration info
Globals:
none
Error:
none
Example:
my ( $ ip , $ host , undef , $ mask ) = xCAT::Utils:: getNodeNetworkCfg ( 'node1' ) ;
Comments:
Presently gateway is always blank . Need to be improved .
= cut
#-------------------------------------------------------------------------------
sub getNodeNetworkCfg
{
my $ node = shift ;
my $ nets = xCAT::Utils:: my_nets ( ) ;
2010-05-12 02:39:41 +00:00
my $ ip = xCAT::NetworkUtils - > getipaddr ( $ node ) ;
2009-07-27 15:28:11 +00:00
my $ mask = undef ;
for my $ net ( keys %$ nets )
{
my $ netname ;
( $ netname , $ mask ) = split /\// , $ net ;
last if ( xCAT::Utils:: isInSameSubnet ( $ netname , $ ip , $ mask , 1 ) ) ;
}
return ( $ ip , $ node , undef , xCAT::Utils:: formatNetmask ( $ mask , 1 , 0 ) ) ;
}
2009-07-31 19:45:28 +00:00
#-------------------------------------------------------------------------------
= head3 get_unique_members
Description:
Return an array which have unique members
Arguments:
origarray: the original array to be treated
Returns:
Return an array , which contains unique members .
Globals:
none
Error:
none
Example:
my @ new_array = xCAT::Utils:: get_unique_members ( @ orig_array ) ;
Comments:
= cut
#-------------------------------------------------------------------------------
sub get_unique_members
{
my @ orig_array = @ _ ;
2009-07-31 21:11:48 +00:00
my % tmp_hash = ( ) ;
for my $ ent ( @ orig_array )
2009-07-31 19:45:28 +00:00
{
2009-07-31 21:11:48 +00:00
$ tmp_hash { $ ent } = 1 ;
2009-07-31 19:45:28 +00:00
}
return keys % tmp_hash ;
}
2009-08-05 11:43:46 +00:00
#-------------------------------------------------------------------------------
2009-12-10 02:19:40 +00:00
= head3 get_hdwr_ip
Description:
Get hardware ( CEC , BPA ) IP from the hosts table , and then /etc/ hosts .
Arguments:
node: the nodename ( cec , or bpa )
Returns:
Return the node IP
- 1 - Failed to get the IP .
Globals:
none
Error:
none
Example:
my $ ip = xCAT::Utils:: get_hdwr_ip ( 'node1' ) ;
Comments:
Used in FSPpower FSPflash , FSPinv .
= cut
#-------------------------------------------------------------------------------
sub get_hdwr_ip
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2009-12-10 02:19:40 +00:00
my $ node = shift ;
my $ ip = undef ;
my $ Rc = undef ;
2010-03-09 06:42:23 +00:00
my $ ip_tmp_res = xCAT::Utils:: toIP ( $ node ) ;
( $ Rc , $ ip ) = @$ ip_tmp_res ;
if ( $ Rc ) {
my $ hosttab = xCAT::Table - > new ( 'hosts' ) ;
if ( $ hosttab ) {
my $ node_ip_hash = $ hosttab - > getNodeAttribs ( $ node , [ qw( ip ) ] ) ;
$ ip = $ node_ip_hash - > { ip } ;
}
2009-12-10 02:19:40 +00:00
}
2010-03-09 06:42:23 +00:00
2009-12-10 02:19:40 +00:00
if ( ! $ ip ) {
2010-03-09 06:42:23 +00:00
return undef ;
2009-12-10 02:19:40 +00:00
}
return $ ip ;
}
#-------------------------------------------------------------------------------
2009-08-05 11:43:46 +00:00
= head3 updateEtcHosts
Description:
Add nodes and their IP addresses into /etc/ hosts .
Arguments:
$ host_ip: the hostname - IP pairs to be updated in /etc/ hosts
Returns:
1 : Succesfully . 0 : Failed .
Globals:
none
Error:
none
Example:
xCAT::Utils:: updateEtcHosts ( \ % node_to_be_updated )
Comments:
= cut
#-------------------------------------------------------------------------------
# Update /etc/hosts
##########################################################################
sub updateEtcHosts
{
2009-11-13 12:56:37 +00:00
my $ host = shift ;
my $ ip = shift ;
2009-08-05 11:43:46 +00:00
my $ fname = "/etc/hosts" ;
unless ( open ( HOSTS , "<$fname" ) ) {
return undef ;
}
my @ rawdata = <HOSTS> ;
my @ newdata = ( ) ;
close ( HOSTS ) ;
chomp @ rawdata ;
######################################
# Remove old entry
######################################
2009-11-13 12:56:37 +00:00
my $ updated = 0 ;
foreach my $ line ( @ rawdata ) {
if ( $ line =~ /^#/ or $ line =~ /^\s*$/ ) {
next ;
2009-08-05 11:43:46 +00:00
}
2009-11-13 12:56:37 +00:00
if ( $ line =~ /^\s*\Q$ip\E\s+(.*)$/ )
2009-08-05 11:43:46 +00:00
{
2009-11-13 12:56:37 +00:00
$ host = $ 1 ;
$ updated = 1 ;
last ;
2009-08-05 11:43:46 +00:00
}
}
2009-11-13 12:56:37 +00:00
if ( ! $ updated )
{
push @ rawdata , "$ip\t$host" ;
}
2009-08-05 11:43:46 +00:00
######################################
# Rewrite file
######################################
unless ( open ( HOSTS , ">$fname" ) ) {
return undef ;
}
for my $ line ( @ rawdata )
{
print HOSTS "$line\n" ;
}
close ( HOSTS ) ;
2009-11-13 12:56:37 +00:00
return [ $ host , $ ip ] ;
2009-08-05 11:43:46 +00:00
}
2010-01-19 18:48:23 +00:00
#-------------------------------------------------------------------------------
= head3 getDBName
Description:
Returns the current database ( SQLITE , DB2 , MYSQL , PG )
Arguments:
None
Returns:
Return string .
Globals:
none
Error:
none
Example:
2010-04-06 13:17:37 +00:00
my $ DBname = xCAT::Utils - > get_DBName ;
2010-01-19 18:48:23 +00:00
Comments:
= cut
#-------------------------------------------------------------------------------
sub get_DBName
{
my $ name = "SQLITE" ; # default
my $ xcatcfg ;
if ( - r "/etc/xcat/cfgloc" ) {
my $ cfgl ;
open ( $ cfgl , "<" , "/etc/xcat/cfgloc" ) ;
$ xcatcfg = <$cfgl> ;
close ( $ cfgl ) ;
if ( $ xcatcfg =~ /^mysql:/ ) {
$ name = "MYSQL"
} else {
if ( $ xcatcfg =~ /^DB2:/ ) {
$ name = "DB2"
} else {
if ( $ xcatcfg =~ /^Pg:/ ) {
$ name = "PG"
}
}
}
}
return $ name ;
}
2009-11-13 12:56:37 +00:00
2010-01-25 08:59:52 +00:00
#-------------------------------------------------------------------------------
= head3 full_path
Description:
Convert the relative path to full path .
Arguments:
relpath: relative path
cwdir: current working directory , use the cwd ( ) if not specified
Returns:
Return the full path
NULL - Failed to get the full path .
Globals:
none
Error:
none
Example:
my $ fp = xCAT::Utils:: full_path ( './test' , '/home/guest' ) ;
Comments:
= cut
#-------------------------------------------------------------------------------
sub full_path
{
my ( $ class , $ relpath , $ cwdir ) = @ _ ;
my $ fullpath ;
if ( ! $ cwdir ) { #cwdir is not specified
$ fullpath = Cwd:: abs_path ( $ relpath ) ;
} else {
$ fullpath = $ cwdir . "/$relpath" ;
}
return $ fullpath ;
}
2010-02-04 10:24:13 +00:00
2010-03-29 13:19:13 +00:00
#-------------------------------------------------------------------------------
= head3 isStateful
returns 1 if localHost is a Stateful install
Arguments:
none
Returns:
1 - localHost is Stateful
0 - localHost is not Stateful
Globals:
none
Error:
none
Example:
if ( xCAT::Utils - > isStateful ( ) ) { }
Comments:
none
= cut
2010-02-26 09:46:29 +00:00
2010-03-29 13:19:13 +00:00
#-------------------------------------------------------------------------------
sub isStateful
{
# check to see if / is a real directory
my $ dir = "\/" ;
my $ cmd = "df -P $dir " ;
my @ output = xCAT::Utils - > runcmd ( $ cmd , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 )
{ # error
xCAT::MsgUtils - > message ( "" , " Could not determine Stateful\n" ) ;
return 0 ;
}
foreach my $ line ( @ output )
{
my ( $ file_sys , $ blocks , $ used , $ avail , $ cap , $ mount_point ) =
split ( ' ' , $ line ) ;
$ mount_point =~ s/\s*//g ; # remove blanks
if ( $ mount_point eq $ dir ) {
if ( - e ( $ file_sys ) )
{
return 1 ;
} else {
return 0 ;
}
}
}
return 0 ;
}
2010-02-26 09:46:29 +00:00
2010-05-05 09:00:15 +00:00
#-----------------------------------------------------------------------------
= head3 setupAIXconserver
Set AIX conserver
= cut
#-------------------------------------------------------------------------------
= head3 setupAIXconserver
Description:
Set AIX conserver
Arguments:
$ verbose:
Returns:
Return result of the operation
Globals:
none
Error:
none
Example:
my $ res = xCAT::Utils:: setupAIXconserver ( $ verbose ) ;
Comments:
= cut
#-----------------------------------------------------------------------------
sub setupAIXconserver
{
my ( $ class , $ verbose ) = @ _ ;
my $ cmd ;
my $ outref ;
my $ msg ;
my $ rc = 0 ;
if ( ! - f "/usr/sbin/conserver" )
{
$ cmd = "ln -sf /opt/freeware/sbin/conserver /usr/sbin/conserver" ;
$ outref = xCAT::Utils - > runcmd ( "$cmd" , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
xCAT::MsgUtils - > message (
'E' ,
"Could not ln -sf /opt/freeware/sbin/conserver /usr/sbin/conserver."
) ;
}
else
{
$ msg = "ln -sf /opt/freeware/sbin/conserver /usr/sbin/conserver." ;
2010-05-14 07:41:43 +00:00
if ( $ verbose ) {
2010-05-05 09:00:15 +00:00
xCAT::MsgUtils - > message ( "I" , $ msg ) ;
}
}
}
if ( ! - f "/usr/bin/console" )
{
$ cmd = "ln -sf /opt/freeware/bin/console /usr/bin/console" ;
$ outref = xCAT::Utils - > runcmd ( "$cmd" , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
xCAT::MsgUtils - > message (
'E' ,
"Could not ln -sf /opt/freeware/bin/console /usr/bin/console."
) ;
}
else
{
$ msg = "ln -sf /opt/freeware/bin/console /usr/sbin/console." ;
2010-05-14 07:41:43 +00:00
if ( $ verbose ) {
2010-05-05 09:00:15 +00:00
xCAT::MsgUtils - > message ( "I" , $ msg ) ;
}
}
}
$ cmd = "lssrc -a | grep conserver >/dev/null 2>&1" ;
$ outref = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
$ cmd =
"mkssys -p /opt/freeware/sbin/conserver -s conserver -u 0 -S -n 15 -f 15 -a \"-o -O1 -C /etc/conserver.cf\"" ;
$ outref = xCAT::Utils - > runcmd ( "$cmd" , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
xCAT::MsgUtils - > message ( 'E' , "Could not add subsystem conserver." ) ;
}
else
{
xCAT::MsgUtils - > message ( 'I' , "Added subsystem conserver." ) ;
# Remove old setting
my $ rmitab_cmd = 'rmitab conserver > /dev/null 2>&1' ;
$ rc = system ( $ rmitab_cmd ) ;
# add to the /etc/inittab file
my $ mkitab_cmd =
'mkitab "conserver:2:once:/usr/bin/startsrc -s conserver > /dev/console 2>&1" > /dev/null 2>&1' ;
$ rc = system ( $ mkitab_cmd ) ; # may already be there no error check
}
}
else
{ # conserver already a service
# Remove old setting
my $ rmitab_cmd = 'rmitab conserver > /dev/null 2>&1' ;
$ rc = system ( $ rmitab_cmd ) ;
# make sure it is registered in /etc/inittab file
my $ mkitab_cmd =
'mkitab "conserver:2:once:/usr/bin/startsrc -s conserver > /dev/console 2>&1" > /dev/null 2>&1' ;
$ rc = system ( $ mkitab_cmd ) ; # may already be there no error check
}
# now make sure conserver is started
$ rc = xCAT::Utils - > startService ( "conserver" ) ;
return $ rc ;
}
2010-09-14 22:29:41 +00:00
#-------------------------------------------------------------------------------
= head3 setAppStatus
Description:
Set an AppStatus value for a specific application in the nodelist
appstatus attribute for a list of nodes
Arguments:
@ nodes
$ application
$ status
Returns:
Return result of call to setNodesAttribs
Globals:
none
Error:
none
Example:
xCAT::Utils:: setAppStatus ( \ @ nodes , $ application , $ status ) ;
Comments:
= cut
#-----------------------------------------------------------------------------
sub setAppStatus
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2010-09-14 22:29:41 +00:00
my ( $ class , $ nodes_ref , $ application , $ status ) = @ _ ;
my @ nodes = @$ nodes_ref ;
#get current local time to set in appstatustime attribute
my (
$ sec , $ min , $ hour , $ mday , $ mon ,
$ year , $ wday , $ yday , $ isdst
)
= localtime ( time ) ;
my $ currtime = sprintf ( "%02d-%02d-%04d %02d:%02d:%02d" ,
$ mon + 1 , $ mday , $ year + 1900 ,
$ hour , $ min , $ sec ) ;
my $ nltab = xCAT::Table - > new ( 'nodelist' ) ;
my $ nodeappstat = $ nltab - > getNodesAttribs ( \ @ nodes , [ 'appstatus' ] ) ;
my % new_nodeappstat ;
foreach my $ node ( keys %$ nodeappstat ) {
2011-09-02 15:34:27 +00:00
if ( $ node =~ /^\s*$/ ) { next ; } # Skip blank node names
2010-09-14 22:29:41 +00:00
my $ new_appstat = "" ;
my $ changed = 0 ;
# Search current appstatus and change if app entry exists
my $ cur_appstat = $ nodeappstat - > { $ node } - > [ 0 ] - > { appstatus } ;
if ( $ cur_appstat ) {
my @ appstatus_entries = split ( /,/ , $ cur_appstat ) ;
foreach my $ appstat ( @ appstatus_entries ) {
my ( $ app , $ stat ) = split ( /=/ , $ appstat ) ;
if ( $ app eq $ application ) {
$ new_appstat . = ",$app=$status" ;
$ changed = 1 ;
} else {
$ new_appstat . = ",$appstat" ;
}
}
}
# If no app entry exists, add it
if ( ! $ changed ) {
$ new_appstat . = ",$application=$status" ;
}
$ new_appstat =~ s/^,// ;
$ new_nodeappstat { $ node } - > { appstatus } = $ new_appstat ;
$ new_nodeappstat { $ node } - > { appstatustime } = $ currtime ;
}
return $ nltab - > setNodesAttribs ( \ % new_nodeappstat ) ;
}
#-------------------------------------------------------------------------------
= head3 getAppStatus
Description:
Get an AppStatus value for a specific application from the
nodelist appstatus attribute for a list of nodes
Arguments:
@ nodes
$ application
Returns:
a hashref of nodes set to application status value
Globals:
none
Error:
none
Example:
my $ appstatus = $ xCAT:: Utils:: getAppStatus ( \ @ nodes , $ application ) ;
my $ node1_status = $ appstatus - > { node1 } ;
Comments:
= cut
#-----------------------------------------------------------------------------
sub getAppStatus
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2010-09-14 22:29:41 +00:00
my ( $ class , $ nodes_ref , $ application ) = @ _ ;
my @ nodes = @$ nodes_ref ;
my $ nltab = xCAT::Table - > new ( 'nodelist' ) ;
my $ nodeappstat = $ nltab - > getNodesAttribs ( \ @ nodes , [ 'appstatus' ] ) ;
my $ ret_nodeappstat ;
foreach my $ node ( keys %$ nodeappstat ) {
my $ cur_appstat = $ nodeappstat - > { $ node } - > [ 0 ] - > { appstatus } ;
my $ found = 0 ;
if ( $ cur_appstat ) {
my @ appstatus_entries = split ( /,/ , $ cur_appstat ) ;
foreach my $ appstat ( @ appstatus_entries ) {
my ( $ app , $ stat ) = split ( /=/ , $ appstat ) ;
if ( $ app eq $ application ) {
$ ret_nodeappstat - > { $ node } = $ stat ;
$ found = 1 ;
}
}
}
# If no app entry exists, return empty
if ( ! $ found ) {
$ ret_nodeappstat - > { $ node } = "" ;
}
}
return $ ret_nodeappstat ;
}
2010-11-02 11:58:45 +00:00
#-------------------------------------------------------------------------------
= head3 enableSSH
Description:
Reads the site . sshbetweennodes attribute and determines
if the input node should be enabled to ssh between nodes
Arguments:
$ node
Returns:
1 = enable ssh
0 = do not enable ssh
Globals:
none
Error:
none
Example:
my $ eable = $ xCAT:: Utils:: enablessh ( $ node ) ;
Comments:
= cut
#-----------------------------------------------------------------------------
sub enablessh
{
2011-04-01 14:02:44 +00:00
require xCAT::Table ;
2010-11-02 11:58:45 +00:00
my ( $ class , $ node ) = @ _ ;
my $ enablessh = 1 ;
if ( xCAT::Utils - > isSN ( $ node ) )
{
$ enablessh = 1 ; # service nodes always enabled
}
else
{
# if not a service node we need to check, before enabling
my $ sitetab = xCAT::Table - > new ( 'site' ) ;
my $ attr = "sshbetweennodes" ;
my $ ref = $ sitetab - > getAttribs ( { key = > $ attr } , 'value' ) ;
if ( $ ref )
{
my $ values = $ ref - > { value } ;
my @ groups = split ( /,/ , $ values ) ;
if ( grep ( /^ALLGROUPS$/ , @ groups ) )
{
$ enablessh = 1 ;
}
else
{
if ( grep ( /^NOGROUPS$/ , @ groups ) )
{
$ enablessh = 0 ;
}
else
{ # check to see if the node is a member of a group
my $ ismember = 0 ;
foreach my $ group ( @ groups )
{
$ ismember = xCAT::Utils - > isMemberofGroup ( $ node , $ group ) ;
if ( $ ismember == 1 )
{
last ;
}
}
if ( $ ismember == 1 )
{
$ enablessh = 1 ;
}
else
{
$ enablessh = 0 ;
}
}
}
}
else
{ # does not exist, set default
$ enablessh = 1 ;
}
}
return $ enablessh ;
2011-07-28 17:01:37 +00:00
}
2010-09-14 22:29:41 +00:00
2011-08-22 11:50:44 +00:00
#-------------------------------------------------------------------------------
= head3 isSELINUX
Returns:
returns 0 if SELINUX is enabled
returns 1 if SELINUX is not enabled
Globals:
none
Error:
none
Example:
if ( xCAT::Utils - > isSELINUX ( ) ) { blah ; }
Comments:
This is tested on Redhat , may need more for SLES
= cut
#-------------------------------------------------------------------------------
sub isSELINUX
{
if ( - e "/usr/sbin/selinuxenabled" ) {
`/usr/sbin/selinuxenabled` ;
if ( $? == 0 ) {
return 0 ;
} else {
return 1 ;
}
} else {
return 1 ;
}
}
#-------------------------------------------------------------------------------
2010-08-02 08:11:46 +00:00
2012-02-10 20:19:54 +00:00
#--------------------------------------------------------------------------------
= head3 pingNodeStatus
This function takes an array of nodes and returns their status using fping .
Arguments:
nodes - - an array of nodes .
Returns:
a hash that has the node status . The format is:
{ alive = > [ node1 , node3 , ... ] , unreachable = > [ node4 , node2 ... ] }
= cut
#--------------------------------------------------------------------------------
sub pingNodeStatus {
my ( $ class , @ mon_nodes ) = @ _ ;
my % status = ( ) ;
my @ active_nodes = ( ) ;
my @ inactive_nodes = ( ) ;
if ( ( @ mon_nodes ) && ( @ mon_nodes > 0 ) ) {
#get all the active nodes
my $ nodes = join ( ' ' , @ mon_nodes ) ;
my $ temp = `fping -a $nodes 2> /dev/null` ;
chomp ( $ temp ) ;
@ active_nodes = split ( /\n/ , $ temp ) ;
#get all the inactive nodes by substracting the active nodes from all.
my % temp2 ;
if ( ( @ active_nodes ) && ( @ active_nodes > 0 ) ) {
foreach ( @ active_nodes ) { $ temp2 { $ _ } = 1 } ;
foreach ( @ mon_nodes ) {
if ( ! $ temp2 { $ _ } ) { push ( @ inactive_nodes , $ _ ) ; }
}
}
else { @ inactive_nodes = @ mon_nodes ; }
}
$ status { $ ::STATUS_ACTIVE } = \ @ active_nodes ;
$ status { $ ::STATUS_INACTIVE } = \ @ inactive_nodes ;
return % status ;
}
2007-12-20 19:02:45 +00:00
1 ;