2008-06-24 16:22:55 +00:00
#!/usr/bin/env perl -w
2007-12-12 19:16:31 +00:00
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#####################################################
#
# xCAT plugin package to handle the xcat2nim command.
#
#####################################################
package xCAT_plugin::xcat2nim ;
2010-01-27 15:03:27 +00:00
BEGIN
{
$ ::XCATROOT = $ ENV { 'XCATROOT' } ? $ ENV { 'XCATROOT' } : '/opt/xcat' ;
}
use lib "$::XCATROOT/lib/perl" ;
2008-09-24 18:14:11 +00:00
use Sys::Hostname ;
2007-12-12 19:16:31 +00:00
use xCAT::NodeRange ;
use xCAT::Schema ;
use xCAT::Utils ;
use xCAT::DBobjUtils ;
use Data::Dumper ;
use Getopt::Long ;
use xCAT::MsgUtils ;
2009-03-15 21:47:38 +00:00
use Socket ;
2007-12-12 19:16:31 +00:00
# options can be bundled up like -vV
Getopt::Long:: Configure ( "bundling" ) ;
$ Getopt:: Long:: ignorecase = 0 ;
#------------------------------------------------------------------------------
= head1 xcat2nim
This program module file supports the xcat2nim command .
= cut
#------------------------------------------------------------------------------
= head2 xCAT xcat2nim command
= cut
#------------------------------------------------------------------------------
#----------------------------------------------------------------------------
= head3 handled_commands
Return a list of commands handled by this plugin
= cut
#-----------------------------------------------------------------------------
sub handled_commands
{
return {
xcat2nim = > "xcat2nim"
} ;
}
2008-09-10 15:51:29 +00:00
#-------------------------------------------------------
= head3 preprocess_request
Check and setup for hierarchy
= cut
#-------------------------------------------------------
sub preprocess_request
{
my $ req = shift ;
my $ cb = shift ;
my % sn ;
2010-01-27 15:03:27 +00:00
2010-02-05 16:02:23 +00:00
# need for runcmd output
$ ::CALLBACK = $ cb ;
2010-01-27 15:03:27 +00:00
#exit if preprocessed
2009-07-15 15:35:05 +00:00
if ( $ req - > { _xcatpreprocessed } - > [ 0 ] == 1 ) { return [ $ req ] ; }
2010-01-27 15:03:27 +00:00
2008-09-24 18:14:11 +00:00
my $ nodes = $ req - > { node } ; # this may not be the list of nodes we need!
my $ command = $ req - > { command } - > [ 0 ] ;
$ ::args = $ req - > { arg } ;
2008-09-10 15:51:29 +00:00
my $ service = "xcat" ;
my @ requests ;
2008-09-24 18:14:11 +00:00
if ( $ command =~ /xcat2nim/ ) {
# handle -h etc.
# list of nodes could be derived multiple ways!!
2010-01-27 15:03:27 +00:00
my ( $ ret , $ mynodes , $ servnodes ) = & prexcat2nim ( $ cb ) ;
2008-09-24 18:14:11 +00:00
if ( $ ret ) { # either error or -h was processed etc.
my $ rsp ;
if ( $ ret eq "1" ) {
$ rsp - > { errorcode } - > [ 0 ] = $ ret ;
push @ { $ rsp - > { data } } , "Return=$ret." ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ cb , $ ret ) ;
}
return undef ;
2010-01-27 15:03:27 +00:00
} elsif ( scalar ( @ { $ mynodes } ) ) {
# set up the requests to go to the service nodes
# - for the nodes that were provided
# - to handle node and group objects
my $ sn ;
$ sn = xCAT::Utils - > get_ServiceNode ( $ mynodes , $ service , "MN" ) ;
foreach my $ snkey ( keys %$ sn ) {
my $ reqcopy = { %$ req } ;
$ reqcopy - > { node } = $ sn - > { $ snkey } ;
$ reqcopy - > { '_xcatdest' } = $ snkey ;
$ reqcopy - > { _xcatpreprocessed } - > [ 0 ] = 1 ;
push @ requests , $ reqcopy ;
}
return \ @ requests ;
} elsif ( scalar ( @ { $ servnodes } ) ) {
# set up the requests to go to the service nodes
# for network objects
foreach my $ sn ( @ { $ servnodes } ) {
my $ reqcopy = { %$ req } ;
$ reqcopy - > { '_xcatdest' } = $ sn ;
$ reqcopy - > { _xcatpreprocessed } - > [ 0 ] = 1 ;
push @ requests , $ reqcopy ;
2008-09-24 18:14:11 +00:00
}
2010-01-27 15:03:27 +00:00
return \ @ requests ;
2008-09-24 18:14:11 +00:00
}
}
2010-01-27 15:03:27 +00:00
return undef ;
2008-09-10 15:51:29 +00:00
}
2007-12-12 19:16:31 +00:00
#----------------------------------------------------------------------------
= head3 process_request
Check for xCAT command and call the appropriate subroutine .
Returns:
0 - OK
1 - error
= cut
#-----------------------------------------------------------------------------
sub process_request
{
$ ::request = shift ;
2008-09-24 18:14:11 +00:00
my $ callback = shift ;
2007-12-12 19:16:31 +00:00
2010-02-05 16:02:23 +00:00
# need for runcmd output
$ ::CALLBACK = $ callback ;
2007-12-12 19:16:31 +00:00
my $ ret ;
my $ msg ;
2008-06-24 16:22:55 +00:00
my $ rsp ;
2007-12-12 19:16:31 +00:00
# globals used by all subroutines.
$ ::args = $ ::request - > { arg } ;
2008-09-24 18:14:11 +00:00
( $ ret , $ msg ) = & x2n ( $ callback ) ;
if ( $ ret > 0 ) {
my $ rsp ;
$ rsp - > { errorcode } - > [ 0 ] = $ ret ;
push @ { $ rsp - > { data } } , "Return=$ret." ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback , $ ret ) ;
}
return 0 ;
}
#----------------------------------------------------------------------------
= head3 prexcat2nim
Preprocessing for the xcat2nim command .
Arguments:
Returns:
0 - OK - needs further processing
1 - error - done processing this cmd
2 - help or version - done processing this cmd
Comments:
= cut
#-----------------------------------------------------------------------------
sub prexcat2nim
{
my $ callback = shift ;
2010-01-27 15:03:27 +00:00
my @ nodelist = ( ) ; # pass back list of nodes - if applicable
my @ servicenodes = ( ) ; # pass back list of service nodes - if applicable
2008-09-24 18:14:11 +00:00
if ( defined ( @ { $ ::args } ) ) {
@ ARGV = @ { $ ::args } ;
} else {
2010-01-27 15:03:27 +00:00
& xcat2nim_usage ( $ callback ) ;
2008-09-24 18:14:11 +00:00
return 1 ;
}
Getopt::Long:: Configure ( "no_pass_through" ) ;
if (
! GetOptions (
'all|a' = > \ $ ::opt_a ,
'f|force' = > \ $ ::FORCE ,
'help|h|?' = > \ $ ::opt_h ,
'list|l' = > \ $ ::opt_l ,
'update|u' = > \ $ ::opt_u ,
'remove|r' = > \ $ ::opt_r ,
2010-01-27 15:03:27 +00:00
'managementnode|M' = > \ $ ::MN ,
2008-09-24 18:14:11 +00:00
'o=s' = > \ $ ::opt_o ,
't=s' = > \ $ ::opt_t ,
2010-01-27 15:03:27 +00:00
's=s' = > \ $ ::SERVERS ,
2008-09-24 18:14:11 +00:00
'verbose|V' = > \ $ ::opt_V ,
'version|v' = > \ $ ::opt_v ,
)
)
{
2010-01-27 15:03:27 +00:00
& xcat2nim_usage ( $ callback ) ;
2008-09-24 18:14:11 +00:00
return 1 ;
}
# Option -h for Help
if ( $ ::opt_h )
2007-12-12 19:16:31 +00:00
{
2010-01-27 15:03:27 +00:00
& xcat2nim_usage ( $ callback ) ;
2008-09-24 18:14:11 +00:00
return 2 ;
2007-12-12 19:16:31 +00:00
}
2008-09-24 18:14:11 +00:00
2010-01-27 15:03:27 +00:00
# Option -v for version
2008-09-24 18:14:11 +00:00
if ( $ ::opt_v )
{
my $ rsp ;
my $ version = xCAT::Utils - > Version ( ) ;
$ rsp - > { data } - > [ 0 ] = "xcat2nim - $version" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
return 2 ; # - just exit
}
# process the command line
2010-01-27 15:03:27 +00:00
my $ rc = & processArgs ( $ callback ) ;
2008-09-24 18:14:11 +00:00
2010-01-27 15:03:27 +00:00
# figure out what nodes are involved - if any
# - so we can send the request to the correct service nodes
2008-09-24 18:14:11 +00:00
my % objhash = xCAT::DBobjUtils - > getobjdefs ( \ % ::objtype ) ;
2010-01-27 15:03:27 +00:00
my $ donet = 0 ;
2008-09-24 18:14:11 +00:00
foreach my $ o ( @ ::clobjnames ) {
if ( $ ::objtype { $ o } eq 'node' ) {
push ( @ nodelist , $ o ) ;
2010-01-27 15:03:27 +00:00
}
2008-09-24 18:14:11 +00:00
if ( $ ::objtype { $ o } eq 'group' ) {
my $ memberlist = xCAT::DBobjUtils - > getGroupMembers ( $ o , \ % objhash ) ;
my @ members = split ( ',' , $ memberlist ) ;
if ( @ members ) {
foreach my $ n ( @ members ) {
push ( @ nodelist , $ n ) ;
}
}
}
2010-01-27 15:03:27 +00:00
if ( $ ::objtype { $ o } eq 'network' ) {
if ( $ ::FORCE || $ ::opt_u || $ ::opt_r ) {
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "The -f, -r and -u options are not supported for network objects.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
& xcat2nim_usage ( $ callback ) ;
return 2 ;
}
$ donet = 1 ;
}
2008-03-07 20:37:33 +00:00
}
2008-09-24 18:14:11 +00:00
2010-01-27 15:03:27 +00:00
# NIM network defs need to be created on the NIM primary
my $ nimprime = xCAT::InstUtils - > getnimprime ( ) ;
chomp $ nimprime ;
@ servicenodes = ( $ nimprime ) ;
if ( 0 ) { # only do networks on the management node (NIM primary) for now
if ( $ donet ) {
if ( $ ::MN ) {
# only do management node
@ servicenodes = ( "$nimprime" ) ;
} elsif ( $ ::SERVERS ) {
@ servicenodes = split ( ',' , $ ::SERVERS ) ;
} else {
# do MN and all servers
@ servicenodes = xCAT::Utils - > getAllSN ( ) ;
push ( @ servicenodes , $ nimprime ) ;
}
}
if ( scalar ( @ nodelist ) ) {
# make sure the nodes are resolvable
# - if not then exit
foreach my $ n ( @ nodelist ) {
my $ packed_ip = gethostbyname ( $ n ) ;
if ( ! $ packed_ip ) {
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Could not resolve node $n.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
}
}
}
2008-09-24 18:14:11 +00:00
2010-01-27 15:03:27 +00:00
return ( 0 , \ @ nodelist , \ @ servicenodes ) ;
2007-12-12 19:16:31 +00:00
}
#----------------------------------------------------------------------------
= head3 processArgs
Process the command line .
Also - Process any input files provided on cmd line .
Arguments:
Returns:
0 - OK
1 - just print usage
2 - error
Globals:
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
sub processArgs
{
2010-01-27 15:03:27 +00:00
my $ callback = shift ;
2007-12-12 19:16:31 +00:00
my $ gotattrs = 0 ;
2008-06-25 15:37:19 +00:00
if ( defined ( @ { $ ::args } ) ) {
@ ARGV = @ { $ ::args } ;
} else {
return 3 ;
}
2007-12-12 19:16:31 +00:00
2008-06-24 16:22:55 +00:00
my % ObjTypeHash ;
2010-01-27 15:03:27 +00:00
@ ::clobjnames = ( ) ;
@ ::clobjtypes = ( ) ;
2008-06-24 16:22:55 +00:00
2007-12-12 19:16:31 +00:00
# parse the options
2008-03-07 20:37:33 +00:00
Getopt::Long:: Configure ( "no_pass_through" ) ;
2007-12-12 19:16:31 +00:00
if (
! GetOptions (
'all|a' = > \ $ ::opt_a ,
2008-06-25 14:42:23 +00:00
'f|force' = > \ $ ::FORCE ,
2008-02-21 19:17:18 +00:00
'help|h|?' = > \ $ ::opt_h ,
2008-02-18 20:12:15 +00:00
'list|l' = > \ $ ::opt_l ,
'update|u' = > \ $ ::opt_u ,
'remove|r' = > \ $ ::opt_r ,
2010-01-27 15:03:27 +00:00
'managementnode|M' = > \ $ ::MN ,
2007-12-12 19:16:31 +00:00
'o=s' = > \ $ ::opt_o ,
2010-01-27 15:03:27 +00:00
's=s' = > \ $ ::SERVERS ,
2007-12-12 19:16:31 +00:00
't=s' = > \ $ ::opt_t ,
'verbose|V' = > \ $ ::opt_V ,
'version|v' = > \ $ ::opt_v ,
)
)
{
# return 2;
}
# can get object names in many ways - easier to keep track
$ ::objectsfrom_args = 0 ;
$ ::objectsfrom_opto = 0 ;
$ ::objectsfrom_optt = 0 ;
$ ::objectsfrom_opta = 0 ;
#
# process @ARGV
#
# - put attr=val operands in ATTRS hash
while ( my $ a = shift ( @ ARGV ) )
{
if ( ! ( $ a =~ /=/ ) )
{
# the first arg could be a noderange or a list of args
if ( ( $ ::opt_t ) && ( $ ::opt_t ne 'node' ) )
{
# if we know the type isn't "node" then set the object list
@ ::clobjnames = split ( ',' , $ a ) ;
$ ::objectsfrom_args = 1 ;
}
elsif ( ! $ ::opt_t || ( $ ::opt_t eq 'node' ) )
{
# if the type was not provided or it is "node"
# then set noderange
@ ::noderange = & noderange ( $ a , 0 ) ;
@ ::clobjnames = @ ::noderange ;
$ ::objectsfrom_args = 1 ;
}
}
else
{
# if it has an "=" sign its an attr=val - we hope
# - this will handle "attr= "
my ( $ attr , $ value ) = $ a =~ /^\s*(\S+?)\s*=\s*(\S*.*)$/ ;
if ( ! defined ( $ attr ) || ! defined ( $ value ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Incorrect \'attr=val\' pair - $a\n" ;
2010-01-27 15:03:27 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
2007-12-12 19:16:31 +00:00
return 3 ;
}
$ gotattrs = 1 ;
# put attr=val in hash
$ ::ATTRS { $ attr } = $ value ;
}
}
# Option -V for verbose output
if ( defined ( $ ::opt_V ) )
{
$ ::verbose = 1 ;
$ ::VERBOSE = 1 ;
}
#
# determine the object types
#
# could have comma seperated list of types
if ( $ ::opt_t )
{
my @ tmptypes ;
if ( $ ::opt_t =~ /,/ )
{
# can't have mult types when using attr=val
if ( $ gotattrs )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
2010-01-27 15:03:27 +00:00
"Cannot combine multiple types with \'att=val\' pairs on the command line.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
2007-12-12 19:16:31 +00:00
return 3 ;
}
else
{
@ tmptypes = split ( ',' , $ ::opt_t ) ;
}
}
else
{
push ( @ tmptypes , $ ::opt_t ) ;
}
# check for valid types
my @ xdeftypes ;
foreach my $ k ( keys % { xCAT::Schema:: defspec } )
{
push ( @ xdeftypes , $ k ) ;
}
foreach my $ t ( @ tmptypes )
{
if ( ! grep ( /$t/ , @ xdeftypes ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
2008-09-24 18:14:11 +00:00
"$::msgstr Type \'$t\' is not a valid xCAT object type.\n" ;
2007-12-12 19:16:31 +00:00
$ rsp - > { data } - > [ 1 ] = "Skipping to the next type.\n" ;
2010-01-27 15:03:27 +00:00
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
2007-12-12 19:16:31 +00:00
}
else
{
chomp $ t ;
push ( @ ::clobjtypes , $ t ) ;
}
}
}
# must have object type(s) - default if not provided
if ( ! @ ::clobjtypes && ! $ ::opt_a )
{
# make the default type = 'node' if not specified
push ( @ ::clobjtypes , 'node' ) ;
2010-01-27 15:03:27 +00:00
#my $rsp;
#$rsp->{data}->[0] = "Assuming an object type of \'node\'.\n";
#xCAT::MsgUtils->message("I", $rsp, $callback);
2007-12-12 19:16:31 +00:00
}
#
# determine the object names
#
# - get object names from the -o option or the noderange
2010-01-27 15:03:27 +00:00
# - this assumes the noderange was not provided as an arg!!!
2007-12-12 19:16:31 +00:00
if ( $ ::opt_o )
{
$ ::objectsfrom_opto = 1 ;
# make a list
if ( $ ::opt_o =~ /,/ )
{
@ ::clobjnames = split ( ',' , $ ::opt_o ) ;
}
else
{
push ( @ ::clobjnames , $ ::opt_o ) ;
}
2010-01-27 15:03:27 +00:00
if ( ! $ ::opt_t || ( $ ::opt_t eq 'node' ) ) {
# if the type is "node"
@ ::noderange = & noderange ( $ ::opt_o , 0 ) ;
@ ::clobjnames = @ ::noderange ;
}
2007-12-12 19:16:31 +00:00
}
# if there is no opt_o & no noderange then try to find all the objects
# of the given types.
if ( $ ::opt_t
&& ! ( $ ::opt_o
|| $ ::opt_a
|| @ ::noderange
|| @ ::clobjnames ) )
{
my @ tmplist ;
$ ::objectsfrom_optt = 1 ;
# could have multiple type
foreach my $ t ( @ ::clobjtypes )
{
# look up all objects of this type in the DB ???
@ tmplist = xCAT::DBobjUtils - > getObjectsOfType ( $ t ) ;
unless ( @ tmplist )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
2010-01-27 15:03:27 +00:00
"Could not get objects of type \'$t\'.\n" ;
2007-12-12 19:16:31 +00:00
$ rsp - > { data } - > [ 1 ] = "Skipping to the next type.\n" ;
2010-01-27 15:03:27 +00:00
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
2007-12-12 19:16:31 +00:00
next ;
}
# add objname and type to hash and global list
foreach my $ o ( @ tmplist )
{
push ( @ ::clobjnames , $ o ) ;
$ ObjTypeHash { $ o } = $ t ;
}
}
}
# can't have -a with other obj sources
if ( $ ::opt_a
&& ( $ ::opt_o || @ ::noderange ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
2010-01-27 15:03:27 +00:00
"Cannot use \'-a\' with \'-o\' or a noderange.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
2007-12-12 19:16:31 +00:00
return 3 ;
}
# if -a then get a list of all DB objects
2008-06-24 16:22:55 +00:00
my % AllObjTypeHash ;
2007-12-12 19:16:31 +00:00
if ( $ ::opt_a )
{
my @ tmplist ;
$ ::objectsfrom_opta = 1 ;
# for every type of data object get the list of defined objects
foreach my $ t ( keys % { xCAT::Schema:: defspec } )
{
2010-01-27 15:03:27 +00:00
if ( ( $ t eq 'node' ) || ( $ t eq 'group' ) || ( $ t eq 'network' ) ) {
2007-12-12 19:16:31 +00:00
my @ tmplist ;
@ tmplist = xCAT::DBobjUtils - > getObjectsOfType ( $ t ) ;
# add objname and type to hash and global list
if ( scalar ( @ tmplist ) > 0 )
{
foreach my $ o ( @ tmplist )
{
push ( @ ::clobjnames , $ o ) ;
$ AllObjTypeHash { $ o } = $ t ;
}
}
}
}
}
# must have object name(s) -
if ( ! @ ::clobjnames )
{
return 3 ;
}
# create hash with object names and types
foreach my $ o ( @ ::clobjnames )
{
if ( $ ::objectsfrom_opta ) {
# if the object names came from the "-a" option then
% ::objtype = % AllObjTypeHash ;
} elsif ( $ ::objectsfrom_optt ) {
# if the names came from the opt_t option
% ::objtype = % ObjTypeHash ;
} elsif ( $ ::objectsfrom_args || $ ::objectsfrom_opto ) {
# from the opt_o or as an argument
# - there can only be one type
2010-01-27 15:03:27 +00:00
$ ::objtype { $ o } = $ ::clobjtypes [ 0 ] ;
2007-12-12 19:16:31 +00:00
}
}
return 0 ;
}
#----------------------------------------------------------------------------
= head3 x2n
Support for the xcat2nim command .
Arguments:
Returns:
0 - OK
1 - error
Globals:
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
sub x2n
{
2008-06-25 14:42:23 +00:00
my $ callback = shift ;
2007-12-12 19:16:31 +00:00
my $ rc = 0 ;
my $ error = 0 ;
2010-01-27 15:03:27 +00:00
# get this systems name as known by xCAT management node
$ ::Sname = xCAT::InstUtils - > myxCATname ( ) ;
chomp $ ::Sname ;
2008-09-24 18:14:11 +00:00
2010-01-27 15:03:27 +00:00
$ ::msgstr = "$::Sname: " ;
2008-09-24 18:14:11 +00:00
2007-12-12 19:16:31 +00:00
# process the command line
2010-01-27 15:03:27 +00:00
$ rc = & processArgs ( $ callback ) ;
2007-12-12 19:16:31 +00:00
if ( $ rc != 0 )
{
# rc: 0 - ok, 1 - return, 2 - help, 3 - error
if ( $ rc != 1 )
{
2010-01-27 15:03:27 +00:00
& xcat2nim_usage ( $ callback ) ;
2007-12-12 19:16:31 +00:00
}
return ( $ rc - 1 ) ;
}
# get all the attrs for these definitions
% ::objhash = xCAT::DBobjUtils - > getobjdefs ( \ % ::objtype ) ;
if ( ! defined ( % ::objhash ) )
{
my $ rsp ;
2010-01-27 15:03:27 +00:00
$ rsp - > { data } - > [ 0 ] = "Could not get xCAT object definitions.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
2007-12-12 19:16:31 +00:00
return 1 ;
}
2010-01-27 15:03:27 +00:00
my @ nodes ;
my @ networks ;
my @ groups ;
foreach my $ obj ( keys % ::objhash ) {
if ( $ ::objtype { $ obj } eq 'node' ) {
push ( @ nodes , $ obj ) ;
} elsif ( $ ::objtype { $ obj } eq 'network' ) {
push ( @ networks , $ obj ) ;
} elsif ( $ ::objtype { $ obj } eq 'group' ) {
push ( @ groups , $ obj ) ;
}
}
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
# NIM machine definitions
if ( scalar ( @ nodes ) ) {
foreach my $ objname ( @ nodes ) {
if ( $ ::opt_l || $ ::opt_r ) {
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
if ( & rm_or_list_nim_object ( $ objname , $ ::objtype { $ objname } , $ callback ) ) {
# the routine failed
$ error + + ;
}
} else {
2008-09-24 18:14:11 +00:00
if ( mkclientdef ( $ objname , $ callback ) ) {
2010-01-27 15:03:27 +00:00
# could not create client definition
2008-09-24 18:14:11 +00:00
$ error + + ;
2010-01-27 15:03:27 +00:00
}
}
next ;
}
}
# NIM network definitions
if ( scalar ( @ networks ) ) {
if ( $ ::opt_l ) {
# list network def
if ( & listNIMnetwork ( $ callback , \ @ networks , \ % ::objhash ) ) {
# could not create client definition
$ error + + ;
}
} elsif ( $ ::opt_r ) {
# remove network def
#if (&rmNIMnetwork($callback, \@networks) ) {
# # could not create client definition
# $error++;
#}
my $ rsp ;
push @ { $ rsp - > { data } } , "$::msgstr The remove option is not supported for NIM network definitions.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
$ error + + ;
} else {
if ( & mkNIMnetwork ( $ callback , \ @ networks , \ % ::objhash ) ) {
# could not create client definition
$ error + + ;
2008-09-24 18:14:11 +00:00
}
2010-01-27 15:03:27 +00:00
}
}
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
# NIM group definitions
if ( scalar ( @ groups ) ) {
foreach my $ objname ( @ groups ) {
# make sure grouptype is set ???
$ ::objhash { $ objname } { 'grouptype' } = 'static' ;
my $ grptab = xCAT::Table - > new ( 'nodegroup' ) ;
#dynamic groups and static groups in nodegroup table
my @ grplist = @ { $ grptab - > getAllEntries ( ) } ;
foreach my $ grpdef_ref ( @ grplist ) {
my % grpdef = %$ grpdef_ref ;
if ( ( $ grpdef { 'groupname' } eq $ objname ) && ( $ grpdef { 'grouptype' } eq 'dynamic' ) ) {
$ ::objhash { $ objname } { 'grouptype' } = 'dynamic' ;
last ;
}
}
$ grptab - > close ;
if ( $ ::opt_l || $ ::opt_r ) {
if ( & rm_or_list_nim_object ( $ objname , $ ::objtype { $ objname } , $ callback ) ) {
# the routine failed
$ error + + ;
}
} else {
if ( & mkgrpdef ( $ objname , $ callback ) ) {
2008-09-24 18:14:11 +00:00
# could not create group definition
$ error + + ;
}
2007-12-12 19:16:31 +00:00
}
2010-01-27 15:03:27 +00:00
next ;
2008-02-18 20:12:15 +00:00
}
2010-01-27 15:03:27 +00:00
}
2007-12-12 19:16:31 +00:00
if ( $ error )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
2008-09-24 18:14:11 +00:00
"$::msgstr One or more errors occured.\n" ;
2010-01-27 15:03:27 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
2007-12-12 19:16:31 +00:00
return 1 ;
}
else
{
return 0 ;
}
2010-01-27 15:03:27 +00:00
return 0 ;
2007-12-12 19:16:31 +00:00
}
#----------------------------------------------------------------------------
= head3 mkclientdef
Create a NIM client definition .
Arguments:
Returns:
0 - OK
1 - error
Globals:
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
sub mkclientdef
{
2008-06-25 14:42:23 +00:00
my $ node = shift ;
my $ callback = shift ;
2007-12-12 19:16:31 +00:00
my $ cabletype = undef ;
my $ ifattr = undef ;
2008-06-24 16:22:55 +00:00
my % finalattrs ;
my $ shorthost ;
my $ net_name ;
my $ adaptertype ;
my $ nim_args ;
my $ nim_type ;
2008-09-24 18:14:11 +00:00
# this code runs on service nodes - which are NIM masters
2007-12-12 19:16:31 +00:00
# check to see if the client is already defined
# - sets $::client_exists
2010-01-27 15:03:27 +00:00
if ( & check_nim_client ( $ node , $ ::Sname , $ callback ) ) {
2007-12-12 19:16:31 +00:00
# the routine failed
return 1 ;
}
2008-06-25 14:42:23 +00:00
# need short host name for NIM client defs
( $ shorthost = $ node ) =~ s/\..*$// ;
2007-12-12 19:16:31 +00:00
# don't update an existing def unless they say so!
if ( $ ::client_exists && ! $ ::opt_u ) {
2008-06-25 14:42:23 +00:00
if ( $ ::FORCE ) {
# get rid of the old definition
my $ rmcmd = "/usr/sbin/nim -Fo reset $shorthost;/usr/sbin/nim -Fo deallocate -a subclass=all $shorthost;/usr/sbin/nim -Fo remove $shorthost" ;
my $ output = xCAT::Utils - > runcmd ( "$rmcmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
my $ rsp ;
2008-09-24 18:14:11 +00:00
push @ { $ rsp - > { data } } , "$::msgstr Could not remove the existing NIM object named \'$shorthost\'.\n" ;
2008-06-25 14:42:23 +00:00
if ( $ ::VERBOSE ) {
push @ { $ rsp - > { data } } , "$output" ;
}
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
} else { # no force
my $ rsp ;
2008-09-24 18:14:11 +00:00
$ rsp - > { data } - > [ 0 ] = "$::msgstr The NIM client machine \'$shorthost\' already exists. Use the \'-f\' option to remove and recreate or the \'-u\' option to update an existing definition.\n" ;
2010-01-27 15:03:27 +00:00
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
2008-06-25 14:42:23 +00:00
return 1 ;
}
}
# either create or update the def
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
# process the args and add defaults etc.
foreach my $ attr ( keys % ::ATTRS ) {
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
if ( $ attr =~ /^if/ ) {
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
$ ifattr = "-a $attr=\'$::ATTRS{$attr}\'" ;
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
} elsif ( $ attr =~ /^cable_type/ ) {
$ cabletype = "-a cable_type1=\'$::ATTRS{$attr}\'" ;
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
} else {
# add to
$ finalattrs { $ attr } = $ ::ATTRS { $ attr } ;
2007-12-12 19:16:31 +00:00
}
2008-06-25 14:42:23 +00:00
}
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
# req a value for cable_type
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
if ( ! $ cabletype ) {
$ cabletype = "-a cable_type1=N/A " ;
}
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
# req a value for "if1" interface def
if ( ! $ ifattr ) {
# then try to create the attr - required
if ( $ ::objhash { $ node } { 'netname' } ) {
$ net_name = $ ::objhash { $ node } { 'netname' } ;
} else {
$ net_name = "find_net" ;
}
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
# only support Ethernet for management interfaces
$ adaptertype = "ent" ;
2008-02-14 14:25:44 +00:00
2008-06-25 14:42:23 +00:00
if ( ! $ ::objhash { $ node } { 'mac' } )
{
my $ rsp ;
2009-03-27 15:45:35 +00:00
$ rsp - > { data } - > [ 0 ] = "$::msgstr Missing the MAC for node \'$node\'.\n" ;
2010-01-27 15:03:27 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
2009-03-27 15:45:35 +00:00
return 1 ;
} else {
$ ::objhash { $ node } { 'mac' } =~ s/://g ;
2007-12-12 19:16:31 +00:00
}
2008-06-25 14:42:23 +00:00
$ ifattr = "-a if1=\'$net_name $shorthost $::objhash{$node}{'mac'} $adaptertype\'" ;
}
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
# only support standalone for now - will get this from node def in future
$ nim_type = "-t standalone" ;
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
$ nim_args = "$ifattr " ;
$ nim_args . = "$cabletype" ;
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
# add the rest of the attr=val to the command line
foreach my $ a ( keys % finalattrs ) {
$ nim_args . = " -a $a=\'$finalattrs{$a}\'" ;
}
2008-02-14 14:25:44 +00:00
2008-06-25 14:42:23 +00:00
# put together the correct NIM command
my $ cmd ;
2008-02-14 14:25:44 +00:00
2008-06-25 14:42:23 +00:00
if ( $ ::client_exists && $ ::opt_u ) {
$ cmd = "nim -F -o change $nim_args $shorthost" ;
} else {
$ cmd = "nim -o define $nim_type $nim_args $shorthost" ;
}
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
my $ nimcmd ;
2008-09-24 18:14:11 +00:00
$ nimcmd = qq~$cmd 2>&1~ ;
2007-12-12 19:16:31 +00:00
2008-06-25 14:42:23 +00:00
# run the cmd
my $ output = xCAT::Utils - > runcmd ( "$nimcmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp ;
2008-09-24 18:14:11 +00:00
$ rsp - > { data } - > [ 0 ] = "$::msgstr Could not create a NIM definition for \'$node\'.\n" ;
2008-06-25 14:42:23 +00:00
if ( $ ::verbose )
{
$ rsp - > { data } - > [ 1 ] = "$output" ;
2007-12-12 19:16:31 +00:00
}
2010-01-27 15:03:27 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
2008-06-25 14:42:23 +00:00
return 1 ;
}
2007-12-12 19:16:31 +00:00
return 0 ;
}
#----------------------------------------------------------------------------
= head3 mkgrpdef
Create a NIM group definition .
Arguments:
Returns:
0 - OK
1 - error
Globals:
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
sub mkgrpdef
{
2008-06-25 14:42:23 +00:00
my $ group = shift ;
my $ callback = shift ;
2010-01-27 15:03:27 +00:00
# get members of xCAT group
my $ memberlist = xCAT::DBobjUtils - > getGroupMembers ( $ group , \ % ::objhash ) ;
my @ members = split ( ',' , $ memberlist ) ;
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
# get list of nim groups defined locally
$ cmd = qq~lsnim -c groups | cut -f1 -d' ' 2>/dev/null~ ;
my @ GroupList = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 )
2009-03-15 21:47:38 +00:00
{
2010-01-27 15:03:27 +00:00
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "$::msgstr Could not get a list of NIM group definitions.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
# get list of nim machine defined locally
$ mcmd = qq~lsnim -c machines | cut -f1 -d' ' 2>/dev/null~ ;
my @ nimnodes = xCAT::Utils - > runcmd ( "$mcmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = " $ ::msgstr Could not get a list of NIM group definit
ions . \ n " ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
2009-03-15 21:47:38 +00:00
2010-01-27 15:03:27 +00:00
# don't update an existing def unless we're told
if ( ( grep ( /$group/ , @ GroupList ) ) && ! $ ::opt_u ) {
if ( $ ::FORCE ) {
# get rid of the old definition
my $ rmcmd = "/usr/sbin/nim -Fo remove $group" ;
my $ output = xCAT::Utils - > runcmd ( "$rmcmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
2009-03-15 21:47:38 +00:00
my $ rsp ;
2010-01-27 15:03:27 +00:00
push @ { $ rsp - > { data } } , "$::msgstr Could not remove the existing NIM group named \'$group\'.\n" ;
if ( $ ::VERBOSE ) {
push @ { $ rsp - > { data } } , "$output" ;
}
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
2008-06-25 14:42:23 +00:00
return 1 ;
}
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
} else { # no force
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "$::msgstr The NIM group \'$group\' already exists. Use the \'-f\' option to remove and recreate or the \'-u\' option to update an existing definition.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
return 1 ;
}
}
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
# either create or update the group def on this master
2008-06-25 14:42:23 +00:00
2010-01-27 15:03:27 +00:00
# any list with more than 1024 members is an error
# - NIM can't handle that
if ( $# members > 1024 ) {
my $ rsp ;
2010-02-05 16:02:23 +00:00
$ rsp - > { data } - > [ 0 ] = "$::msgstr Cannot create a NIM group definition with more than 1024 members." ;
2010-01-27 15:03:27 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
next ;
}
2008-06-25 14:42:23 +00:00
2010-01-27 15:03:27 +00:00
#
# The list may become quite long and not fit on one cmd line
# so we do it one at a time for now - need to revisit this
# (like do blocks at a time) - TODO
#
my $ justadd = 0 ; # after the first define we just need to add
foreach my $ memb ( @ members ) {
# if this node is not defined locally then don't add it to the list
if ( ! grep ( /$memb/ , @ nimnodes ) ) {
next ;
}
my $ shorthost ;
( $ shorthost = $ memb ) =~ s/\..*$// ;
2008-06-25 14:42:23 +00:00
2010-01-27 15:03:27 +00:00
# do we change or create
my $ cmd ;
if ( ( ( grep ( /$group/ , @ GroupList ) ) && $ ::opt_u ) || $ justadd ) {
$ cmd = "nim -o change -a add_member=$shorthost $group 2>&1" ;
} else {
$ cmd = "nim -o define -t mac_group -a add_member=$shorthost $group 2>&1" ;
$ justadd + + ;
}
2009-03-15 21:47:38 +00:00
2010-01-27 15:03:27 +00:00
my $ output = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
2010-02-05 16:02:23 +00:00
2010-01-27 15:03:27 +00:00
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "$::msgstr Could not create a NIM definition for \'$group\'.\n" ;
if ( $ ::verbose )
{
$ rsp - > { data } - > [ 1 ] = "$output" ;
2007-12-12 19:16:31 +00:00
}
2010-01-27 15:03:27 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
2008-06-25 14:42:23 +00:00
}
2007-12-12 19:16:31 +00:00
}
return 0 ;
}
#----------------------------------------------------------------------------
= head3 rm_or_list_nim_object
List a NIM object definition .
2010-01-27 15:03:27 +00:00
Argument:
2007-12-12 19:16:31 +00:00
Returns:
0 - OK
1 - error
Globals:
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
sub rm_or_list_nim_object
{
2010-01-27 15:03:27 +00:00
my ( $ object , $ type , $ callback ) = @ _ ;
2007-12-12 19:16:31 +00:00
if ( $ type eq 'node' ) {
if ( $ ::opt_l ) {
2008-06-24 16:22:55 +00:00
my $ cmd ;
2008-09-24 18:14:11 +00:00
$ cmd = qq~lsnim -l $object 2>/dev/null~ ;
2010-01-27 15:03:27 +00:00
2008-02-20 20:50:44 +00:00
my $ outref = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
2007-12-12 19:16:31 +00:00
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp ;
2008-09-24 18:14:11 +00:00
$ rsp - > { data } - > [ 0 ] = "$::msgstr Could not get the NIM definition for $object.\n" ;
2008-02-20 20:50:44 +00:00
if ( $ ::verbose )
{
$ rsp - > { data } - > [ 1 ] = "$outref" ;
}
2010-01-27 15:03:27 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
2007-12-12 19:16:31 +00:00
return 1 ;
} else {
# display to NIM output
my $ rsp ;
2008-02-18 20:12:15 +00:00
$ rsp - > { data } - > [ 0 ] = "$outref" ;
2010-01-27 15:03:27 +00:00
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
2007-12-12 19:16:31 +00:00
return 0 ;
}
} elsif ( $ ::opt_r ) {
# remove the object
2008-06-24 16:22:55 +00:00
my $ cmd ;
2008-10-10 15:54:06 +00:00
if ( $ ::FORCE ) {
$ cmd = qq~nim -Fo reset $object;nim -Fo deallocate -a subclass=all $object;nim -Fo remove $object 2>/dev/null~ ;
} else {
2009-03-15 21:47:38 +00:00
$ cmd = qq~nim -Fo remove $object 2>/dev/null~ ;
2008-10-10 15:54:06 +00:00
}
2007-12-12 19:16:31 +00:00
2008-06-24 16:22:55 +00:00
my $ outref = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
2007-12-12 19:16:31 +00:00
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp ;
2008-09-24 18:14:11 +00:00
$ rsp - > { data } - > [ 0 ] = "$::msgstr Could not remove the NIM definition for \'$object\'.\n" ;
2008-02-20 20:50:44 +00:00
if ( $ ::verbose )
{
$ rsp - > { data } - > [ 1 ] = "$outref" ;
}
2010-01-27 15:03:27 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
2007-12-12 19:16:31 +00:00
return 1 ;
}
}
}
if ( $ type eq 'group' ) {
2010-01-27 15:03:27 +00:00
my $ cmd ;
if ( $ ::opt_l ) {
$ cmd = qq~lsnim -l $object 2>/dev/null~ ;
my $ outref = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "$::msgstr Could not list the NIM definition for \'$object\'.\n" ;
if ( $ ::verbose )
{
$ rsp - > { data } - > [ 1 ] = "$outref" ;
}
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
} else {
2009-03-15 21:47:38 +00:00
2010-01-27 15:03:27 +00:00
# display NIM output
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "$outref" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
return 0 ;
}
} elsif ( $ ::opt_r ) {
$ cmd = qq~nim -Fo remove $object 2>/dev/null~ ;
2009-03-15 21:47:38 +00:00
2010-01-27 15:03:27 +00:00
my $ outref = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "$::msgstr Could not remove the NIM definition for \'$object\'.\n" ;
if ( $ ::verbose )
{
$ rsp - > { data } - > [ 1 ] = "$outref" ;
2008-10-10 15:54:06 +00:00
}
2010-01-27 15:03:27 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
}
2008-10-10 15:54:06 +00:00
}
2007-12-12 19:16:31 +00:00
return 0 ;
}
#----------------------------------------------------------------------------
= head3 getNIMmaster
Get the name of the NIM master for a node .
Arguments:
Returns:
name
undef - error
Globals:
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
sub getNIMmaster
{
my ( $ node ) = @ _ ;
my $ NimMaster ;
my $ master = undef ;
# get the server name
if ( $ ::objhash { $ node } { nimmaster } ) {
$ NimMaster = $ ::objhash { $ node } { nimmaster } ;
} elsif ( $ ::objhash { $ node } { servicenode } ) {
# the servicenode attr is set for this node
$ NimMaster = $ ::objhash { $ node } { servicenode } ;
} elsif ( $ ::objhash { $ node } { xcatmaster } ) {
$ NimMaster = $ ::objhash { $ node } { xcatmaster } ;
} else {
2010-02-05 16:02:23 +00:00
my $ nimprime = xCAT::InstUtils - > getnimprime ( ) ;
chomp $ nimprime ;
$ NimMaster = $ nimprime ;
2007-12-12 19:16:31 +00:00
}
# assume short hostnames for now???
if ( $ NimMaster ) {
( $ master = $ NimMaster ) =~ s/\..*$// ;
}
return $ master ;
}
#----------------------------------------------------------------------------
2010-01-27 15:03:27 +00:00
= head3 check_nim_client
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
See if an xCAT node has already been defined as a NIM client .
2007-12-12 19:16:31 +00:00
Arguments:
Returns:
2010-01-27 15:03:27 +00:00
0 - OK
1 - error
2007-12-12 19:16:31 +00:00
Globals:
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
2010-01-27 15:03:27 +00:00
sub check_nim_client
2007-12-12 19:16:31 +00:00
{
2010-01-27 15:03:27 +00:00
my ( $ node , $ servnode , $ callback ) = @ _ ;
my ( $ cmd , @ ClientList ) ;
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
$ cmd = qq~lsnim -c machines | cut -f1 -d' ' 2>/dev/null~ ;
@ ClientList = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "$::msgstr Could not get a list of NIM client definitions from \'$servnode\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
2007-12-12 19:16:31 +00:00
}
2010-01-27 15:03:27 +00:00
$ ::client_exists = grep ( /^$node$/ , @ ClientList ) ? 1 : 0 ;
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
return 0 ;
}
2007-12-12 19:16:31 +00:00
#----------------------------------------------------------------------------
2010-01-27 15:03:27 +00:00
= head3 xcat2nim_usage
2007-12-12 19:16:31 +00:00
Arguments:
Returns:
Globals:
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
2010-01-27 15:03:27 +00:00
sub xcat2nim_usage
2007-12-12 19:16:31 +00:00
{
2010-01-27 15:03:27 +00:00
my $ callback = shift ;
my $ rsp ;
push @ { $ rsp - > { data } } , "\nUsage: xcat2nim - Use this command to create and manage AIX NIM definitions based on xCAT object definitions.\n" ;
push @ { $ rsp - > { data } } , " xcat2nim [-h|--help ]\n" ;
push @ { $ rsp - > { data } } , " xcat2nim [-V|--verbose] [-l|--list] [-r|--remove] [-u|--update]\n [-f|--force] [-t object-types] [-o object-names] [-a|--allobjects]\n [noderange] [attr=val [attr=val...]]\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
return 0 ;
}
#-------------------------------------------------------------------------------
= head3 mkNIMnetwork
Create NIM network definitions corresponding to xCAT network
definitions . This routine runs on the NIMprime and AIX SNs
Arguments:
Returns:
Comments:
ex . & mkNIMnetwork ( $ callback , \ @ networks , \ % nethash ) ;
= cut
#-------------------------------------------------------------------------------
sub mkNIMnetwork
{
my $ callback = shift ;
my $ xnets = shift ;
my $ xnhash = shift ;
2008-06-24 16:22:55 +00:00
2010-01-27 15:03:27 +00:00
my @ xnetworks = @ { $ xnets } ;
my % xnethash ; # hash of xCAT network definitions
if ( $ xnhash ) {
% xnethash = % { $ xnhash } ;
}
#
# get all the nim network names and attrs defined on this server
#
my $ cmd = qq~/usr/sbin/lsnim -c networks | /usr/bin/cut -f1 -d' ' 2>/dev/null~ ;
my @ networks = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
2008-04-22 13:17:31 +00:00
2010-01-27 15:03:27 +00:00
# for each NIM network - get the attrs
my % NIMnets ;
foreach my $ netwk ( @ networks ) {
my $ cmd = qq~/usr/sbin/lsnim -Z -a net_addr -a snm $netwk 2>/dev/null~ ;
my @ result = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
my $ rsp ;
push @ { $ rsp - > { data } } , "$::msgstr Could not run lsnim command: \'$cmd\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
foreach my $ l ( @ result ) {
# skip comment lines
next if ( $ l =~ /^\s*#/ ) ;
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
my ( $ nimname , $ net_addr , $ snm ) = split ( ':' , $ l ) ;
$ NIMnets { $ netwk } { 'net_addr' } = $ net_addr ;
$ NIMnets { $ netwk } { 'snm' } = $ snm ;
}
2007-12-12 19:16:31 +00:00
}
2010-01-27 15:03:27 +00:00
#
# for each xCAT network - see if the net we need is defined
#
foreach my $ net ( @ xnetworks ) {
# see if it's already defined - or equivalent is defined
# split mask
my ( $ nm1 , $ nm2 , $ nm3 , $ nm4 ) = split ( '\.' , $ xnethash { $ net } { mask } ) ;
# split net addr
my ( $ nn1 , $ nn2 , $ nn3 , $ nn4 ) = split ( '\.' , $ xnethash { $ net } { net } ) ;
# foreach nim network name
foreach my $ netwk ( @ networks ) {
# split definition mask
my ( $ dm1 , $ dm2 , $ dm3 , $ dm4 ) = split ( '\.' , $ NIMnets { $ netwk } { 'snm' } ) ;
# split definition net addr
my ( $ dn1 , $ dn2 , $ dn3 , $ dn4 ) = split ( '\.' , $ NIMnets { $ netwk } { 'net_addr' } ) ;
# check for the same netmask and network address
if ( ( $ nn1 == $ dn1 ) && ( $ nn2 == $ dn2 ) && ( $ nn3 == $ dn3 ) && ( $ nn4 == $ dn4 ) ) {
if ( ( $ nm1 == $ dm1 ) && ( $ nm2 == $ dm2 ) && ( $ nm3 == $ dm3 ) && ( $ nm4 == $ dm4 ) ) {
$ foundmatch = 1 ;
}
}
}
# if not defined then define it!
if ( ! $ foundmatch ) {
# create new nim network def
# use the same network name as xCAT uses
my $ cmd ;
$ cmd = qq~/usr/sbin/nim -o define -t ent -a net_addr=$xnethash{$net}{net} -a snm=$xnethash{$net}{mask} -a routing1='default $xnethash{$net}{gateway}' $net 2>/dev/null~ ;
my $ output1 = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
my $ rsp ;
push @ { $ rsp - > { data } } , "$::msgstr Could not run \'$cmd\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
#
# create an interface def (if*) for the master
#
# first get the if* and cable_type* attrs
# - the -A option gets the next avail index for this attr
my $ ifcmd = qq~/usr/sbin/lsnim -A if master 2>/dev/null~ ;
my $ ifindex = xCAT::Utils - > runcmd ( "$ifcmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
my $ rsp ;
push @ { $ rsp - > { data } } , "Could not run \'$ifcmd\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
my $ ctcmd = qq~/usr/sbin/lsnim -A cable_type master 2>/dev/null~ ;
my $ ctindex = xCAT::Utils - > runcmd ( "$ctcmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
my $ rsp ;
push @ { $ rsp - > { data } } , "$::msgstr Could not run \'$ctcmd\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
# get the local adapter hostname for this network
# get all the possible IPs for the node I'm running on
my $ ifgcmd = "ifconfig -a | grep 'inet '" ;
my @ result = xCAT::Utils - > runcmd ( $ ifgcmd , 0 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
my $ rsp ;
push @ { $ rsp - > { data } } , "$::msgstr Could not run \'$ifgcmd\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
my $ adapterhostname ;
foreach my $ int ( @ result ) {
my ( $ inet , $ myIP , $ str ) = split ( " " , $ int ) ;
chomp $ myIP ;
# split interface IP
my ( $ h1 , $ h2 , $ h3 , $ h4 ) = split ( '\.' , $ myIP ) ;
# split mask
my ( $ m1 , $ m2 , $ m3 , $ m4 ) = split ( '\.' , $ xnethash { $ net } { mask } ) ;
# split net address
my ( $ n1 , $ n2 , $ n3 , $ n4 ) = split ( '\.' , $ xnethash { $ net } { net } ) ;
# 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 ) ) ;
# if all the octals match the network addr then we have
# the right interface
if ( ( $ n1 == $ a1 ) && ( $ n2 == $ a2 ) && ( $ n3 == $ a3 ) && ( $ n4 == $ a4 ) ) {
my $ packedaddr = inet_aton ( $ myIP ) ;
$ adapterhostname = gethostbyaddr ( $ packedaddr , AF_INET ) ;
last ;
}
}
# define the new interface
my $ chcmd = qq~/usr/sbin/nim -o change -a if$ifindex='$net $adapterhostname 0' -a cable_type$ctindex=N/A master 2>/dev/null~ ;
my $ output2 = xCAT::Utils - > runcmd ( "$chcmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
my $ rsp ;
push @ { $ rsp - > { data } } , "$::msgstr Could not run \'$chcmd\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
# get the next index for the routing attr
my $ ncmd = qq~/usr/sbin/lsnim -A routing master_net 2>/dev/null~ ;
my $ rtindex = xCAT::Utils - > runcmd ( "$ncmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
my $ rsp ;
push @ { $ rsp - > { data } } , "$::msgstr Could not run \'$ncmd\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
# get hostname of primary int - always if1
my $ hncmd = qq~/usr/sbin/lsnim -a if1 -Z master 2>/dev/null~ ;
my @ ifone = xCAT::Utils - > runcmd ( "$hncmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
my $ rsp ;
push @ { $ rsp - > { data } } , "$::msgstr Could not run \'$hncmd\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
my ( $ junk1 , $ junk2 , $ adapterhost ) ;
foreach my $ l ( @ ifone ) {
# skip comment lines
next if ( $ l =~ /^\s*#/ ) ;
( $ junk1 , $ junk2 , $ adapterhost ) = split ( ':' , $ l ) ;
}
# get the ip of the nim primary interface
my $ gwIP = inet_ntoa ( inet_aton ( $ adapterhost ) ) ;
chomp $ gwIP ;
# create static routes between the networks
my $ rtgcmd = qq~/usr/sbin/nim -o change -a routing$rtindex='master_net $gwIP $xnethash{$net}{gateway}' $net 2>/dev/null~ ;
my $ output3 = xCAT::Utils - > runcmd ( "$rtgcmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
my $ rsp ;
push @ { $ rsp - > { data } } , "$::msgstr Could not run \'$rtgcmd\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
} # end - define new nim network
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
} # end - for each network
2007-12-12 19:16:31 +00:00
return 0 ;
}
2010-01-27 15:03:27 +00:00
#-------------------------------------------------------------------------------
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
= head3 listNIMnetwork
List NIM network definitions corresponding to xCAT network
definitions . This routine runs on the NIMprime and AIX SNs
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
Arguments:
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
Returns:
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
Comments:
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
ex . & listNIMnetwork ( $ callback , \ @ networks , \ % nethash ) ;
2007-12-12 19:16:31 +00:00
= cut
2010-01-27 15:03:27 +00:00
#-------------------------------------------------------------------------------
sub listNIMnetwork
2007-12-12 19:16:31 +00:00
{
2010-01-27 15:03:27 +00:00
my $ callback = shift ;
my $ xnets = shift ;
my $ xnhash = shift ;
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
my % xnethash ; # hash of xCAT network definitions
if ( $ xnhash ) {
% xnethash = % { $ xnhash } ;
}
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
my @ xcatnetworks = @ { $ xnets } ;
#
# get all the nim network names
#
my $ cmd = qq~/usr/sbin/lsnim -c networks | /usr/bin/cut -f1 -d' ' 2>/dev/null~ ;
my @ nimnetworks = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
my $ rsp ;
push @ { $ rsp - > { data } } , "$::msgstr Could not run lsnim command: \'$cmd\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
# for each NIM network - get the attrs
my % NIMnets ;
foreach my $ netwk ( @ nimnetworks ) {
my $ cmd = qq~/usr/sbin/lsnim -Z -a net_addr -a snm $netwk 2>/dev/null~ ;
my @ result = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
2007-12-12 19:16:31 +00:00
my $ rsp ;
2010-01-27 15:03:27 +00:00
push @ { $ rsp - > { data } } , "$::msgstr Could not run lsnim command: \'$cmd\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
2007-12-12 19:16:31 +00:00
return 1 ;
}
2010-01-27 15:03:27 +00:00
foreach my $ l ( @ result ) {
# skip comment lines
next if ( $ l =~ /^\s*#/ ) ;
my ( $ nimname , $ net_addr , $ snm ) = split ( ':' , $ l ) ;
$ NIMnets { $ netwk } { 'net_addr' } = $ net_addr ;
$ NIMnets { $ netwk } { 'snm' } = $ snm ;
}
2007-12-12 19:16:31 +00:00
}
2010-01-27 15:03:27 +00:00
# for each xCAT network check for an equivalent NIM network
# - if a match then display the NIM def
# - display output of "lsnim -l <netname>"
foreach my $ xcatnet ( @ xcatnetworks ) {
# split mask
my ( $ nm1 , $ nm2 , $ nm3 , $ nm4 ) = split ( '\.' , $ xnethash { $ xcatnet } { mask } ) ;
# split net addr
my ( $ nn1 , $ nn2 , $ nn3 , $ nn4 ) = split ( '\.' , $ xnethash { $ xcatnet } { net } ) ;
foreach my $ nimnet ( @ nimnetworks ) {
# split definition mask
my ( $ dm1 , $ dm2 , $ dm3 , $ dm4 ) = split ( '\.' , $ NIMnets { $ nimnet } { 'snm' } ) ;
# split definition net addr
my ( $ dn1 , $ dn2 , $ dn3 , $ dn4 ) = split ( '\.' , $ NIMnets { $ nimnet } { 'net_addr' } ) ;
# check for the same netmask and network address
if ( ( $ nn1 == $ dn1 ) && ( $ nn2 == $ dn2 ) && ( $ nn3 == $ dn3 ) && ( $ nn4 == $ dn4 ) ) {
if ( ( $ nm1 == $ dm1 ) && ( $ nm2 == $ dm2 ) && ( $ nm3 == $ dm3 ) && ( $ nm4 == $ dm4 ) ) {
# found match so display NIM net def
my $ cmd = qq~/usr/sbin/lsnim -l $nimnet 2>/dev/null~ ;
my $ output = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
# my $rsp;
# push @{$rsp->{data}}, "Could not run lsnim command: \'$cmd\'.\n";
# xCAT::MsgUtils->message("E", $rsp, $callback);
next ;
} else {
my $ rsp ;
push @ { $ rsp - > { data } } , "Note: The following is a match for \nxCAT network named \'$xcatnet\'\n" ;
push @ { $ rsp - > { data } } , "$output\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
}
}
}
} # end for each nim net
} # end foreach xcat net
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
return 0 ;
2007-12-12 19:16:31 +00:00
}
2010-01-27 15:03:27 +00:00
#-------------------------------------------------------------------------------
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
= head3 rmNIMnetwork
Remove NIM network definitions corresponding to xCAT network
definitions . This routine runs on the NIMprime and AIX SNs
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
Arguments:
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
Returns:
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
Comments:
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
ex . & rmNIMnetwork ( $ callback , \ @ networks ) ;
2007-12-12 19:16:31 +00:00
2010-01-27 15:03:27 +00:00
= cut
#-------------------------------------------------------------------------------
sub rmNIMnetwork
2007-12-12 19:16:31 +00:00
{
2010-01-27 15:03:27 +00:00
my $ callback = shift ;
my $ xnets = shift ;
############################################
#
# This will not work - you must first remove the master if* definition
# and the route defs AND any objects that may reference the network
# - it is not worth the effort - maybe a future
# enhancement - I'll leave the code here for now.
#########################################################
my @ xcatnetworks = @ { $ xnets } ;
#
# get all the nim network names
#
my $ cmd = qq~/usr/sbin/lsnim -c networks | /usr/bin/cut -f1 -d' ' 2>/dev/null~ ;
my @ nimnetworks = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
my $ rsp ;
push @ { $ rsp - > { data } } , "Could not run lsnim command: \'$cmd\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
foreach my $ xcatnet ( @ xcatnetworks ) {
chomp $ xcatnet ;
foreach my $ nimnet ( @ nimnetworks ) {
chomp $ nimnet ;
if ( $ xcatnet eq $ nimnet ) {
# get rid of the old definition
my $ rmcmd = "/usr/sbin/nim -Fo remove $nimnet" ;
my $ output = xCAT::Utils - > runcmd ( "$rmcmd" , - 1 ) ;
if ( $ ::RUNCMD_RC != 0 ) {
my $ rsp ;
push @ { $ rsp - > { data } } , "Could not remove the existing NIM network named \'$nimnet\'.\n" ;
if ( $ ::VERBOSE ) {
push @ { $ rsp - > { data } } , "$output" ;
}
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
} else {
if ( $ ::VERBOSE ) {
my $ rsp ;
push @ { $ rsp - > { data } } , "Removed the NIM network definition called \'$nimnet\'\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
}
}
}
}
}
return 0 ;
2007-12-12 19:16:31 +00:00
}
1 ;