2007-10-26 22:44:33 +00:00
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#####################################################
#
# xCAT plugin package to handle commands that manage the xCAT object
# definitions
#
#####################################################
2007-11-26 20:09:18 +00:00
2007-10-26 22:44:33 +00:00
package xCAT_plugin::DBobjectdefs ;
2007-11-26 20:09:18 +00:00
2007-10-26 22:44:33 +00:00
use xCAT::NodeRange ;
use xCAT::Schema ;
2007-11-26 20:09:18 +00:00
use xCAT::DBobjUtils ;
2007-10-26 22:44:33 +00:00
use Data::Dumper ;
use Getopt::Long ;
2007-11-26 20:09:18 +00:00
use xCAT::MsgUtils ;
2007-10-26 22:44:33 +00:00
# options can be bundled up like -vV
Getopt::Long:: Configure ( "bundling" ) ;
2007-11-26 20:09:18 +00:00
Getopt::Long:: Configure ( "pass_through" ) ;
$ Getopt:: Long:: ignorecase = 0 ;
#
# Globals
#
2007-10-26 22:44:33 +00:00
% ::CLIATTRS ; # attr=values provided on the command line
2007-11-26 20:09:18 +00:00
% ::FILEATTRS ; # attr=values provided in an input file
% ::FINALATTRS ; # final set of attr=values that are used to set
# the object
% ::objfilehash ; # hash of objects/types based of "-f" option
# (list in file)
% ::WhereHash ; # hash of attr=val from "-w" option
@ ::AttrList ; # list of attrs from "-i" option
# object type lists
@ ::clobjtypes ; # list of object types derived from the command line.
@ ::fileobjtypes ; # list of object types from input file ("-x" or "-z")
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# object name lists
@ ::clobjnames ; # list of object names derived from the command line
@ ::fileobjnames ; # list of object names from an input file
@ ::objfilelist ; # list of object names from the "-f" option
@ ::allobjnames ; # combined list
@ ::noderange ; # list of nodes derived from command line
2007-10-26 22:44:33 +00:00
#------------------------------------------------------------------------------
= head1 DBobjectdefs
This program module file supports the management of the xCAT data object
definitions .
2007-11-26 20:09:18 +00:00
Supported xCAT data object commands:
mkdef - create xCAT data object definitions .
lsdef - list xCAT data object definitions .
chdef - change xCAT data object definitions .
rmdef - remove xCAT data object definitions .
2007-10-26 22:44:33 +00:00
If adding to this file , please take a moment to ensure that:
1 . Your contrib has a readable pod header describing the purpose and use of
the subroutine .
2 . Your contrib is under the correct heading and is in alphabetical order
under that heading .
3 . You have run tidypod on your this file and saved the html file
= cut
#------------------------------------------------------------------------------
= head2 xCAT data object definition support
= cut
#------------------------------------------------------------------------------
#----------------------------------------------------------------------------
= head3 handled_commands
Return a list of commands handled by this plugin
= cut
#-----------------------------------------------------------------------------
sub handled_commands
{
return {
2007-11-26 20:09:18 +00:00
mkdef = > "DBobjectdefs" ,
lsdef = > "DBobjectdefs" ,
chdef = > "DBobjectdefs" ,
rmdef = > "DBobjectdefs"
2007-10-26 22:44:33 +00:00
} ;
}
#----------------------------------------------------------------------------
= head3 process_request
Check for xCAT command and call the appropriate subroutine .
Arguments:
Returns:
0 - OK
1 - error
Globals:
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
sub process_request
{
$ ::request = shift ;
$ ::callback = shift ;
my $ ret ;
my $ msg ;
# globals used by all subroutines.
2007-11-26 20:09:18 +00:00
$ ::command = $ ::request - > { command } - > [ 0 ] ;
$ ::args = $ ::request - > { arg } ;
$ ::filedata = $ ::request - > { stdin } - > [ 0 ] ;
2007-10-26 22:44:33 +00:00
# figure out which cmd and call the subroutine to process
2007-11-26 20:09:18 +00:00
if ( $ ::command eq "mkdef" )
2007-10-26 22:44:33 +00:00
{
( $ ret , $ msg ) = & defmk ;
}
2007-11-26 20:09:18 +00:00
elsif ( $ ::command eq "lsdef" )
2007-10-26 22:44:33 +00:00
{
( $ ret , $ msg ) = & defls ;
}
2007-11-26 20:09:18 +00:00
elsif ( $ ::command eq "chdef" )
2007-10-26 22:44:33 +00:00
{
( $ ret , $ msg ) = & defch ;
}
2007-11-26 20:09:18 +00:00
elsif ( $ ::command eq "rmdef" )
2007-10-26 22:44:33 +00:00
{
( $ ret , $ msg ) = & defrm ;
}
if ( $ msg )
{
2007-11-26 20:09:18 +00:00
my $ rsp ;
2007-10-26 22:44:33 +00:00
$ rsp - > { data } - > [ 0 ] = $ msg ;
$ ::callback - > ( $ rsp ) ;
}
return $ ret ;
}
#----------------------------------------------------------------------------
= head3 processArgs
Process the command line . Covers all four commands .
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
{
2007-11-26 20:09:18 +00:00
my $ gotattrs = 0 ;
2007-10-26 22:44:33 +00:00
@ ARGV = @ { $ ::args } ;
# parse the options - include any option from all 4 cmds
if (
! GetOptions (
2007-11-26 20:09:18 +00:00
'all|a' = > \ $ ::opt_a ,
2007-10-26 22:44:33 +00:00
'dynamic|d' = > \ $ ::opt_d ,
2007-11-26 20:09:18 +00:00
'f|force' = > \ $ ::opt_f ,
2007-10-26 22:44:33 +00:00
'i=s' = > \ $ ::opt_i ,
'help|h' = > \ $ ::opt_h ,
'long|l' = > \ $ ::opt_l ,
'm|minus' = > \ $ ::opt_m ,
'o=s' = > \ $ ::opt_o ,
2007-11-26 20:09:18 +00:00
'p|plus' = > \ $ ::opt_p ,
2007-10-26 22:44:33 +00:00
't=s' = > \ $ ::opt_t ,
'verbose|V' = > \ $ ::opt_V ,
'version|v' = > \ $ ::opt_v ,
'w=s' = > \ $ ::opt_w ,
2007-11-26 20:09:18 +00:00
'x|xml' = > \ $ ::opt_x ,
'z|stanza' = > \ $ ::opt_z
2007-10-26 22:44:33 +00:00
)
)
{
2007-11-26 20:09:18 +00:00
# return 2;
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
# opt_x not yet supported
if ( $ ::opt_x )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"The \'-x\' (XML format) option is not yet implemented." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
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 ;
$ ::objectsfrom_nr = 0 ;
$ ::objectsfrom_file = 0 ;
#
# process @ARGV
#
# - put attr=val operands in ATTRS hash
while ( my $ a = shift ( @ ARGV ) )
{
2007-10-26 22:44:33 +00:00
if ( ! ( $ a =~ /=/ ) )
{
2007-11-26 20:09:18 +00:00
# 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 ) ;
}
2007-10-26 22:44:33 +00:00
}
else
{
# if it has an "=" sign its an attr=val - we hope
2007-11-26 20:09:18 +00:00
# - this will handle "attr= "
my ( $ attr , $ value ) = $ a =~ /^\s*(\S+?)\s*=\s*(\S*.*)$/ ;
2007-10-26 22:44:33 +00:00
if ( ! defined ( $ attr ) || ! defined ( $ value ) )
{
2007-11-26 20:09:18 +00:00
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Incorrect \'attr=val\' pair - $a\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 3 ;
2007-10-26 22:44:33 +00:00
}
$ gotattrs = 1 ;
# put attr=val in hash
$ ::ATTRS { $ attr } = $ value ;
}
}
# Option -h for Help
2007-11-26 20:09:18 +00:00
# if user specifies "-t" & "-h" they want a list of valid attrs
if ( defined ( $ ::opt_h ) && ! defined ( $ ::opt_t ) )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
return 2 ;
2007-10-26 22:44:33 +00:00
}
# Option -v for version - do we need this???
if ( defined ( $ ::opt_v ) )
{
2007-11-26 20:09:18 +00:00
my $ rsp ;
2007-10-26 22:44:33 +00:00
$ rsp - > { data } - > [ 0 ] = "$::command - version 1.0" ;
2007-11-26 20:09:18 +00:00
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
return 1 ; # no usage - just exit
2007-10-26 22:44:33 +00:00
}
# Option -V for verbose output
if ( defined ( $ ::opt_V ) )
{
$ ::verbose = 1 ;
2007-11-26 20:09:18 +00:00
$ ::VERBOSE = 1 ;
}
#
# process the input file - if provided
#
if ( $ ::filedata )
{
my $ rc = xCAT::DBobjUtils - > readFileInput ( $ ::filedata ) ;
if ( $ rc )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Could not process file input data.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
return 1 ;
}
# - %::FILEATTRS{fileobjname}{attr}=val
# set @::fileobjtypes, @::fileobjnames, %::FILEATTRS
$ ::objectsfrom_file = 1 ;
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
#
# determine the object types
#
2007-10-26 22:44:33 +00:00
# could have comma seperated list of types
if ( $ ::opt_t )
{
2007-11-26 20:09:18 +00:00
my @ tmptypes ;
2007-10-26 22:44:33 +00:00
if ( $ ::opt_t =~ /,/ )
{
# can't have mult types when using attr=val
if ( $ gotattrs )
{
2007-11-26 20:09:18 +00:00
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Cannot combine multiple types with \'att=val\' pairs on the command line.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 3 ;
2007-10-26 22:44:33 +00:00
}
else
{
2007-11-26 20:09:18 +00:00
@ tmptypes = split ( ',' , $ ::opt_t ) ;
2007-10-26 22:44:33 +00:00
}
}
else
{
2007-11-26 20:09:18 +00:00
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 ] =
"Type \'$t\' is not a valid xCAT object type.\n" ;
$ rsp - > { data } - > [ 1 ] = "Skipping to the next type.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
else
{
chomp $ t ;
push ( @ ::clobjtypes , $ t ) ;
}
2007-10-26 22:44:33 +00:00
}
}
2007-11-26 20:09:18 +00:00
# must have object type(s) - default if not provided
if ( ! @ ::clobjtypes && ! @ ::fileobjtypes && ! $ ::opt_a && ! $ ::opt_t )
{
# make the default type = 'node' if not specified
push ( @ ::clobjtypes , 'node' ) ;
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Assuming an object type of \'node\'.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
# if user specifies "-t" & "-h" they want valid type or attrs info
if ( $ ::opt_h && $ ::opt_t )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
# give the list of attr names for each type specified
2007-10-26 22:44:33 +00:00
foreach my $ t ( @ ::clobjtypes )
{
2007-11-26 20:09:18 +00:00
if ( $ t eq 'site' )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"\nThere can only be one site definition. The name of the site definition is \'clustersite\'. This definiton consists of an unlimited list of user-defined attributes and values. Some specific attribute values are required to support xCAT features. See the xCAT documentation for more information.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
next ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
}
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"\nThe valid attribute names for object type \'$t\' are:\n\n" ;
# get the data type definition from Schema.pm
my $ datatype = $ xCAT:: Schema:: defspec { $ t } ;
# get the objkey for this type object (ex. objkey = 'node')
my $ objkey = $ datatype - > { 'objkey' } ;
$ rsp - > { data } - > [ 1 ] = "Attribute Description\n" ;
my @ alreadydone ; # the same attr may appear more then once
foreach $ this_attr ( sort @ { $ datatype - > { 'attrs' } } )
{
my $ attr = $ this_attr - > { attr_name } ;
my $ desc = $ this_attr - > { description } ;
# if (($attr ne $objkey) && !grep(/^$attr$/, @alreadydone))
if ( ! grep ( /^$attr$/ , @ alreadydone ) )
{
push ( @ attrlist , "$attr\t\t- $desc\n" ) ;
}
push ( @ alreadydone , $ attr ) ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
}
my $ n = 2 ;
foreach my $ l ( sort @ attrlist )
{
$ rsp - > { data } - > [ $ n ] = "$l" ;
$ n + + ;
}
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
return 1 ;
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
#
# determine the object names
#
2007-10-26 22:44:33 +00:00
# - get object names from the -o option or the noderange
if ( $ ::opt_o )
{
2007-11-26 20:09:18 +00:00
$ ::objectsfrom_opto = 1 ;
# special handling for site table !!!!!
if ( ( $ ::opt_t eq 'site' ) && ( $ ::opt_o ne 'clustersite' ) )
{
push ( @ ::clobjnames , 'clustersite' ) ;
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Only one site definition is supported." ;
$ rsp - > { data } - > [ 1 ] = "Setting the name of the site definition to \'clustersite\'.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
elsif ( $ ::opt_t eq 'node' )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
@ ::clobjnames = & noderange ( $ ::opt_o , 0 ) ;
2007-10-26 22:44:33 +00:00
}
else
{
2007-11-26 20:09:18 +00:00
# make a list
if ( $ ::opt_o =~ /,/ )
{
@ ::clobjnames = split ( ',' , $ ::opt_o ) ;
}
else
{
push ( @ ::clobjnames , $ ::opt_o ) ;
}
2007-10-26 22:44:33 +00:00
}
}
2007-11-26 20:09:18 +00:00
elsif ( @ ::noderange && ( @ ::clobjtypes [ 0 ] eq 'node' ) )
2007-10-26 22:44:33 +00:00
{
# if there's no object list and the type is node then the
2007-11-26 20:09:18 +00:00
# noderange list is assumed to be the object names list
@ ::clobjnames = @ ::noderange ;
$ ::objectsfrom_nr = 1 ;
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
# special case for site table!!!!!!!!!!!!!!
if ( ( $ ::opt_t eq 'site' ) && ! $ ::opt_o )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Setting the name of the site definition to \'clustersite\'." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
push ( @ ::clobjnames , 'clustersite' ) ;
$ ::objectsfrom_opto = 1 ;
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# if there is no other input for object names then we need to
# find all the object names for the specified types
if ( $ ::opt_t
&& ! ( $ ::opt_o
|| $ ::filedata
|| $ ::opt_a
|| @ ::noderange
|| @ ::clobjnames ) )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
my @ tmplist ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# also ne chdef ????????
if ( $ ::command ne 'mkdef' )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
$ ::objectsfrom_optt = 1 ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# could have multiple type
foreach my $ t ( @ ::clobjtypes )
{
# special case for site table !!!!
if ( $ t eq 'site' )
{
push ( @ tmplist , 'clustersite' ) ;
}
else
{
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# look up all objects of this type in the DB ???
@ tmplist = xCAT::DBobjUtils - > getObjectsOfType ( $ t ) ;
unless ( @ tmplist )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Could not get objects of type \'$t\'.\n" ;
$ rsp - > { data } - > [ 1 ] = "Skipping to the next type.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
next ;
}
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# add objname and type to hash and global list
foreach my $ o ( @ tmplist )
{
push ( @ ::clobjnames , $ o ) ;
$ ::ObjTypeHash { $ o } = $ t ;
}
}
}
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
2007-10-26 22:44:33 +00:00
# can't have -a with other obj sources
if ( $ ::opt_a
2007-11-26 20:09:18 +00:00
&& ( $ ::opt_o || $ ::filedata || @ ::noderange ) )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Cannot use \'-a\' with \'-o\', a noderange or file input.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 3 ;
2007-10-26 22:44:33 +00:00
}
# if -a then get a list of all DB objects
if ( $ ::opt_a )
{
2007-11-26 20:09:18 +00:00
my @ tmplist ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# for every type of data object get the list of defined objects
foreach my $ t ( keys % { xCAT::Schema:: defspec } )
{
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
$ ::objectsfrom_opta = 1 ;
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 ;
}
}
}
2007-10-26 22:44:33 +00:00
}
# must have object name(s) -
if ( ! @ ::clobjnames && ! @ ::fileobjnames )
{
2007-11-26 20:09:18 +00:00
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Could not determine what object definitions to remove.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 3 ;
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
# combine object name all object names provided
2007-10-26 22:44:33 +00:00
@ ::allobjnames = @ ::clobjnames ;
if ( @ ::fileobjnames )
{
2007-11-26 20:09:18 +00:00
# add list from stanza or xml file
2007-10-26 22:44:33 +00:00
push @ ::allobjnames , @ ::fileobjnames ;
}
2007-11-26 20:09:18 +00:00
elsif ( @ ::objfilelist )
{
# add list from "-f" file option
push @ ::allobjnames , @ ::objfilelist ;
}
# check for the -w option
if ( $ ::opt_w )
{
my @ tmpWhereList = split ( ',' , $ ::opt_w ) ;
foreach my $ w ( @ tmpWhereList )
{
if ( $ w =~ /=/ )
{
my ( $ a , $ v ) = $ w =~ /^\s*(\S+?)\s*=\s*(\S*.*)$/ ;
if ( ! defined ( $ a ) || ! defined ( $ v ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Incorrect \'attr=val\' pair - $a\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 3 ;
}
$ ::WhereHash { $ a } = $ v ;
}
}
}
# check for the -i option
if ( $ ::opt_i && ( $ ::command ne 'lsdef' ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"The \'-i\' option is only valid for the lsdef command.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 3 ;
}
# just make a global list of the attr names provided
if ( $ ::opt_i )
{
@ ::AttrList = split ( ',' , $ ::opt_i ) ;
}
2007-10-26 22:44:33 +00:00
return 0 ;
}
#----------------------------------------------------------------------------
= head3 defmk
2007-11-26 20:09:18 +00:00
Support for the xCAT mkdef command .
2007-10-26 22:44:33 +00:00
Arguments:
Returns:
0 - OK
1 - error
Globals:
Error:
Example:
Comments:
Object names to create are derived from
- o , - t , w , - z , - x , or noderange !
Attr = val pairs come from cmd line args or - z / - x files
= cut
#-----------------------------------------------------------------------------
sub defmk
{
2007-11-26 20:09:18 +00:00
@ ::allobjnames = [] ;
my $ rc = 0 ;
my $ error = 0 ;
2007-10-26 22:44:33 +00:00
# process the command line
2007-11-26 20:09:18 +00:00
$ rc = & processArgs ;
2007-10-26 22:44:33 +00:00
if ( $ rc != 0 )
{
2007-11-26 20:09:18 +00:00
# rc: 0 - ok, 1 - return, 2 - help, 3 - error
if ( $ rc != 1 )
{
& defmk_usage ;
}
2007-10-26 22:44:33 +00:00
return ( $ rc - 1 ) ;
}
2007-11-26 20:09:18 +00:00
# check options unique to these commands
if ( $ ::opt_p || $ ::opt_m )
{
# error
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"The \'-p\' and \'-m\' options are not valid for the mkdef command." ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
& defmk_usage ;
return 1 ;
}
if ( $ ::opt_t && ( $ ::opt_a || $ ::opt_z || $ ::opt_x ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Cannot combine \'-t\' and \'-a\', \'-z\', or \'-x\' options.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
& defmk_usage ;
return 1 ;
}
# check to make sure we have a list of objects to work with
if ( ! @ ::allobjnames )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "No object names were provided.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
& defmk_usage ;
return 1 ;
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# set $objtype & fill in cmd line hash
if ( % ::ATTRS || ( $ ::opt_t eq "group" ) )
2007-10-26 22:44:33 +00:00
{
# if attr=val on cmd line then could only have one type
2007-11-26 20:09:18 +00:00
$ ::objtype = @ ::clobjtypes [ 0 ] ;
2007-10-26 22:44:33 +00:00
#
# set cli attrs for each object definition
#
2007-11-26 20:09:18 +00:00
foreach my $ objname ( @ ::clobjnames )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
# set the objtype attr - if provided
if ( $ ::objtype )
{
$ ::CLIATTRS { $ objname } { objtype } = $ ::objtype ;
}
# get the data type definition from Schema.pm
my $ datatype = $ xCAT:: Schema:: defspec { $ ::objtype } ;
my @ list ;
foreach my $ this_attr ( sort @ { $ datatype - > { 'attrs' } } )
{
my $ a = $ this_attr - > { attr_name } ;
push ( @ list , $ a ) ;
}
# set the attrs from the attr=val pairs
foreach my $ attr ( keys % ::ATTRS )
{
if ( ! grep ( /$attr/ , @ list ) && ( $ ::objtype ne 'site' ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"\'$attr\' is not a valid attribute name for for an object type of \'$::objtype\'.\n" ;
$ rsp - > { data } - > [ 1 ] = "Skipping to the next attribute.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
next ;
}
else
{
$ ::CLIATTRS { $ objname } { $ attr } = $ ::ATTRS { $ attr } ;
}
} # end - foreach attr
2007-10-26 22:44:33 +00:00
}
}
#
# Pull all the pieces together for the final hash
2007-11-26 20:09:18 +00:00
# - combines the command line attrs and input file attrs if provided
2007-10-26 22:44:33 +00:00
#
if ( & setFINALattrs != 0 )
{
2007-11-26 20:09:18 +00:00
$ error = 1 ;
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
# we need a list of objects that are
# already defined for each type.
foreach my $ t ( @ ::finalTypeList )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
# special case for site table !!!!!!!!!!!!!!!!!!!!
if ( $ t eq 'site' )
{
@ { $ objTypeLists { $ t } } = 'clustersite' ;
}
else
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
@ { $ objTypeLists { $ t } } = xCAT::DBobjUtils - > getObjectsOfType ( $ t ) ;
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
foreach my $ obj ( keys % ::FINALATTRS )
{
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
my $ type = $ ::FINALATTRS { $ obj } { objtype } ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# check to make sure we have type
if ( ! $ type )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "No type was provided for object \'$obj\'.\n" ;
$ rsp - > { data } - > [ 1 ] = "Skipping to the next object.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
2007-10-26 22:44:33 +00:00
next ;
}
2007-11-26 20:09:18 +00:00
# ndebug mk
# if object already exists
if ( grep ( /$obj/ , @ { $ objTypeLists { $ type } } ) )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
if ( $ ::opt_f )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
# remove the old object
$ objhash { $ obj } = $ type ;
if ( xCAT::DBobjUtils - > rmobjdefs ( \ % objhash ) != 0 )
{
$ error = 1 ;
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Could not remove the definition for \'$obj\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
}
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
else
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
# won't remove the old one unless the force option is used
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"\nA definition for \'$obj\' already exists.\n" ;
$ rsp - > { data } - > [ 1 ] =
"To remove the old definition and replace it with \na new definition use the force \'-f\' option.\n" ;
$ rsp - > { data } - > [ 2 ] =
"To change the existing definition use the \'chdef\' command.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
2007-10-26 22:44:33 +00:00
next ;
2007-11-26 20:09:18 +00:00
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# need to handle group definitions - special!
if ( $ type eq 'group' )
{
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
my @ memberlist ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# if the group type was not set then set it
if ( ! $ ::FINALATTRS { $ obj } { grouptype } )
{
if ( $ ::opt_d )
{
$ ::FINALATTRS { $ obj } { grouptype } = 'dynamic' ;
$ ::FINALATTRS { $ obj } { members } = 'dynamic' ;
}
else
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
$ ::FINALATTRS { $ obj } { grouptype } = 'static' ;
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# if dynamic and wherevals not set then set to opt_w
if ( $ ::FINALATTRS { $ obj } { grouptype } eq 'dynamic' )
{
if ( ! $ ::FINALATTRS { $ obj } { wherevals } )
{
if ( $ ::opt_w )
{
$ ::FINALATTRS { $ obj } { wherevals } = $ ::opt_w ;
}
else
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"The \'where\' attributes and values were not provided for dynamic group \'$obj\'.\n" ;
$ rsp - > { data } - > [ 1 ] = "Skipping to the next group.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
next ;
}
}
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# if static group then figure out memberlist
if ( $ ::FINALATTRS { $ obj } { grouptype } eq 'static' )
{
if ( $ ::opt_w && $ ::FINALATTRS { $ obj } { members } )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Cannot use a list of members together with the \'-w\' option.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 1 ;
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
if ( $ ::FINALATTRS { $ obj } { members } )
{
@ memberlist = & noderange ( $ ::FINALATTRS { $ obj } { members } , 0 ) ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# don't list all the nodes in the group table
# set the value to static and we'll figure out the list
# by looking in the nodelist table
$ ::FINALATTRS { $ obj } { members } = 'static' ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
}
else
{
if ( $ ::opt_w )
{
$ ::FINALATTRS { $ obj } { members } = 'static' ;
# get a list of nodes whose attr values match the
# "where" values and make that the memberlist of
# the group.
# get a list of all node nodes
my @ tmplist =
xCAT::DBobjUtils - > getObjectsOfType ( 'node' ) ;
# create a hash of obj names and types
foreach my $ n ( @ tmplist )
{
$ objhash { $ n } = 'node' ;
}
# get all the attrs for these nodes
my % myhash = xCAT::DBobjUtils - > getobjdefs ( \ % objhash ) ;
# see which ones match the where values
foreach my $ objname ( keys % myhash )
{
# all the "where" attrs must match the object attrs
my $ addlist = 1 ;
foreach my $ testattr ( keys % ::WhereHash )
{
if ( $ myhash { $ objname } { $ testattr } ne
$ ::WhereHash { $ testattr } )
{
# don't disply
$ addlist = 0 ;
break ;
}
}
if ( $ addlist )
{
push ( @ memberlist , $ objname ) ;
}
}
}
else
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Cannot determine a member list for group \'$objname\'.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# need to add group name to all members in nodelist table
my $ tab =
xCAT::Table - > new ( 'nodelist' , - create = > 1 , - autocommit = > 0 ) ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
my $ newgroups ;
foreach my $ n ( @ memberlist )
{
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# add this group name to the node entry in
# the nodelist table
$ nodehash { $ n } { groups } = $ obj ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# get the current value
my $ grps = $ tab - > getNodeAttribs ( $ n , [ 'groups' ] ) ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# if it's not already in the "groups" list then add it
my @ tmpgrps = split ( /,/ , $ grps - > { 'groups' } ) ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
if ( ! grep ( /^$obj$/ , @ tmpgrps ) )
{
if ( $ grps and $ grps - > { 'groups' } )
{
$ newgroups = "$grps->{'groups'},$obj" ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
}
else
{
$ newgroups = $ obj ;
}
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# add this group name to the node entry in
# the nodelist table
if ( $ newgroups )
{
$ tab - > setNodeAttribs ( $ n , { groups = > $ newgroups } ) ;
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
}
$ tab - > commit ;
}
} # end - if group type
if ( ( $ type eq "node" ) && $ ::FINALATTRS { $ obj } { groups } )
{
my @ grouplist ;
@ grouplist = split ( /,/ , $ ::FINALATTRS { $ obj } { groups } ) ;
foreach my $ g ( @ grouplist )
{
$ GroupHash { $ g } { objtype } = "group" ;
$ GroupHash { $ g } { grouptype } = "static" ;
$ GroupHash { $ g } { members } = "static" ;
}
if ( xCAT::DBobjUtils - > setobjdefs ( \ % GroupHash ) != 0 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Could not write data to the xCAT database.\n" ;
# xCAT::MsgUtils->message("E", $rsp, $::callback);
$ error = 1 ;
}
}
}
#
# write each object into the tables in the xCAT database
#
if ( xCAT::DBobjUtils - > setobjdefs ( \ % ::FINALATTRS ) != 0 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Could not write data to the xCAT database.\n" ;
# xCAT::MsgUtils->message("E", $rsp, $::callback);
$ error = 1 ;
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
if ( $ error )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"One or more errors occured when attempting to create or modify xCAT \nobject definitions.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 1 ;
}
else
{
if ( $ ::verbose )
{
# give results
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"The database was updated for the following objects:\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
my $ n = 1 ;
foreach my $ o ( sort ( keys % ::FINALATTRS ) )
{
$ rsp - > { data } - > [ $ n ] = "$o\n" ;
$ n + + ;
}
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
else
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Object definitions have been created or modified.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
return 0 ;
}
}
#----------------------------------------------------------------------------
= head3 defch
Support for the xCAT chdef command .
Arguments:
2007-10-26 22:44:33 +00:00
Returns:
0 - OK
1 - error
Globals:
Error:
Example:
Comments:
2007-11-26 20:09:18 +00:00
Object names to create are derived from
- o , - t , w , - z , - x , or noderange !
Attr = val pairs come from cmd line args or - z / - x files
2007-10-26 22:44:33 +00:00
= cut
#-----------------------------------------------------------------------------
2007-11-26 20:09:18 +00:00
sub defch
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
@ ::allobjnames = [] ;
my $ rc = 0 ;
my $ error = 0 ;
# process the command line
$ rc = & processArgs ;
if ( $ rc != 0 )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
# rc: 0 - ok, 1 - return, 2 - help, 3 - error
if ( $ rc != 1 )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
& defch_usage ;
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
return ( $ rc - 1 ) ;
}
#
# check options unique to this command
#
if ( $ ::opt_f )
{
# error
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"The \'-f\' option is not valid for the chdef command." ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
& defch_usage ;
return 1 ;
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
if ( $ ::opt_t && ( $ ::opt_a || $ ::opt_z || $ ::opt_x ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Cannot combine \'-t\' and \'-a\', \'-z\', or \'-x\' options.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
& defch_usage ;
return 1 ;
}
# check to make sure we have a list of objects to work with
if ( ! @ ::allobjnames )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "No object names were provided.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
& defch_usage ;
return 1 ;
}
# set $objtype & fill in cmd line hash
if ( % ::ATTRS || ( $ ::opt_t eq "group" ) )
{
# if attr=val on cmd line then could only have one type
$ ::objtype = @ ::clobjtypes [ 0 ] ;
#
# set cli attrs for each object definition
#
foreach my $ objname ( @ ::clobjnames )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
# set the objtype attr - if provided
if ( $ ::objtype )
{
chomp $ ::objtype ;
$ ::CLIATTRS { $ objname } { objtype } = $ ::objtype ;
}
# get the data type definition from Schema.pm
my $ datatype = $ xCAT:: Schema:: defspec { $ ::objtype } ;
my @ list ;
foreach my $ this_attr ( sort @ { $ datatype - > { 'attrs' } } )
{
my $ a = $ this_attr - > { attr_name } ;
push ( @ list , $ a ) ;
}
# set the attrs from the attr=val pairs
foreach my $ attr ( keys % ::ATTRS )
{
if ( ! grep ( /$attr/ , @ list ) && ( $ ::objtype ne 'site' ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"\'$attr\' is not a valid attribute name for for an object type of \'$::objtype\'.\n" ;
$ rsp - > { data } - > [ 1 ] = "Skipping to the next attribute.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
next ;
}
else
{
$ ::CLIATTRS { $ objname } { $ attr } = $ ::ATTRS { $ attr } ;
}
}
2007-10-26 22:44:33 +00:00
}
}
2007-11-26 20:09:18 +00:00
#
# Pull all the pieces together for the final hash
# - combines the command line attrs and input file attrs if provided
#
if ( & setFINALattrs != 0 )
{
$ error = 1 ;
}
# we need a list of objects that are
# already defined for each type.
foreach my $ t ( @ ::finalTypeList )
{
# special case for site table !!!!!!!!!!!!!!!!!!!!
if ( $ t eq 'site' )
{
@ { $ objTypeLists { $ t } } = 'clustersite' ;
}
else
{
@ { $ objTypeLists { $ t } } = xCAT::DBobjUtils - > getObjectsOfType ( $ t ) ;
}
}
foreach my $ obj ( keys % ::FINALATTRS )
{
my $ isDefined = 0 ;
my $ type = $ ::FINALATTRS { $ obj } { objtype } ;
# check to make sure we have type
if ( ! $ type )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "No type was provided for object \'$obj\'.\n" ;
$ rsp - > { data } - > [ 1 ] = "Skipping to the next object.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
next ;
}
if ( grep ( /$obj/ , @ { $ objTypeLists { $ type } } ) )
{
$ isDefined = 1 ;
}
if ( ! isDefined && $ ::opt_m )
{
#error - cannot remove items from an object that does not exist.
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"The \'-m\' option is not valid since the \'$obj\' definition does not exist.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
next ;
}
#
# need to handle group definitions - special!
# - may need to update the node definitions for the group members
#
if ( $ type eq 'group' )
{
my % grphash ;
my @ memberlist ;
# what kind of group is this? - static or dynamic
my $ grptype ;
if ( $ isDefined )
{
$ objhash { $ obj } = $ type ;
% grphash = xCAT::DBobjUtils - > getobjdefs ( \ % objhash ) ;
if ( ! defined ( % grphash ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Could not get xCAT object definitions.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 1 ;
}
$ grptype = $ grphash { $ obj } { grouptype } ;
}
else
{ #not defined
if ( $ ::FINALATTRS { $ obj } { grouptype } )
{
$ grptype = $ ::FINALATTRS { $ obj } { grouptype } ;
}
elsif ( $ ::opt_d )
{
$ grptype = 'dynamic' ;
}
else
{
$ grptype = 'static' ;
}
}
# make sure wherevals was set - if info provided
if ( ! $ ::FINALATTRS { $ obj } { wherevals } )
{
if ( $ ::opt_w )
{
$ ::FINALATTRS { $ obj } { wherevals } = $ ::opt_w ;
}
}
# get the @memberlist for static group
# - if provided - to use below
if ( $ grptype eq 'static' )
{
# check for bad cmd line options
if ( $ ::opt_w && $ ::FINALATTRS { $ obj } { members } )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Cannot use a list of members together with the \'-w\' option.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
next ;
}
if ( $ ::FINALATTRS { $ obj } { members } )
{
@ memberlist = & noderange ( $ ::FINALATTRS { $ obj } { members } , 0 ) ;
# don't list all the nodes in the group table
# set the value to static and we figure out the list
# by looking in the nodelist table
$ ::FINALATTRS { $ obj } { members } = 'static' ;
}
elsif ( $ ::FINALATTRS { $ obj } { wherevals } )
{
$ ::FINALATTRS { $ obj } { members } = 'static' ;
# get a list of nodes whose attr values match the
# "where" values and make that the memberlist of
# the group.
# get a list of all node nodes
my @ tmplist = xCAT::DBobjUtils - > getObjectsOfType ( 'node' ) ;
# create a hash of obj names and types
foreach my $ n ( @ tmplist )
{
$ objhash { $ n } = 'node' ;
}
# get all the attrs for these nodes
my % myhash = xCAT::DBobjUtils - > getobjdefs ( \ % objhash ) ;
# get a list of attr=val pairs
my @ tmpWhereList =
split ( ',' , $ ::FINALATTRS { $ obj } { wherevals } ) ;
# create an attr-val hash
foreach my $ w ( @ tmpWhereList )
{
if ( $ w =~ /=/ )
{
my ( $ a , $ v ) = $ w =~ /^\s*(\S+?)\s*=\s*(\S*.*)$/ ;
if ( ! defined ( $ a ) || ! defined ( $ v ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Incorrect \'attr=val\' pair - $a\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 3 ;
}
$ ::WhereHash { $ a } = $ v ;
}
}
# see which ones match the where values
foreach my $ objname ( keys % myhash )
{
# all the "where" attrs must match the object attrs
my $ addlist = 1 ;
foreach my $ testattr ( keys % ::WhereHash )
{
if ( $ myhash { $ objname } { $ testattr } ne
$ ::WhereHash { $ testattr } )
{
# don't disply
$ addlist = 0 ;
break ;
}
}
if ( $ addlist )
{
push ( @ memberlist , $ objname ) ;
}
}
}
else
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Cannot determine a member list forgroup \'$objname\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
}
} # end - get memberlist for static group
if ( ! $ isDefined )
{
# if the group type was not set then set it
if ( ! $ ::FINALATTRS { $ obj } { grouptype } )
{
if ( $ ::opt_d )
{
$ ::FINALATTRS { $ obj } { grouptype } = 'dynamic' ;
$ ::FINALATTRS { $ obj } { members } = 'dynamic' ;
if ( ! $ ::FINALATTRS { $ obj } { wherevals } )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"The \'where\' attributes and values were not provided for dynamic group \'$obj\'.\n" ;
$ rsp - > { data } - > [ 1 ] = "Skipping to the next group.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
next ;
}
}
else
{
$ ::FINALATTRS { $ obj } { grouptype } = 'static' ;
}
}
# if this is a static group
# then update the "groups" attr of each member node
if ( $ ::FINALATTRS { $ obj } { grouptype } eq 'static' )
{
# for each node in memberlist add this group
# name to the groups attr of the node
my % membhash ;
foreach $ n ( @ memberlist )
{
$ membhash { $ n } { groups } = $ obj ;
}
$ ::plus_option = 1 ;
$ ::minus_option = 0 ;
if ( xCAT::DBobjUtils - > setobjdefs ( \ % membhash ) != 0 )
{
$ error = 1 ;
}
$ ::plus_option = 0 ;
}
}
else
{ # group is defined
# if a list of members is provided then update the node entries
# note: the members attr of the group def will be set
# to static
if ( @ memberlist )
{
# options supported
if ( $ ::opt_m )
{ # removing these members
# for each node in memberlist - remove this group
# from the groups attr
my % membhash ;
foreach $ n ( @ memberlist )
{
$ membhash { $ n } { groups } = $ obj ;
$ membhash { $ n } { objtype } = 'node' ;
}
$ ::plus_option = 0 ;
$ ::minus_option = 1 ;
if ( xCAT::DBobjUtils - > setobjdefs ( \ % membhash ) != 0 )
{
$ error = 1 ;
}
$ ::minus_option = 0 ;
}
elsif ( $ ::opt_p )
{ #adding these new members
# for each node in memberlist add this group
# name to the groups attr
my % membhash ;
foreach $ n ( @ memberlist )
{
$ membhash { $ n } { groups } = $ obj ;
$ membhash { $ n } { objtype } = 'node' ;
}
$ ::plus_option = 1 ;
$ ::minus_option = 0 ;
if ( xCAT::DBobjUtils - > setobjdefs ( \ % membhash ) != 0 )
{
$ error = 1 ;
}
$ ::plus_option = 0 ;
}
else
{ # replace the members list altogether
# this is the default for the chdef command
# get the current members list
my $ list =
xCAT::DBobjUtils - > getGroupMembers ( $ obj , \ % grphash ) ;
my @ currentlist = split ( ',' , $ list ) ;
# for each node in currentlist - remove group name
# from groups attr
my % membhash ;
foreach $ n ( @ currentlist )
{
$ membhash { $ n } { groups } = $ obj ;
$ membhash { $ n } { objtype } = 'node' ;
}
$ ::plus_option = 0 ;
$ ::minus_option = 1 ;
if ( xCAT::DBobjUtils - > setobjdefs ( \ % membhash ) != 0 )
{
$ error = 1 ;
}
$ ::minus_option = 0 ;
# for each node in memberlist add this group
# name to the groups attr
my % membhash ;
foreach $ n ( @ memberlist )
{
$ membhash { $ n } { groups } = $ obj ;
$ membhash { $ n } { objtype } = 'node' ;
}
$ ::plus_option = 1 ;
$ ::minus_option = 0 ;
if ( xCAT::DBobjUtils - > setobjdefs ( \ % membhash ) != 0 )
{
$ error = 1 ;
}
$ ::plus_option = 0 ;
}
} # end - if memberlist
} # end - if group is defined
} # end - if group type
#
# Need special handling for node objects that have the
# groups attr set - may need to create group defs
#
if ( ( $ type eq "node" ) && $ ::FINALATTRS { $ obj } { groups } )
{
# get the list of groups in the "groups" attr
my @ grouplist ;
@ grouplist = split ( /,/ , $ ::FINALATTRS { $ obj } { groups } ) ;
# get the list of all defined group objects
@ definedgroups = xCAT::DBobjUtils - > getObjectsOfType ( group ) ;
# if we're creating the node or we're adding to or replacing
# the "groups" attr then check if the group
# defs exist and create them if they don't
if ( ! $ isDefined || ! $ ::opt_m )
{
# we either replace, add or take away from the "groups"
# list
# if not taking away then we must be adding or replacing
foreach my $ g ( @ grouplist )
{
if ( ! grep ( /^$g$/ , @ definedgroups ) )
{
# define it
$ GroupHash { $ g } { objtype } = "group" ;
$ GroupHash { $ g } { grouptype } = "static" ;
$ GroupHash { $ g } { members } = "static" ;
}
}
if ( defined ( % GroupHash ) )
{
if ( xCAT::DBobjUtils - > setobjdefs ( \ % GroupHash ) != 0 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Could not write data to the xCAT database.\n" ;
# xCAT::MsgUtils->message("E", $rsp, $::callback);
$ error = 1 ;
}
}
}
} # end - if type = node
} # end - for each object to update
#
# write each object into the tables in the xCAT database
#
# set update option
$ ::plus_option = 0 ;
$ ::minus_option = 0 ;
if ( $ ::opt_p )
{
$ ::plus_option = 1 ;
}
elsif ( $ ::opt_m )
{
$ ::minus_option = 1 ;
}
if ( xCAT::DBobjUtils - > setobjdefs ( \ % ::FINALATTRS ) != 0 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Could not write data to the xCAT database.\n" ;
# xCAT::MsgUtils->message("E", $rsp, $::callback);
$ error = 1 ;
}
if ( $ error )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"One or more errors occured when attempting to create or modify xCAT \nobject definitions.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 1 ;
}
else
{
if ( $ ::verbose )
{
# give results
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"The database was updated for the following objects:\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
my $ n = 1 ;
foreach my $ o ( sort ( keys % ::FINALATTRS ) )
{
$ rsp - > { data } - > [ $ n ] = "$o\n" ;
$ n + + ;
}
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
else
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Object definitions have been created or modified.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
return 0 ;
}
2007-10-26 22:44:33 +00:00
}
#----------------------------------------------------------------------------
= head3 setFINALattrs
create % ::FINALATTRS { objname } { attr } = val hash
conbines % ::FILEATTRS , and % ::CLIATTR
Arguments:
Returns:
0 - OK
1 - error
Globals:
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
sub setFINALattrs
{
2007-11-26 20:09:18 +00:00
my $ error = 0 ;
2007-10-26 22:44:33 +00:00
# set the final hash based on the info from the input file
if ( @ ::fileobjnames )
{
foreach my $ objname ( @ ::fileobjnames )
{
# check if this object is one of the type specified
2007-11-26 20:09:18 +00:00
if ( @ ::clobtypes )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
if ( ! grep ( /$::FILEATTRS{$objname}{objtype}/ , @ ::clobtypes ) )
{
next ;
}
}
# get the data type definition from Schema.pm
my $ datatype =
$ xCAT:: Schema:: defspec { $ ::FILEATTRS { $ objname } { objtype } } ;
my @ list ;
foreach my $ this_attr ( sort @ { $ datatype - > { 'attrs' } } )
{
my $ a = $ this_attr - > { attr_name } ;
push ( @ list , $ a ) ;
}
push ( @ list , "objtype" ) ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# if so then add it to the final hash
foreach my $ attr ( keys % { $ ::FILEATTRS { $ objname } } )
{
# see if valid attr
if ( ! grep ( /$attr/ , @ list )
&& ( $ ::FILEATTRS { $ objname } { objtype } ne 'site' ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"\'$attr\' is not a valid attribute name for for an object type of \'$::objtype\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
next ;
}
else
2007-10-26 22:44:33 +00:00
{
$ ::FINALATTRS { $ objname } { $ attr } =
$ ::FILEATTRS { $ objname } { $ attr } ;
}
2007-11-26 20:09:18 +00:00
}
2007-10-26 22:44:33 +00:00
}
}
# set the final hash based on the info from the cmd line hash
2007-11-26 20:09:18 +00:00
@ ::finalTypeList = ( ) ;
2007-10-26 22:44:33 +00:00
foreach my $ objname ( @ ::clobjnames )
{
foreach my $ attr ( keys % { $ ::CLIATTRS { $ objname } } )
{
2007-11-26 20:09:18 +00:00
2007-10-26 22:44:33 +00:00
$ ::FINALATTRS { $ objname } { $ attr } = $ ::CLIATTRS { $ objname } { $ attr } ;
2007-11-26 20:09:18 +00:00
if ( $ attr eq 'objtype' )
{
if (
! grep ( /^$::FINALATTRS{$objname}{objtype}/ , @ ::finalTypeList )
)
{
my $ type = $ ::FINALATTRS { $ objname } { objtype } ;
chomp $ type ;
push @ ::finalTypeList , $ type ;
}
}
2007-10-26 22:44:33 +00:00
}
}
2007-11-26 20:09:18 +00:00
if ( $ error )
{
return 1 ;
}
else
{
return 0 ;
}
2007-10-26 22:44:33 +00:00
}
#----------------------------------------------------------------------------
2007-11-26 20:09:18 +00:00
= head3 defls
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
Support for the xCAT defls command .
2007-10-26 22:44:33 +00:00
Arguments:
Returns:
0 - OK
1 - error
Globals:
2007-11-26 20:09:18 +00:00
2007-10-26 22:44:33 +00:00
Error:
Example:
Comments:
2007-11-26 20:09:18 +00:00
Object names derived from - o , - t , w , - a or noderange !
List of attrs to display is given by - i .
Output goes to standard out or a stanza / xml file ( - z or - x )
2007-10-26 22:44:33 +00:00
= cut
#-----------------------------------------------------------------------------
2007-11-26 20:09:18 +00:00
sub defls
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
my $ long = 0 ;
my % myhash ;
my % objhash ;
my @ objectlist ;
@ ::allobjnames ;
my $ numtypes = 0 ;
2007-10-26 22:44:33 +00:00
# process the command line
my $ rc = & processArgs ;
if ( $ rc != 0 )
{
2007-11-26 20:09:18 +00:00
# rc: 0 - ok, 1 - return, 2 - help, 3 - error
if ( $ rc != 1 )
{
& defls_usage ;
}
2007-10-26 22:44:33 +00:00
return ( $ rc - 1 ) ;
}
2007-11-26 20:09:18 +00:00
# do we want just the object names or all the attr=val
if ( $ ::opt_l || @ ::noderange || $ ::opt_i )
{
# assume we want the the details - not just the names
# - if provided object names or noderange
$ long + + ;
}
2007-10-26 22:44:33 +00:00
#
2007-11-26 20:09:18 +00:00
# put together a hash with the list of objects and the associated types
# - need to figure out which objects to look up
2007-10-26 22:44:33 +00:00
#
2007-11-26 20:09:18 +00:00
# if a set of objects was provided on the cmd line then there can
# be only one type value
if ( $ ::objectsfrom_opto || $ ::objectsfrom_nr || $ ::objectsfrom_args )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
my $ type = @ ::clobjtypes [ 0 ] ;
$ numtypes = 1 ;
foreach my $ obj ( sort @ ::clobjnames )
{
$ objhash { $ obj } = $ type ;
}
% myhash = xCAT::DBobjUtils - > getobjdefs ( \ % objhash ) ;
if ( ! defined ( % myhash ) )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Could not get xCAT object definitions.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
2007-10-26 22:44:33 +00:00
return 1 ;
2007-11-26 20:09:18 +00:00
2007-10-26 22:44:33 +00:00
}
}
2007-11-26 20:09:18 +00:00
# if just provided type list then find all objects of these types
if ( $ ::objectsfrom_optt )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
% objhash = % ::ObjTypeHash ;
% myhash = xCAT::DBobjUtils - > getobjdefs ( \ % objhash ) ;
if ( ! defined ( % myhash ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Could not get xCAT object definitions.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 1 ;
}
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
# if specify all
if ( $ ::opt_a )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
# could be modified by type
if ( $ ::opt_t )
{
# get all objects matching type list
# Get all object in this type list
foreach my $ t ( @ ::clobjtypes )
{
@ tmplist = xCAT::DBobjUtils - > getObjectsOfType ( $ t ) ;
if ( scalar ( @ tmplist ) > 1 )
{
foreach my $ obj ( @ tmplist )
{
$ objhash { $ obj } = $ t ;
}
}
else
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Could not get objects of type \'$type\'.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
}
% myhash = xCAT::DBobjUtils - > getobjdefs ( \ % objhash ) ;
if ( ! defined ( % myhash ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Could not get xCAT object definitions.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 1 ;
}
}
else
{
% myhash = xCAT::DBobjUtils - > getobjdefs ( \ % ::AllObjTypeHash ) ;
if ( ! defined ( % myhash ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Could not get xCAT object definitions.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 1 ;
}
}
foreach my $ t ( keys % { xCAT::Schema:: defspec } )
{
push ( @ ::clobjtypes , $ t ) ;
}
}
if ( ! defined ( % myhash ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Could not find any objects to display.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
return 0 ;
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# the list of objects may be limited by the "-w" option
# see which objects have attr/val that match the where values
# - if provided
if ( $ ::opt_w )
{
foreach my $ obj ( sort ( keys % myhash ) )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
# all the "where" attrs must match the object attrs
my $ dodisplay = 1 ;
foreach my $ testattr ( keys % ::WhereHash )
{
if ( $ myhash { $ obj } { $ testattr } ne $ ::WhereHash { $ testattr } )
{
# don't disply
$ dodisplay = 0 ;
break ;
}
}
if ( $ dodisplay )
{
push ( @ displayObjList , $ obj ) ;
}
2007-10-26 22:44:33 +00:00
}
}
2007-11-26 20:09:18 +00:00
#
# output in specified format
#
my @ foundobjlist ;
if ( $ ::opt_z )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "# <xCAT data object stanza file>" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
# group the objects by type to make the output easier to read
my $ numobjects = 0 ; # keep track of how many object we want to display
foreach my $ type ( @ ::clobjtypes )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
my % defhash ;
foreach my $ obj ( keys % myhash )
{
if ( $ obj )
{
$ numobjects + + ;
if ( $ myhash { $ obj } { 'objtype' } eq $ type )
{
$ defhash { $ obj } = $ myhash { $ obj } ;
}
}
}
if ( $ numobjects == 0 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Could not find any object definitions to display.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
return 0 ;
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
foreach my $ obj ( keys % defhash )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
unless ( $ obj )
{
next ;
}
# special handling for site table - for now!!!!!!!
if ( $ defhash { $ obj } { 'objtype' } ne 'site' )
{
my @ tmplist =
xCAT::DBobjUtils - > getObjectsOfType ( $ defhash { $ obj } { 'objtype' } ) ;
unless ( @ tmplist )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Could not find any objects of type \'$defhash{$obj}{'objtype'}\'.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
next ;
}
if ( ! grep ( /$obj/ , @ tmplist ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Could not find an object named \'$obj\' of type \'$defhash{$obj}{'objtype'}\'.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
next ;
}
} # end - if not site table
###################
# special handling for site table - for now !!!!!!!
######################
my @ attrlist ;
if ( $ defhash { $ obj } { 'objtype' } eq 'site' )
{
foreach my $ a ( keys % { $ defhash { $ obj } } )
{
push ( @ attrlist , $ a ) ;
}
}
else
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
# get the list of all attrs for this type object
# get the data type definition from Schema.pm
my $ datatype =
$ xCAT:: Schema:: defspec { $ defhash { $ obj } { 'objtype' } } ;
foreach $ this_attr ( @ { $ datatype - > { 'attrs' } } )
{
push ( @ attrlist , $ this_attr - > { attr_name } ) ;
}
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
if ( $ ::opt_x )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
# do output in XML format
2007-10-26 22:44:33 +00:00
}
else
{
2007-11-26 20:09:18 +00:00
# standard output or stanza format
if ( $ ::opt_w )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
# just display objects that match -w
if ( grep /^$obj$/ , @ displayObjList )
{
# display data
# do we want the short or long output?
if ( $ long )
{
if ( $ ::opt_z )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "\n$obj:" ;
$ rsp - > { data } - > [ 1 ] =
" objtype=$defhash{$obj}{'objtype'}" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
else
{
if ( $# ::clobjtypes > 0 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Object name: $obj ($defhash{$obj}{'objtype'})" ;
xCAT::MsgUtils - > message ( "I" , $ rsp ,
$ ::callback ) ;
}
else
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Object name: $obj" ;
xCAT::MsgUtils - > message ( "I" , $ rsp ,
$ ::callback ) ;
}
}
foreach my $ showattr ( sort @ attrlist )
{
if ( $ showattr eq 'objtype' )
{
next ;
}
if ( $ myhash { $ obj } { $ showattr } )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
" $showattr=$defhash{$obj}{$showattr}" ;
xCAT::MsgUtils - > message ( "I" , $ rsp ,
$ ::callback ) ;
}
# else
# {
# pr " $showattr=\n";
# }
}
}
else
{
# just give names of objects
if ( $ ::opt_z )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "\n$obj:" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
else
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "$obj" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
}
}
2007-10-26 22:44:33 +00:00
}
else
{
2007-11-26 20:09:18 +00:00
# not -w
# display all data
# do we want the short or long output?
if ( $ long )
{
if ( $ ::opt_z )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "\n$obj:" ;
$ rsp - > { data } - > [ 1 ] =
" objtype=$defhash{$obj}{'objtype'}" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
else
{
if ( $# ::clobjtypes > 0 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"\nObject name: $obj ($defhash{$obj}{'objtype'})" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
else
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "\nObject name: $obj" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
}
foreach my $ showattr ( sort @ attrlist )
{
if ( $ showattr eq 'objtype' )
{
next ;
}
my $ attrval ;
if ( $ defhash { $ obj } { $ showattr } )
{
$ attrval = $ defhash { $ obj } { $ showattr } ;
}
else
{
$ attrval = " " ;
}
# if an attr list was provided then just display those
if ( $ ::opt_i )
{
if ( grep ( /^$showattr$/ , @ ::AttrList ) )
{
if ( ( $ obj eq 'group' )
&& ( $ showattr eq 'members' ) )
{
my $ memberlist =
xCAT::DBobjUtils - > getGroupMembers (
$ obj ,
\ % defhash ) ;
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
" $showattr=$memberlist" ;
xCAT::MsgUtils - > message ( "I" , $ rsp ,
$ ::callback ) ;
}
else
{
# since they asked for this attr
# show it even if not set
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
" $showattr=$attrval" ;
xCAT::MsgUtils - > message ( "I" , $ rsp ,
$ ::callback ) ;
}
}
}
else
{
if ( ( $ defhash { $ obj } { 'objtype' } eq 'group' )
&& ( $ showattr eq 'members' ) )
{
my $ memberlist =
xCAT::DBobjUtils - > getGroupMembers ( $ obj ,
\ % defhash ) ;
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
" $showattr=$memberlist" ;
xCAT::MsgUtils - > message ( "I" , $ rsp ,
$ ::callback ) ;
}
else
{
# don't print unless set
if ( $ attrval ne " " )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
" $showattr=$attrval" ;
xCAT::MsgUtils - > message ( "I" , $ rsp ,
$ ::callback ) ;
}
}
}
}
}
else
{
if ( $ ::opt_a )
{
if ( $ ::opt_z )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "\n$obj:" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
else
{
# give the type also
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"$obj ($::AllObjTypeHash{$obj})" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
}
else
{
# just give the name
if ( $ ::opt_z )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "\n$obj:" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
else
{
if ( $# ::clobjtypes > 0 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"$obj ($defhash{$obj}{'objtype'})" ;
xCAT::MsgUtils - > message ( "I" , $ rsp ,
$ ::callback ) ;
}
else
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "$obj" ;
xCAT::MsgUtils - > message ( "I" , $ rsp ,
$ ::callback ) ;
}
}
}
}
2007-10-26 22:44:33 +00:00
}
}
}
}
return 0 ;
}
#----------------------------------------------------------------------------
2007-11-26 20:09:18 +00:00
= head3 defrm
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
Support for the xCAT defrm command .
2007-10-26 22:44:33 +00:00
Arguments:
Returns:
0 - OK
1 - error
Globals:
2007-11-26 20:09:18 +00:00
2007-10-26 22:44:33 +00:00
Error:
Example:
Comments:
2007-11-26 20:09:18 +00:00
Object names to remove are derived from - o , - t , w , - a , - f ,
or noderange !
2007-10-26 22:44:33 +00:00
= cut
#-----------------------------------------------------------------------------
2007-11-26 20:09:18 +00:00
sub defrm
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
my % objhash ;
my $ error = 0 ;
my % rmhash ;
my % myhash ;
2007-10-26 22:44:33 +00:00
# process the command line
my $ rc = & processArgs ;
if ( $ rc != 0 )
{
2007-11-26 20:09:18 +00:00
# rc: 0 - ok, 1 - return, 2 - help, 3 - error
if ( $ rc != 1 )
{
& defrm_usage ;
}
2007-10-26 22:44:33 +00:00
return ( $ rc - 1 ) ;
}
2007-11-26 20:09:18 +00:00
if ( $ ::opt_a && ! $ ::opt_f )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"You must use the \'-f\' option when using the \'-a\' option.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
& defrm_usage ;
return 1 ;
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
#
# build a hash of object names and their types
#
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# the list of objects to remove could have come from: the arg list,
# opt_o, a noderange, opt_t, or opt_a. (rmdef doesn't take file
# input)
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# if a set of objects was specifically provided on the cmd line then
# there can only be one type value
if ( $ ::objectsfrom_opto || $ ::objectsfrom_nr || $ ::objectsfrom_args )
{
my $ type = @ ::clobjtypes [ 0 ] ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
foreach my $ obj ( sort @ ::clobjnames )
{
$ objhash { $ obj } = $ type ;
}
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# if we derived a list of objects from a list of types
if ( $ ::objectsfrom_optt )
{
% objhash = % ::ObjTypeHash ;
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# if we derived the list of objects from the "all" option
if ( $ ::objectsfrom_opta )
{
% objhash = % ::AllObjTypeHash ;
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# handle the "-w" value - if provided
# the list of objects may be limited by the "-w" option
# see which objects have attr/val that match the where values
# - if provided
# !!!!! don't support -w for now - gets way too complicated with groups!!!!
if ( $ ::opt_w )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"The \'-w\' option is not supported for the rmdef command." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
$ error = 1 ;
return 1 ;
}
if ( 0 )
{
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# need to get object defs from DB
% myhash = xCAT::DBobjUtils - > getobjdefs ( \ % objhash ) ;
if ( ! defined ( % myhash ) )
{
$ error = 1 ;
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
foreach my $ obj ( sort ( keys % objhash ) )
{
foreach my $ testattr ( keys % ::WhereHash )
{
if ( $ myhash { $ obj } { $ testattr } eq $ ::WhereHash { $ testattr } )
{
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# add this object to the remove hash
$ rmhash { $ obj } = $ objhash { $ obj } ;
}
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
}
% objhash = % rmhash ;
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# if the object to remove is a group then the "groups" attr of
# the memberlist nodes must be updated.
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
my $ numobjects = 0 ;
foreach my $ obj ( keys % objhash )
{
$ numobjects + + ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
if ( $ objhash { $ obj } eq 'group' )
{
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# get the group object definition
$ ghash { $ obj } = 'group' ;
% grphash = xCAT::DBobjUtils - > getobjdefs ( \ % ghash ) ;
if ( ! defined ( % grphash ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Could not get xCAT object definition for \'$obj\'." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
next ;
}
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# get the members list
my $ memberlist = xCAT::DBobjUtils - > getGroupMembers ( $ obj , \ % grphash ) ;
my @ members = split ( ',' , $ memberlist ) ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# foreach member node of the group
my % nodehash ;
my % nhash ;
my @ gprslist ;
foreach my $ m ( @ members )
{
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# need to update the "groups" attr of the node def
# get the def of this node
$ nhash { $ m } = 'node' ;
% nodehash = xCAT::DBobjUtils - > getobjdefs ( \ % nhash ) ;
if ( ! defined ( % nodehash ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"Could not get xCAT object definition for \'$m\'." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
next ;
}
# split the "groups" to get a list
@ gprslist = split ( ',' , $ nodehash { $ m } { groups } ) ;
# make a new "groups" list for the node without the
# group that is being removed
my $ first = 1 ;
my $ newgrps ;
foreach my $ grp ( @ gprslist )
{
chomp ( $ grp ) ;
if ( $ grp eq $ obj )
{
next ;
}
else
{
# set new groups list for node
if ( ! $ first )
{
$ newgrps . = "," ;
}
$ newgrps . = $ grp ;
$ first = 0 ;
}
}
# make the change to %nodehash
$ nodehash { $ m } { groups } = $ newgrps ;
}
# set the new node attr values
if ( xCAT::DBobjUtils - > setobjdefs ( \ % nodehash ) != 0 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Could not write data to xCAT database." ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
}
}
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
# remove the objects
if ( xCAT::DBobjUtils - > rmobjdefs ( \ % objhash ) != 0 )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
$ error = 1 ;
2007-10-26 22:44:33 +00:00
}
2007-11-26 20:09:18 +00:00
if ( $ error )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"One or more errors occured when attempting to remove xCAT object definitions." ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 1 ;
}
else
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
if ( $ numobjects > 0 )
{
if ( $ ::verbose )
{
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
# give results
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "The following objects were removed:" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
my $ n = 1 ;
foreach my $ o ( sort ( keys % objhash ) )
{
$ rsp - > { data } - > [ $ n ] = "$o" ;
$ n + + ;
}
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
else
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Object definitions have been removed." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
}
else
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
"No objects have been removed from the xCAT database." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
return 0 ;
2007-10-26 22:44:33 +00:00
2007-11-26 20:09:18 +00:00
}
2007-10-26 22:44:33 +00:00
}
#----------------------------------------------------------------------------
= head3 defmk_usage
Arguments:
Returns:
Globals:
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
# subroutines to display the usage
sub defmk_usage
{
2007-11-26 20:09:18 +00:00
my $ rsp ;
2007-10-26 22:44:33 +00:00
$ rsp - > { data } - > [ 0 ] =
2007-11-26 20:09:18 +00:00
"\nUsage: mkdef - Create xCAT data object definitions.\n" ;
$ rsp - > { data } - > [ 1 ] = " mkdef [-h | --help ] [-t object-types]\n" ;
2007-10-26 22:44:33 +00:00
$ rsp - > { data } - > [ 2 ] =
2007-11-26 20:09:18 +00:00
" mkdef [-V | --verbose] [-t object-types] [-o object-names] [-z|--stanza ]" ;
2007-10-26 22:44:33 +00:00
$ rsp - > { data } - > [ 3 ] =
2007-11-26 20:09:18 +00:00
" [-x|--xml ] [-d | --dynamic] [-w attr=val,[attr=val...]]" ;
$ rsp - > { data } - > [ 4 ] =
" [-f | --force] [noderange] [attr=val [attr=val...]]\n" ;
$ rsp - > { data } - > [ 5 ] =
"\nThe following data object types are supported by xCAT.\n" ;
my $ n = 6 ;
foreach my $ t ( sort ( keys % { xCAT::Schema:: defspec } ) )
{
$ rsp - > { data } - > [ $ n ] = "$t" ;
$ n + + ;
}
$ rsp - > { data } - > [ $ n ] =
"\nUse the \'-h\' option together with the \'-t\' option to" ;
$ n + + ;
$ rsp - > { data } - > [ $ n ] =
"get a list of valid attribute names for each object type.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
return 0 ;
2007-10-26 22:44:33 +00:00
}
#----------------------------------------------------------------------------
= head3 defch_usage
Arguments:
Returns:
Globals:
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
sub defch_usage
{
2007-11-26 20:09:18 +00:00
my $ rsp ;
2007-10-26 22:44:33 +00:00
$ rsp - > { data } - > [ 0 ] =
2007-11-26 20:09:18 +00:00
"\nUsage: chdef - Change xCAT data object definitions.\n" ;
$ rsp - > { data } - > [ 1 ] = " chdef [-h | --help ] [-t object-types]\n" ;
2007-10-26 22:44:33 +00:00
$ rsp - > { data } - > [ 2 ] =
2007-11-26 20:09:18 +00:00
" chdef [-V | --verbose] [-t object-types] [-o object-names] [-d | --dynamic]" ;
2007-10-26 22:44:33 +00:00
$ rsp - > { data } - > [ 3 ] =
2007-11-26 20:09:18 +00:00
" [-z | --stanza] [-x | --xml] [-m | --minus] [-p | --plus]" ;
$ rsp - > { data } - > [ 4 ] =
" [-w attr=val,[attr=val...] ] [noderange] [attr=val [attr=val...]]\n" ;
$ rsp - > { data } - > [ 5 ] =
"\nThe following data object types are supported by xCAT.\n" ;
my $ n = 6 ;
foreach my $ t ( sort ( keys % { xCAT::Schema:: defspec } ) )
{
$ rsp - > { data } - > [ $ n ] = "$t" ;
$ n + + ;
}
$ rsp - > { data } - > [ $ n ] =
"\nUse the \'-h\' option together with the \'-t\' option to" ;
$ n + + ;
$ rsp - > { data } - > [ $ n ] =
"get a list of valid attribute names for each object type.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
return 0 ;
2007-10-26 22:44:33 +00:00
}
#----------------------------------------------------------------------------
= head3 defls_usage
Arguments:
Returns:
Globals:
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
sub defls_usage
{
2007-11-26 20:09:18 +00:00
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "\nUsage: lsdef - List xCAT data object definitions.\n" ;
$ rsp - > { data } - > [ 1 ] = " lsdef [-h | --help ] [-t object-types]\n" ;
2007-10-26 22:44:33 +00:00
$ rsp - > { data } - > [ 2 ] =
2007-11-26 20:09:18 +00:00
" lsdef [-V | --verbose] [-t object-types] [-o object-names]" ;
2007-10-26 22:44:33 +00:00
$ rsp - > { data } - > [ 3 ] =
2007-11-26 20:09:18 +00:00
" [ -l | --long] [-a | --all] [-z | --stanza ] [-x | --xml ]" ;
$ rsp - > { data } - > [ 4 ] =
" [-i attr-list] [-w attr=val,[attr=val...]] [noderange]\n" ;
$ rsp - > { data } - > [ 5 ] =
"\nThe following data object types are supported by xCAT.\n" ;
my $ n = 6 ;
foreach my $ t ( sort ( keys % { xCAT::Schema:: defspec } ) )
{
$ rsp - > { data } - > [ $ n ] = "$t" ;
$ n + + ;
}
$ rsp - > { data } - > [ $ n ] =
"\nUse the \'-h\' option together with the \'-t\' option to" ;
$ n + + ;
$ rsp - > { data } - > [ $ n ] =
"get a list of valid attribute names for each object type.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
return 0 ;
2007-10-26 22:44:33 +00:00
}
#----------------------------------------------------------------------------
= head3 defrm_usage
Arguments:
Returns:
Globals:
Error:
Example:
Comments:
= cut
#-----------------------------------------------------------------------------
sub defrm_usage
{
2007-11-26 20:09:18 +00:00
my $ rsp ;
2007-10-26 22:44:33 +00:00
$ rsp - > { data } - > [ 0 ] =
2007-11-26 20:09:18 +00:00
"\nUsage: rmdef - Remove xCAT data object definitions.\n" ;
$ rsp - > { data } - > [ 1 ] = " rmdef [-h | --help ] [-t object-types]\n" ;
2007-10-26 22:44:33 +00:00
$ rsp - > { data } - > [ 2 ] =
2007-11-26 20:09:18 +00:00
" rmdef [-V | --verbose] [-t object-types] [-a | --all] [-f | --force]" ;
$ rsp - > { data } - > [ 3 ] =
" [-o object-names] [-w attr=val,[attr=val...] [noderange]\n" ;
$ rsp - > { data } - > [ 4 ] =
"\nThe following data object types are supported by xCAT.\n" ;
my $ n = 5 ;
foreach my $ t ( sort ( keys % { xCAT::Schema:: defspec } ) )
{
$ rsp - > { data } - > [ $ n ] = "$t" ;
$ n + + ;
}
$ rsp - > { data } - > [ $ n ] =
"\nUse the \'-h\' option together with the \'-t\' option to" ;
$ n + + ;
$ rsp - > { data } - > [ $ n ] =
"get a list of valid attribute names for each object type.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
return 0 ;
2007-10-26 22:44:33 +00:00
}
1 ;
2007-11-26 20:09:18 +00:00