2008-07-09 16:10:10 +00:00
#!/usr/bin/env perl -w
2007-10-26 22:44:33 +00:00
# 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 ;
2009-06-30 09:47:48 +00:00
use xCAT::Utils ;
2008-07-09 16:10:10 +00:00
use strict ;
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:: 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
2008-02-21 21:10:35 +00:00
This program module file supports the management of the xCAT data object
2007-10-26 22:44:33 +00:00
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:
2008-02-21 21:10:35 +00:00
2007-10-26 22:44:33 +00:00
Returns:
0 - OK
1 - error
Globals:
2008-02-21 21:10:35 +00:00
2007-10-26 22:44:33 +00:00
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 ;
}
2008-07-09 16:10:10 +00:00
my $ rsp ;
2007-10-26 22:44:33 +00:00
if ( $ msg )
{
$ rsp - > { data } - > [ 0 ] = $ msg ;
$ ::callback - > ( $ rsp ) ;
}
2008-03-07 21:01:32 +00:00
if ( $ ret > 0 ) {
$ rsp - > { errorcode } - > [ 0 ] = $ ret ;
}
2007-10-26 22:44:33 +00:00
}
#----------------------------------------------------------------------------
= 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:
2008-02-21 21:10:35 +00:00
2007-10-26 22:44:33 +00:00
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
2008-06-25 15:37:19 +00:00
if ( defined ( @ { $ ::args } ) ) {
@ ARGV = @ { $ ::args } ;
} else {
return 2 ;
}
2008-02-21 21:10:35 +00:00
2008-01-22 13:41:44 +00:00
if ( scalar ( @ ARGV ) <= 0 ) {
return 2 ;
}
2007-10-26 22:44:33 +00:00
# parse the options - include any option from all 4 cmds
2008-03-07 21:01:32 +00:00
Getopt::Long:: Configure ( "no_pass_through" ) ;
2007-10-26 22:44:33 +00:00
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 ,
2008-02-21 19:16:33 +00:00
'help|h|?' = > \ $ ::opt_h ,
2007-10-26 22:44:33 +00:00
'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 ,
2009-06-30 09:47:48 +00:00
'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." ;
2009-06-09 08:30:49 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
2007-11-26 20:09:18 +00:00
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
2009-06-15 09:29:56 +00:00
if ( ( $ ::command ne 'mkdef' ) && ( $ a =~ m/^\// ) )
{
@ ::noderange = & noderange ( $ a , 1 ) ; # Use the "verify" option to support regular expression
}
else
{
@ ::noderange = & noderange ( $ a , 0 ) ; # mkdef could not spport regular expression
}
2007-11-26 20:09:18 +00:00
}
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 ;
2008-06-24 16:22:55 +00:00
my $ version = xCAT::Utils - > Version ( ) ;
push @ { $ rsp - > { data } } , "$::command - $version\n" ;
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 ;
2009-03-22 19:15:19 +00:00
} else {
$ ::verbose = 0 ;
$ ::VERBOSE = 0 ;
}
2007-11-26 20:09:18 +00:00
#
# 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 )
{
2009-07-21 19:36:14 +00:00
if ( ! grep ( /^$t$/ , @ xdeftypes ) )
2007-11-26 20:09:18 +00:00
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
2009-05-07 13:58:00 +00:00
"\nType \'$t\' is not a valid xCAT object type." ;
2009-06-09 08:30:49 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
2009-05-07 13:58:00 +00:00
return 3 ;
2007-11-26 20:09:18 +00:00
}
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 ;
2008-01-29 13:17:35 +00:00
if ( ! $ ::opt_z && ! $ ::opt_x ) {
# don't want this msg in stanza or xml output
2008-04-16 18:01:36 +00:00
#$rsp->{data}->[0] = "Assuming an object type of \'node\'.\n";
#xCAT::MsgUtils->message("I", $rsp, $::callback);
2008-01-29 13:17:35 +00:00
}
2007-11-26 20:09:18 +00:00
}
# 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
my $ rsp ;
2009-03-20 18:46:11 +00:00
if ( $ t eq 'site' ) {
my $ schema = xCAT::Table - > getTableSchema ( 'site' ) ;
my $ desc ;
2009-03-22 19:15:19 +00:00
$ rsp - > { data } - > [ 0 ] = "\nThere can only be one xCAT site definition. This definition consists \nof an unlimited list of user-defined attributes and values that represent \nglobal settings for the whole cluster. The following is a list \nof the attributes currently supported by xCAT.\n" ;
2009-03-20 18:46:11 +00:00
$ desc = $ schema - > { descriptions } - > { 'key' } ;
$ rsp - > { data } - > [ 1 ] = $ desc ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
next ;
}
# get the data type definition from Schema.pm
2007-11-26 20:09:18 +00:00
my $ datatype = $ xCAT:: Schema:: defspec { $ t } ;
2009-03-20 18:46:11 +00:00
$ rsp - > { data } - > [ 0 ] = "The valid attribute names for object type '$t' are:\n" ;
2007-11-26 20:09:18 +00:00
# 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
2008-07-29 17:43:47 +00:00
my @ attrlist ;
2008-01-21 20:35:16 +00:00
my $ outstr = "" ;
2008-02-12 14:00:20 +00:00
2008-07-09 16:10:10 +00:00
foreach my $ this_attr ( @ { $ datatype - > { 'attrs' } } )
2007-11-26 20:09:18 +00:00
{
my $ attr = $ this_attr - > { attr_name } ;
my $ desc = $ this_attr - > { description } ;
2008-07-29 17:43:47 +00:00
if ( ! defined ( $ desc ) ) {
# description key not there, so go to the corresponding
# entry in tabspec to get the description
2008-02-21 21:10:35 +00:00
my ( $ tab , $ at ) = split ( /\./ , $ this_attr - > { tabentry } ) ;
my $ schema = xCAT::Table - > getTableSchema ( $ tab ) ;
$ desc = $ schema - > { descriptions } - > { $ at } ;
}
2007-11-26 20:09:18 +00:00
2008-02-21 21:10:35 +00:00
# could display the table that the attr is in
2008-02-12 14:00:20 +00:00
# however some attrs are in more than one table!!!
2008-02-21 21:10:35 +00:00
#my ($tab, $junk) = split('\.', $this_attr->{tabentry});
2008-02-12 14:00:20 +00:00
2007-11-26 20:09:18 +00:00
if ( ! grep ( /^$attr$/ , @ alreadydone ) )
2008-02-21 21:10:35 +00:00
{
my $ space = ( length ( $ attr ) < 7 ? "\t\t" : "\t" ) ;
2008-07-29 17:43:47 +00:00
push ( @ attrlist , "$attr:$space$desc\n\n" ) ;
2007-11-26 20:09:18 +00:00
}
push ( @ alreadydone , $ attr ) ;
}
2008-02-21 21:10:35 +00:00
2008-07-29 17:43:47 +00:00
# print the output in alphabetical order
foreach my $ a ( sort @ attrlist ) {
$ outstr . = "$a" ;
}
chop ( $ outstr ) ; chop ( $ outstr ) ;
2008-01-21 20:35:16 +00:00
$ rsp - > { data } - > [ 2 ] = $ outstr ;
2008-06-24 16:22:55 +00:00
# the monitoring table is special
if ( $ t eq 'monitoring' ) {
$ rsp - > { data } - > [ 3 ] = "\nYou can also include additional monitoring plug-in specific settings. These settings will be used by the monitoring plug-in to customize the behavior such as event filter, sample interval, responses etc.\n" ;
}
2007-11-26 20:09:18 +00:00
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' ) ;
2008-02-21 21:10:35 +00:00
my $ rsp ;
2007-11-26 20:09:18 +00:00
$ rsp - > { data } - > [ 0 ] = "Only one site definition is supported." ;
$ rsp - > { data } - > [ 1 ] = "Setting the name of the site definition to \'clustersite\'.\n" ;
2008-02-21 21:10:35 +00:00
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
2007-11-26 20:09:18 +00:00
}
elsif ( $ ::opt_t eq 'node' )
2007-10-26 22:44:33 +00:00
{
2009-06-15 09:29:56 +00:00
if ( ( $ ::command ne 'mkdef' ) && ( $ a =~ m/^\// ) )
{
@ ::clobjnames = & noderange ( $ ::opt_o , 1 ) ; #Use the "verify" option to support regular expression
}
else
{
@ ::clobjnames = & noderange ( $ ::opt_o , 0 ) ; #mkdef can not support regular expression
}
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 )
{
2008-02-21 21:10:35 +00:00
my $ rsp ;
2007-11-26 20:09:18 +00:00
$ 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" ;
2009-05-07 13:58:00 +00:00
#$rsp->{data}->[1] = "Skipping to the next type.\n";
2009-06-09 08:30:49 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
2009-05-07 13:58:00 +00:00
return 3 ;
2007-11-26 20:09:18 +00:00
}
}
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) -
2008-08-22 14:07:55 +00:00
if ( ( scalar ( @ ::clobjnames ) == 0 ) && ( scalar ( @ ::fileobjnames ) == 0 ) )
2007-10-26 22:44:33 +00:00
{
2007-11-26 20:09:18 +00:00
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 ;
2008-08-22 14:07:55 +00:00
if ( scalar ( @ ::fileobjnames ) > 0 )
2007-10-26 22:44:33 +00:00
{
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 ;
}
2008-08-22 14:07:55 +00:00
elsif ( scalar ( @ ::objfilelist ) > 0 )
2007-11-26 20:09:18 +00:00
{
# add list from "-f" file option
push @ ::allobjnames , @ ::objfilelist ;
}
# check for the -w option
if ( $ ::opt_w )
{
2009-06-30 09:47:48 +00:00
my $ rc = xCAT::Utils - > parse_selection_string ( $ ::opt_w , \ % ::WhereHash ) ;
if ( $ rc != 0 )
2007-11-26 20:09:18 +00:00
{
2009-06-30 09:47:48 +00:00
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Incorrect selection string specified with -w flag\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 3 ;
2007-11-26 20:09:18 +00:00
}
}
# 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:
2008-02-21 21:10:35 +00:00
Object names to create are derived from
2007-10-26 22:44:33 +00:00
- 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
2008-07-09 16:10:10 +00:00
my % objTypeLists ;
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 ;
}
2008-02-28 19:28:41 +00:00
# can't have -z with other obj sources
if ( $ ::opt_z && ( $ ::opt_o || @ ::noderange ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Cannot use \'-z\' with \'-o\' or a noderange." ;
$ rsp - > { data } - > [ 1 ] = "Example of -z usage:\n\t\'cat stanzafile | mkdef -z\'\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
& defmk_usage ;
return 1 ;
}
2007-11-26 20:09:18 +00:00
# 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" ;
2009-06-09 08:30:49 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
2007-11-26 20:09:18 +00:00
& 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 )
{
2009-07-21 19:36:14 +00:00
if ( ! grep ( /^$attr$/ , @ list ) && ( $ ::objtype ne 'site' ) && ( $ ::objtype ne 'monitoring' ) )
2007-11-26 20:09:18 +00:00
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
2009-07-24 03:40:40 +00:00
"\'$attr\' is not a valid attribute name for an object type of \'$::objtype\'.\n" ;
2007-11-26 20:09:18 +00:00
$ rsp - > { data } - > [ 1 ] = "Skipping to the next attribute.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
next ;
}
else
{
$ ::CLIATTRS { $ objname } { $ attr } = $ ::ATTRS { $ attr } ;
2008-11-10 03:11:12 +00:00
if ( $ ::verbose )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "\nFunction: defmk-->set the attrs for each object definition" ;
$ rsp - > { data } - > [ 1 ] = "defmk: objname=$objname, attr=$attr, value=$::ATTRS{$attr}" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
2007-11-26 20:09:18 +00:00
}
} # 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
}
2008-11-10 03:11:12 +00:00
if ( $ ::verbose )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "\ndefmk: list objects that are defined for each type" ;
$ rsp - > { data } - > [ 1 ] = "@{$objTypeLists{$t}}\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
2007-11-26 20:09:18 +00:00
}
2007-10-26 22:44:33 +00:00
2009-05-07 13:58:00 +00:00
OBJ: foreach my $ obj ( keys % ::FINALATTRS )
2007-11-26 20:09:18 +00:00
{
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 ) ;
2009-08-07 01:18:17 +00:00
$ error = 1 ;
2007-10-26 22:44:33 +00:00
next ;
}
2009-05-07 13:58:00 +00:00
# we don't want to overwrite any existing table row. This could
# happen if there are multiple table keys. (ex. networks table -
# where the object name is not either of the table keys - net
# & mask)
# just handle network objects for now -
if ( $ type eq 'network' ) {
my @ nets = xCAT::DBobjUtils - > getObjectsOfType ( 'network' ) ;
my % objhash ;
foreach my $ n ( @ nets ) {
$ objhash { $ n } = $ type ;
}
my % nethash = xCAT::DBobjUtils - > getobjdefs ( \ % objhash ) ;
foreach my $ o ( keys % nethash ) {
2009-05-15 13:00:18 +00:00
if ( ( $ nethash { $ o } { net } eq $ ::FINALATTRS { $ obj } { net } ) && ( $ nethash { $ o } { mask } eq $ ::FINALATTRS { $ obj } { mask } ) ) {
2009-05-07 13:58:00 +00:00
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "A network definition called \'$o\' already exists that contains the same net and mask values. Cannot create a definition for \'$obj\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
2009-05-15 13:00:18 +00:00
delete $ ::FINALATTRS { $ obj } ;
2009-05-07 13:58:00 +00:00
next OBJ ;
}
}
}
2007-11-26 20:09:18 +00:00
# if object already exists
2009-04-22 17:29:11 +00:00
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
2008-07-09 16:10:10 +00:00
my % objhash ;
2007-11-26 20:09:18 +00:00
$ 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 )
{
2009-08-07 02:09:33 +00:00
# For dynamic node group,
# can not assign attributes for inherit
# only the 'objtype' in %::FINALATTRS
if ( scalar ( keys % { $ ::FINALATTRS { $ obj } } ) > 1 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Can not assign attributes to dynamic node group \'$obj\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
next ;
}
2007-11-26 20:09:18 +00:00
$ ::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 )
{
2009-06-30 09:47:48 +00:00
$ ::FINALATTRS { $ obj } { wherevals } = join ( '::' , @ { $ ::opt_w } ) ;
#$::FINALATTRS{$obj}{wherevals} = $::opt_w;
2007-11-26 20:09:18 +00:00
}
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
2008-07-09 16:10:10 +00:00
my % objhash ;
2007-11-26 20:09:18 +00:00
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 )
{
2009-06-30 09:47:48 +00:00
if ( xCAT::Utils - > selection_string_match ( \ % myhash , $ objname , \ % ::WhereHash ) ) {
2007-11-26 20:09:18 +00:00
push ( @ memberlist , $ objname ) ;
}
}
}
else
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
2008-02-12 14:00:20 +00:00
"Cannot determine a member list for group \'$obj\'.\n" ;
2009-06-09 08:30:49 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
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 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 )
{
2008-11-10 03:11:12 +00:00
if ( $ ::verbose )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "defmk: add group name [$n] to nodelist table" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
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
2008-07-09 16:10:10 +00:00
#$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 ;
}
2008-02-28 19:05:31 +00:00
} # end - if group type
2007-11-26 20:09:18 +00:00
2008-10-12 17:43:32 +00:00
#
# 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
2009-05-15 02:29:28 +00:00
# getObjectsOfType("group") only returns static groups,
# generally speaking, the nodegroup table should includes all the static and dynamic groups,
# but it is possible that the static groups are not in nodegroup table,
# so we have to get the static and dynamic groups separately.
my @ definedgroups = xCAT::DBobjUtils - > getObjectsOfType ( "group" ) ; #static groups
my $ grptab = xCAT::Table - > new ( 'nodegroup' ) ;
my @ grplist = @ { $ grptab - > getAllEntries ( ) } ; #dynamic groups and static groups in nodegroup table
2008-10-12 17:43:32 +00:00
my % GroupHash ;
foreach my $ g ( @ grouplist )
{
2009-05-15 02:29:28 +00:00
my $ indynamicgrp = 0 ;
#check the dynamic node groups
foreach my $ grpdef_ref ( @ grplist )
2008-10-12 17:43:32 +00:00
{
2009-05-15 02:29:28 +00:00
my % grpdef = %$ grpdef_ref ;
if ( ( $ grpdef { 'groupname' } eq $ g ) && ( $ grpdef { 'grouptype' } eq 'dynamic' ) )
{
$ indynamicgrp = 1 ;
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "nodegroup $g is a dynamic node group, should not add a node into a dynamic node group statically.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
last ;
}
}
if ( ! $ indynamicgrp )
{
if ( ! grep ( /^$g$/ , @ definedgroups ) )
{
# define it
$ GroupHash { $ g } { objtype } = "group" ;
$ GroupHash { $ g } { grouptype } = "static" ;
$ GroupHash { $ g } { members } = "static" ;
}
2008-10-12 17:43:32 +00:00
}
}
if ( defined ( % GroupHash ) )
{
2008-11-10 03:11:12 +00:00
if ( $ ::verbose )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Write GroupHash: %GroupHash to xCAT database\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
2008-10-12 17:43:32 +00:00
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
2009-05-14 09:35:08 +00:00
# If none of the attributes in nodelist is defined: groups,status,appstatus,primarysn,comments,disable
# the nodelist table will not be updated, caused mkdef failed.
# We can give a restriction that the "groups" must be specified with mkdef,
# but it is not so reasonable especially when the dynamic node group feature is implemented.
# fixing this issue with specifying an empty "groups" if the "groups" is not specified with the command line or stanza file
if ( ( $ type eq "node" ) && ! defined ( $ ::FINALATTRS { $ obj } { groups } ) )
{
$ ::FINALATTRS { $ obj } { groups } = '' ;
}
2008-10-12 17:43:32 +00:00
} # end of each obj
2007-11-26 20:09:18 +00:00
#
# 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:
2008-02-21 21:10:35 +00:00
Object names to create are derived from
2007-11-26 20:09:18 +00:00
- 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 ;
2008-02-28 19:05:31 +00:00
my $ firsttime = 1 ;
2007-11-26 20:09:18 +00:00
2008-07-09 16:10:10 +00:00
my % objTypeLists ;
2007-11-26 20:09:18 +00:00
# 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 ;
}
2008-02-28 19:28:41 +00:00
# can't have -z with other obj sources
if ( $ ::opt_z && ( $ ::opt_o || @ ::noderange ) )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Cannot use \'-z\' with \'-o\' or a noderange." ;
$ rsp - > { data } - > [ 1 ] = "Example of -z usage:\n\t\'cat stanzafile | chdef -z\'\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
& defch_usage ;
return 1 ;
}
2007-11-26 20:09:18 +00:00
# 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" ;
2009-06-09 08:30:49 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
2007-11-26 20:09:18 +00:00
& 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 )
{
2009-07-21 19:36:14 +00:00
if ( ! grep ( /^$attr$/ , @ list ) && ( $ ::objtype ne 'site' ) && ( $ ::objtype ne 'monitoring' ) )
2007-11-26 20:09:18 +00:00
{
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 ) ;
}
2008-11-10 03:11:12 +00:00
if ( $ ::verbose )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "\ndefch: list objects that are defined for each type" ;
$ rsp - > { data } - > [ 1 ] = "@{$objTypeLists{$t}}\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
}
2007-11-26 20:09:18 +00:00
}
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 ;
}
2009-07-21 19:36:14 +00:00
if ( grep ( /^$obj$/ , @ { $ objTypeLists { $ type } } ) )
2007-11-26 20:09:18 +00:00
{
$ isDefined = 1 ;
}
2008-02-28 19:05:31 +00:00
2008-07-09 16:10:10 +00:00
if ( ! $ isDefined && $ ::opt_m )
2007-11-26 20:09:18 +00:00
{
#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 ;
2008-07-09 16:10:10 +00:00
my % objhash ;
2009-08-07 02:09:33 +00:00
if ( $ ::opt_d )
{
# For dynamic node group,
# can not assign attributes for inherit
# only the 'objtype' in %::FINALATTRS
if ( scalar ( keys % { $ ::FINALATTRS { $ obj } } ) > 1 )
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Can not assign attributes to dynamic node group \'$obj\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
next ;
}
}
2007-11-26 20:09:18 +00:00
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 ;
}
2009-06-23 05:51:28 +00:00
$ grptype = $ grphash { $ obj } { grouptype } ;
2008-02-28 19:05:31 +00:00
# for now all groups are static
2009-06-23 05:51:28 +00:00
#$grptype = 'static';
2007-11-26 20:09:18 +00:00
}
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 )
{
2009-06-30 09:47:48 +00:00
$ ::FINALATTRS { $ obj } { wherevals } = join ( '::' , @ { $ ::opt_w } ) ;
#$::FINALATTRS{$obj}{wherevals} = $::opt_w;
2007-11-26 20:09:18 +00:00
}
}
# 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
2008-07-09 16:10:10 +00:00
my % objhash ;
2007-11-26 20:09:18 +00:00
foreach my $ n ( @ tmplist )
{
$ objhash { $ n } = 'node' ;
}
# get all the attrs for these nodes
my % myhash = xCAT::DBobjUtils - > getobjdefs ( \ % objhash ) ;
2009-06-30 09:47:48 +00:00
# get a list of attr=val pairs, is it really necessary??
my @ wherevals = split ( /::/ , $ ::FINALATTRS { $ obj } { wherevals } ) ;
my $ rc = xCAT::Utils - > parse_selection_string ( \ @ wherevals , \ % ::WhereHash ) ;
if ( $ rc != 0 )
2007-11-26 20:09:18 +00:00
{
2009-06-30 09:47:48 +00:00
my $ rsp ;
2009-07-06 09:45:22 +00:00
$ rsp - > { data } - > [ 0 ] = "Incorrect selection string" ;
2009-06-30 09:47:48 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
return 3 ;
2007-11-26 20:09:18 +00:00
}
# see which ones match the where values
foreach my $ objname ( keys % myhash )
{
2009-06-30 09:47:48 +00:00
if ( xCAT::Utils - > selection_string_match ( \ % myhash , $ objname , \ % ::WhereHash ) ) {
2007-11-26 20:09:18 +00:00
push ( @ memberlist , $ objname ) ;
}
2009-06-30 09:47:48 +00:00
2007-11-26 20:09:18 +00:00
}
}
} # 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 ;
2008-07-09 16:10:10 +00:00
foreach my $ n ( @ memberlist )
2007-11-26 20:09:18 +00:00
{
2008-02-28 19:05:31 +00:00
2007-11-26 20:09:18 +00:00
$ 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 ;
2008-07-09 16:10:10 +00:00
foreach my $ n ( @ memberlist )
2007-11-26 20:09:18 +00:00
{
$ 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 ;
2008-07-09 16:10:10 +00:00
foreach my $ n ( @ memberlist )
2007-11-26 20:09:18 +00:00
{
$ 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
2008-02-28 19:05:31 +00:00
if ( $ firsttime ) {
2007-11-26 20:09:18 +00:00
# get the current members list
2008-02-28 19:05:31 +00:00
$ grphash { $ obj } { 'grouptype' } = "static" ;
2007-11-26 20:09:18 +00:00
my $ list =
xCAT::DBobjUtils - > getGroupMembers ( $ obj , \ % grphash ) ;
my @ currentlist = split ( ',' , $ list ) ;
# for each node in currentlist - remove group name
# from groups attr
my % membhash ;
2008-07-09 16:10:10 +00:00
foreach my $ n ( @ currentlist )
2007-11-26 20:09:18 +00:00
{
$ membhash { $ n } { groups } = $ obj ;
$ membhash { $ n } { objtype } = 'node' ;
}
$ ::plus_option = 0 ;
$ ::minus_option = 1 ;
if ( xCAT::DBobjUtils - > setobjdefs ( \ % membhash ) != 0 )
{
$ error = 1 ;
}
2008-02-28 19:05:31 +00:00
$ firsttime = 0 ;
} # end - first time
2007-11-26 20:09:18 +00:00
$ ::minus_option = 0 ;
# for each node in memberlist add this group
# name to the groups attr
my % membhash ;
2008-07-09 16:10:10 +00:00
foreach my $ n ( @ memberlist )
2007-11-26 20:09:18 +00:00
{
$ 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
2009-05-15 02:29:28 +00:00
# getObjectsOfType("group") only returns static groups,
# generally speaking, the nodegroup table should includes all the static and dynamic groups,
# but it is possible that the static groups are not in nodegroup table,
# so we have to get the static and dynamic groups separately.
my @ definedgroups = xCAT::DBobjUtils - > getObjectsOfType ( "group" ) ; #Static node groups
my $ grptab = xCAT::Table - > new ( 'nodegroup' ) ;
my @ grplist = @ { $ grptab - > getAllEntries ( ) } ; #dynamic groups and static groups in nodegroup table
2007-11-26 20:09:18 +00:00
# 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
2008-07-09 16:10:10 +00:00
my % GroupHash ;
2007-11-26 20:09:18 +00:00
foreach my $ g ( @ grouplist )
{
2009-05-15 02:29:28 +00:00
my $ indynamicgrp = 0 ;
#check the dynamic node groups
foreach my $ grpdef_ref ( @ grplist )
{
my % grpdef = %$ grpdef_ref ;
if ( ( $ grpdef { 'groupname' } eq $ g ) && ( $ grpdef { 'grouptype' } eq 'dynamic' ) )
{
$ indynamicgrp = 1 ;
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "nodegroup $g is a dynamic node group, should not add a node into a dynamic node group statically.\n" ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
last ;
}
}
if ( ! $ indynamicgrp )
2007-11-26 20:09:18 +00:00
{
2009-05-15 02:29:28 +00:00
if ( ! grep ( /^$g$/ , @ definedgroups ) )
{
2007-11-26 20:09:18 +00:00
2009-05-15 02:29:28 +00:00
# define it
$ GroupHash { $ g } { objtype } = "group" ;
$ GroupHash { $ g } { grouptype } = "static" ;
$ GroupHash { $ g } { members } = "static" ;
}
2007-11-26 20:09:18 +00:00
}
}
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
2009-08-06 01:33:14 +00:00
#special case for osimage, if the osimage was not defined,
#chdef can not create it correctly if no attribute in osimage table is defined
#set the default imagetype 'NIM' if it is not specified
if ( ( ! $ isDefined ) && ( $ type eq 'osimage' ) && ( ! defined ( $ ::FINALATTRS { $ obj } { imagetype } ) ) )
{
$ ::FINALATTRS { $ obj } { imagetype } = 'NIM' ;
}
2008-10-12 17:43:32 +00:00
2007-11-26 20:09:18 +00:00
} # 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
{
2009-07-21 19:36:14 +00:00
if ( ! grep ( /^$::FILEATTRS{$objname}{objtype}$/ , @ ::clobtypes ) )
2007-11-26 20:09:18 +00:00
{
next ;
}
}
# get the data type definition from Schema.pm
2009-01-29 18:42:59 +00:00
if ( ! $ ::FILEATTRS { $ objname } { objtype } ) {
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "\nNo objtype value was specified for \'$objname\'. Cannot create object definition.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
$ error = 1 ;
next ;
}
2007-11-26 20:09:18 +00:00
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
2009-07-21 19:36:14 +00:00
if ( ! grep ( /^$attr$/ , @ list ) && ( $ ::FILEATTRS { $ objname } { objtype } ne 'site' ) && ( $ ::FILEATTRS { $ objname } { objtype } ne 'monitoring' ) )
2007-11-26 20:09:18 +00:00
{
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
}
2008-06-07 14:12:13 +00:00
# need to make sure the node attr is set otherwise nothing
# gets set in the nodelist table
if ( $ ::FINALATTRS { $ objname } { objtype } eq "node" ) {
$ ::FINALATTRS { $ objname } { node } = $ objname ;
}
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 (
2009-07-21 19:36:14 +00:00
! grep ( /^$::FINALATTRS{$objname}{objtype}$/ , @ ::finalTypeList )
2007-11-26 20:09:18 +00:00
)
{
my $ type = $ ::FINALATTRS { $ objname } { objtype } ;
chomp $ type ;
push @ ::finalTypeList , $ type ;
}
}
2008-06-07 14:12:13 +00:00
}
# need to make sure the node attr is set otherwise nothing
# gets set in the nodelist table
if ( $ ::FINALATTRS { $ objname } { objtype } eq "node" ) {
$ ::FINALATTRS { $ objname } { node } = $ objname ;
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 )
2008-02-21 21:10:35 +00:00
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 ;
2008-07-09 16:10:10 +00:00
my @ displayObjList ;
2007-11-26 20:09:18 +00:00
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 + + ;
}
2008-04-15 16:48:53 +00:00
# which attrs do we want?
# this is a temp hack to help scaling when you only
# want a list of nodes - needs to be fully implemented
if ( $ ::opt_l || $ ::opt_w ) {
# if long or -w then get all the attrs
$ ::ATTRLIST = "all" ;
} elsif ( $ ::opt_i ) {
# is -i then just get the ones in the list
$ ::ATTRLIST = $ ::opt_i ;
} elsif ( @ ::noderange || $ ::opt_o ) {
# if they gave a list of objects then they must want more
# than the object names!
$ ::ATTRLIST = "all" ;
} else {
# otherwise just get a list of object names
$ ::ATTRLIST = "none" ;
}
2007-11-26 20:09:18 +00:00
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 ;
}
2009-03-22 19:15:19 +00:00
% myhash = xCAT::DBobjUtils - > getobjdefs ( \ % objhash , $ ::VERBOSE ) ;
2007-11-26 20:09:18 +00:00
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 ;
2009-03-22 19:15:19 +00:00
% myhash = xCAT::DBobjUtils - > getobjdefs ( \ % objhash , $ ::VERBOSE ) ;
2007-11-26 20:09:18 +00:00
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 )
{
2008-07-09 16:10:10 +00:00
my @ tmplist = xCAT::DBobjUtils - > getObjectsOfType ( $ t ) ;
2007-11-26 20:09:18 +00:00
if ( scalar ( @ tmplist ) > 1 )
{
foreach my $ obj ( @ tmplist )
{
$ objhash { $ obj } = $ t ;
}
}
else
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
2008-07-09 16:10:10 +00:00
"Could not get objects of type \'$t\'.\n" ;
2007-11-26 20:09:18 +00:00
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
{
2009-03-22 19:15:19 +00:00
% myhash = xCAT::DBobjUtils - > getobjdefs ( \ % ::AllObjTypeHash , $ ::VERBOSE ) ;
2007-11-26 20:09:18 +00:00
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 ) ;
}
2008-02-28 19:05:31 +00:00
} # end - if specify all
2007-11-26 20:09:18 +00:00
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
2009-08-07 04:26:25 +00:00
# need a special case for the node postscripts attribute,
# The 'xcatdefaults' postscript should be added to the postscript attribute
my $ getnodes = 0 ;
2009-08-07 04:34:10 +00:00
if ( ! $ ::opt_z ) { #if -z flag is specified, do not add the xcatdefaults
foreach my $ objtype ( @ ::clobjtypes )
2009-08-07 04:26:25 +00:00
{
2009-08-07 04:34:10 +00:00
if ( $ objtype eq 'node' )
{
$ getnodes = 1 ;
last ;
}
2009-08-07 04:26:25 +00:00
}
}
if ( $ getnodes )
{
my $ xcatdefaultsps ;
my @ TableRowArray = xCAT::DBobjUtils - > getDBtable ( 'postscripts' ) ;
if ( defined ( @ TableRowArray ) )
{
foreach my $ tablerow ( @ TableRowArray )
{
if ( ( $ tablerow - > { node } eq 'xcatdefaults' ) && ! ( $ tablerow - > { disable } ) )
{
$ xcatdefaultsps = $ tablerow - > { postscripts } ;
last ;
}
}
}
foreach my $ obj ( keys % myhash )
{
if ( $ myhash { $ obj } { objtype } eq 'node' )
{
if ( $ xcatdefaultsps )
{
if ( $ myhash { $ obj } { postscripts } )
{
$ myhash { $ obj } { postscripts } = $ xcatdefaultsps . ',' . $ myhash { $ obj } { postscripts } ;
}
else
{
$ myhash { $ obj } { postscripts } = $ xcatdefaultsps ;
}
}
}
}
}
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
{
2009-06-30 09:47:48 +00:00
if ( xCAT::Utils - > selection_string_match ( \ % myhash , $ obj , \ % ::WhereHash ) ) {
2007-11-26 20:09:18 +00:00
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
2008-02-28 19:05:31 +00:00
# for each type
2007-11-26 20:09:18 +00:00
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
2008-02-28 19:05:31 +00:00
# for each object
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 ;
}
2008-02-28 19:05:31 +00:00
# if anything but the site table do this
2007-11-26 20:09:18 +00:00
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 ;
}
2008-08-22 14:07:55 +00:00
if ( ! grep ( /^$obj$/ , @ tmplist ) )
2007-11-26 20:09:18 +00:00
{
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
2008-02-28 19:05:31 +00:00
#
2007-11-26 20:09:18 +00:00
# special handling for site table - for now !!!!!!!
2008-02-28 19:05:31 +00:00
#
2007-11-26 20:09:18 +00:00
my @ attrlist ;
2008-06-24 16:22:55 +00:00
if ( ( $ defhash { $ obj } { 'objtype' } eq 'site' ) || ( $ defhash { $ obj } { 'objtype' } eq 'monitoring' ) )
2007-11-26 20:09:18 +00:00
{
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' } } ;
2008-01-28 13:03:58 +00:00
my @ alreadydone ;
2008-07-09 16:10:10 +00:00
foreach my $ this_attr ( @ { $ datatype - > { 'attrs' } } )
2007-11-26 20:09:18 +00:00
{
2008-01-28 13:03:58 +00:00
if ( ! grep ( /^$this_attr->{attr_name}$/ , @ alreadydone ) ) {
push ( @ attrlist , $ this_attr - > { attr_name } ) ;
}
push ( @ alreadydone , $ this_attr - > { attr_name } ) ;
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 ( $ ::opt_x )
2007-10-26 22:44:33 +00:00
{
2008-02-28 19:05:31 +00:00
# TBD - 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 ;
}
2009-03-20 18:46:11 +00:00
if ( exists ( $ myhash { $ obj } { $ showattr } ) )
2007-11-26 20:09:18 +00:00
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
" $showattr=$defhash{$obj}{$showattr}" ;
xCAT::MsgUtils - > message ( "I" , $ rsp ,
$ ::callback ) ;
}
}
}
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 ;
2009-03-20 18:46:11 +00:00
if ( exists ( $ defhash { $ obj } { $ showattr } ) )
2007-11-26 20:09:18 +00:00
{
$ attrval = $ defhash { $ obj } { $ showattr } ;
}
# if an attr list was provided then just display those
if ( $ ::opt_i )
{
if ( grep ( /^$showattr$/ , @ ::AttrList ) )
{
2008-07-09 16:10:10 +00:00
if ( ( $ defhash { $ obj } { 'objtype' } eq 'group' ) && ( $ showattr eq 'members' ) )
2007-11-26 20:09:18 +00:00
{
2009-05-15 02:29:28 +00:00
#$defhash{$obj}{'grouptype'} = "static";
2007-11-26 20:09:18 +00:00
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' ) )
{
2009-05-15 02:29:28 +00:00
#$defhash{$obj}{'grouptype'} = "static";
2007-11-26 20:09:18 +00:00
my $ memberlist =
2008-07-09 16:10:10 +00:00
xCAT::DBobjUtils - > getGroupMembers ( $ obj , \ % defhash ) ;
2007-11-26 20:09:18 +00:00
my $ rsp ;
$ rsp - > { data } - > [ 0 ] =
" $showattr=$memberlist" ;
xCAT::MsgUtils - > message ( "I" , $ rsp ,
$ ::callback ) ;
}
else
{
# don't print unless set
2009-06-30 17:22:25 +00:00
if ( ( defined ( $ attrval ) ) && ( $ attrval ne '' ) )
2007-11-26 20:09:18 +00:00
{
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
}
2008-02-28 19:05:31 +00:00
} # end - standard output or stanza format
} # end - for each object
} # end - for each type
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:
2008-02-21 21:10:35 +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 ;
2009-06-10 06:31:37 +00:00
my % objTypeLists ;
2007-11-26 20:09:18 +00:00
foreach my $ obj ( keys % objhash )
{
2009-06-10 06:31:37 +00:00
my $ objtype = $ objhash { $ obj } ;
if ( ! defined ( $ objTypeLists { $ objtype } ) ) # Do no call getObjectsOfType for the same objtype more than once.
{
@ { $ objTypeLists { $ objtype } } = xCAT::DBobjUtils - > getObjectsOfType ( $ objtype ) ;
}
if ( ! grep ( /^$obj$/ , @ { $ objTypeLists { $ objtype } } ) ) #Object is not in the db, do not need to delete
{
my $ rsp ;
$ rsp - > { data } - > [ 0 ] = "Could not find an object named \'$obj\' of type \'$objtype\'.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ ::callback ) ;
next ;
}
2007-11-26 20:09:18 +00:00
$ 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
2008-07-09 16:10:10 +00:00
my % ghash ;
2007-11-26 20:09:18 +00:00
$ ghash { $ obj } = 'group' ;
2008-07-09 16:10:10 +00:00
my % grphash = xCAT::DBobjUtils - > getobjdefs ( \ % ghash ) ;
2007-11-26 20:09:18 +00:00
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
2009-06-23 05:22:57 +00:00
# Dynamic node group stores in nodegroup table
# do not need to update the nodelist table
if ( $ grphash { $ obj } { 'grouptype' } eq 'dynamic' )
{
next ;
}
2007-11-26 20:09:18 +00:00
# get the members list
2008-02-28 19:05:31 +00:00
# all groups are "static" for now
$ grphash { $ obj } { 'grouptype' } = "static" ;
2007-11-26 20:09:18 +00:00
my $ memberlist = xCAT::DBobjUtils - > getGroupMembers ( $ obj , \ % grphash ) ;
my @ members = split ( ',' , $ memberlist ) ;
2007-10-26 22:44:33 +00:00
2009-06-23 05:33:53 +00:00
# No node in the group
if ( scalar ( @ members ) == 0 )
{
next ;
}
2007-11-26 20:09:18 +00:00
# foreach member node of the group
my % nodehash ;
my % nhash ;
my @ gprslist ;
foreach my $ m ( @ members )
{
# get the def of this node
$ nhash { $ m } = 'node' ;
2009-06-23 05:22:57 +00:00
}
# Performance: Only call getobjdefs once
2007-11-26 20:09:18 +00:00
% nodehash = xCAT::DBobjUtils - > getobjdefs ( \ % nhash ) ;
if ( ! defined ( % nodehash ) )
{
my $ rsp ;
2009-06-23 05:22:57 +00:00
my @ nodes = keys % nhash ;
my $ m = join ',' , @ nodes ;
2007-11-26 20:09:18 +00:00
$ rsp - > { data } - > [ 0 ] =
"Could not get xCAT object definition for \'$m\'." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ ::callback ) ;
next ;
}
2009-06-23 05:22:57 +00:00
foreach my $ m ( keys % nodehash )
{
# need to update the "groups" attr of the node def
2007-11-26 20:09:18 +00:00
# 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 ;
2008-12-11 17:58:37 +00:00
my $ newgrps = "" ;
2007-11-26 20:09:18 +00:00
foreach my $ grp ( @ gprslist )
{
chomp ( $ grp ) ;
if ( $ grp eq $ obj )
{
next ;
}
else
{
# set new groups list for node
if ( ! $ first )
{
$ newgrps . = "," ;
}
2008-12-11 17:58:37 +00:00
$ newgrps . = "$grp" ;
2007-11-26 20:09:18 +00:00
$ 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 ] =
2009-07-06 09:45:22 +00:00
" [-d | --dynamic] [-w attr==val [-w attr=~val] ...]" ;
2007-11-26 20:09:18 +00:00
$ 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 ] =
2008-05-28 19:12:56 +00:00
" [-z | --stanza] [-m | --minus] [-p | --plus]" ;
2007-11-26 20:09:18 +00:00
$ rsp - > { data } - > [ 4 ] =
2009-07-06 09:45:22 +00:00
" [-w attr==val [-w attr=~val] ... ] [noderange] [attr=val [attr=val...]]\n" ;
2007-11-26 20:09:18 +00:00
$ 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 ] =
2008-05-28 19:12:56 +00:00
" [ -l | --long] [-a | --all] [-z | --stanza ]" ;
2007-11-26 20:09:18 +00:00
$ rsp - > { data } - > [ 4 ] =
2009-07-06 09:45:22 +00:00
" [-i attr-list] [-w attr==val [-w attr=~val] ...] [noderange]\n" ;
2007-11-26 20:09:18 +00:00
$ 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