2009-09-21 11:30:05 +00:00
# IBM(c) 2009 EPL license http://www.eclipse.org/legal/epl-v10.html
2009-09-21 06:33:27 +00:00
package xCAT::PPCenergy ;
use strict ;
use Getopt::Long ;
use xCAT::Usage ;
use xCAT::NodeRange ;
% ::QUERY_ATTRS = (
'savingstatus' = > 1 ,
2010-01-30 14:35:01 +00:00
'dsavingstatus' = > 1 ,
2009-09-21 06:33:27 +00:00
'cappingstatus' = > 1 ,
'cappingmaxmin' = > 1 ,
'cappingvalue' = > 1 ,
'cappingsoftmin' = > 1 ,
'averageAC' = > 1 ,
'averageDC' = > 1 ,
'ambienttemp' = > 1 ,
'exhausttemp' = > 1 ,
2010-01-30 14:35:01 +00:00
'CPUspeed' = > 1 ,
'syssbpower' = > 1 ,
'sysIPLtime' = > 1 ,
) ;
2009-09-21 06:33:27 +00:00
% ::SET_ATTRS = (
'savingstatus' = > 1 ,
2010-01-30 14:35:01 +00:00
'dsavingstatus' = > 1 ,
2009-09-21 06:33:27 +00:00
'cappingstatus' = > 1 ,
'cappingwatt' = > 1 ,
'cappingperc' = > 1 ,
) ;
$ ::CIM_CLIENT_PATH = "$::XCATROOT/sbin/xCAT_cim_client" ;
# Parse the arguments of the command line for renergy command
sub parse_args {
my $ request = shift ;
my % opt = ( ) ;
my $ cmd = $ request - > { command } ;
my $ args = $ request - > { arg } ;
my $ nodes = $ request - > { node } ;
my $ query_attrs = ( ) ; # The attributes list for query operation
my $ set_pair = ( ) ; # The attribute need to be set. e.g. savingstatus=on
my $ set_flag = ( ) ; # Indicate there's setting param in the argv
my $ argv_flag = ( ) ; # Indicate there's param in the argv
my @ notfspnodes = ( ) ; # The nodes list which are not fsp
# set the usage subroutine
local * usage = sub {
my $ usage_string = xCAT::Usage - > getUsage ( $ cmd ) ;
2010-01-30 14:35:01 +00:00
return ( [ $ _ [ 0 ] , $ usage_string ] ) ;
2009-09-21 06:33:27 +00:00
} ;
if ( $ request - > { arg } ) {
@ ARGV = @ { $ request - > { arg } } ;
$ Getopt:: Long:: ignorecase = 0 ;
Getopt::Long:: Configure ( "bundling" ) ;
if ( $ nodes ) {
if ( ! GetOptions ( 'V' = > \ $ ::VERBOSE ) ) {
return ( & usage ( ) ) ;
}
if ( $ ::VERBOSE ) {
$ opt { verbose } = 1 ;
}
if ( $# ARGV < 0 ) {
return ( & usage ( ) ) ;
}
# Check the validity of the parameters of Query and Set
foreach my $ attr ( @ ARGV ) {
my ( $ set_attr , $ set_value ) = split ( /=/ , $ attr ) ;
2010-01-30 14:35:01 +00:00
if ( defined ( $ set_value ) ) {
2009-09-21 06:33:27 +00:00
if ( $ argv_flag ) {
return ( & usage ( ) ) ;
}
if ( $ ::SET_ATTRS { $ set_attr } != 1 ) {
return ( & usage ( ) ) ;
}
if ( $ set_attr eq "savingstatus"
&& ( $ set_value ne "on" && $ set_value ne "off" ) ) {
return ( & usage ( ) ) ;
2010-01-30 14:35:01 +00:00
} elsif ( $ set_attr eq "dsavingstatus"
&& ( $ set_value ne "off"
&& $ set_value ne "on-norm" && $ set_value ne "on-maxp" ) ) {
return ( & usage ( ) ) ;
2009-09-21 06:33:27 +00:00
} elsif ( $ set_attr eq "cappingstatus"
&& ( $ set_value ne "on" && $ set_value ne "off" ) ) {
return ( & usage ( ) ) ;
} elsif ( ( $ set_attr eq "cappingwatt"
|| $ set_attr eq "cappingperc" )
&& $ set_value =~ /\D/ ) {
return ( & usage ( ) ) ;
}
$ set_pair = $ set_attr . "=" . $ set_value ;
$ set_flag = 1 ;
} else {
if ( $ set_flag ) {
return ( & usage ( ) ) ;
}
}
$ argv_flag = 1 ;
}
if ( ! $ set_flag ) {
my @ query_list = @ ARGV ;
2010-01-30 14:35:01 +00:00
2009-09-21 06:33:27 +00:00
if ( $ query_list [ 0 ] eq "all" and $# query_list == 0 ) {
2010-01-30 14:35:01 +00:00
$ query_attrs = "all" ;
2009-09-21 06:33:27 +00:00
} else {
my @ no_dup_query_list = ( ) ;
foreach my $ q_attr ( @ query_list ) {
chomp ( $ q_attr ) ;
2010-01-30 14:35:01 +00:00
2009-09-21 06:33:27 +00:00
if ( $ ::QUERY_ATTRS { $ q_attr } != 1 ) {
return ( & usage ( ) ) ;
}
2009-09-21 11:30:05 +00:00
if ( ! grep ( /^$q_attr$/ , @ no_dup_query_list ) ) {
2009-09-21 06:33:27 +00:00
push @ no_dup_query_list , $ q_attr ;
}
}
$ query_attrs = join ( ',' , @ no_dup_query_list ) ;
}
}
} else {
# If has not nodes, the -h or -v option must be input
if ( ! GetOptions ( 'h|help' = > \ $ ::HELP ,
'v|version' = > \ $ ::VERSION ) ) {
return ( & usage ( ) ) ;
}
if ( ! ( $ ::HELP || $ ::VERSION ) ) {
return ( & usage ( ) ) ;
}
if ( $ ::HELP ) {
return ( & usage ( ) ) ;
}
if ( $ ::VERSION ) {
my $ version_string = xCAT::Usage - > getVersion ( 'renergy' ) ;
return ( [ $ _ [ 0 ] , $ version_string ] ) ;
}
2010-01-30 14:35:01 +00:00
if ( scalar ( @ ARGV ) ) {
return ( & usage ( ) ) ;
}
2009-09-21 06:33:27 +00:00
}
} else {
return ( & usage ( ) ) ;
}
# Check whether the hardware type of nodes are fsp
my $ nodetype_tb = xCAT::Table - > new ( 'nodetype' ) ;
unless ( $ nodetype_tb ) {
2010-01-30 14:35:01 +00:00
return ( [ undef , "Error: Cannot open the nodetype table" ] ) ;
2009-09-21 06:33:27 +00:00
}
my $ nodetype_v = $ nodetype_tb - > getNodesAttribs ( $ nodes , [ 'nodetype' ] ) ;
foreach my $ node ( @ { $ nodes } ) {
if ( $ nodetype_v - > { $ node } - > [ 0 ] - > { 'nodetype' } ne 'fsp' ) {
push @ notfspnodes , $ node ;
}
}
2009-09-21 11:30:05 +00:00
$ nodetype_tb - > close ( ) ;
2009-09-21 06:33:27 +00:00
if ( @ notfspnodes ) {
2010-01-30 14:35:01 +00:00
return ( [ undef , "Error: The hardware type of following nodes are not fsp: " . join ( ',' , @ notfspnodes ) ] ) ;
2009-09-21 06:33:27 +00:00
}
if ( $ query_attrs ) {
$ opt { 'query' } = $ query_attrs ;
} elsif ( $ set_pair ) {
$ opt { 'set' } = $ set_pair ;
}
$ request - > { method } = $ cmd ;
return ( \ % opt ) ;
}
# Handle the energy query and setting work
sub renergy {
my $ request = shift ;
my $ hcphost = shift ;
my $ nodehash = shift ;
my @ return_msg = ( ) ;
my $ opt = $ request - > { 'opt' } ;
my $ verbose = $ opt - > { 'verbose' } ;
# Get the User and Password for the HCP
my $ user = $ request - > { $ hcphost } { 'cred' } [ 0 ] ;
my $ password = $ request - > { $ hcphost } { 'cred' } [ 1 ] ;
# Get the CEC
my ( $ node , $ attrs ) = %$ nodehash ;
my $ cec_name = @$ attrs [ 2 ] ;
if ( $ verbose ) {
push @ return_msg , [ $ node , "Attributes of $node:\n User=$user\n Password=$password\n CEC=$cec_name\n" , 0 ] ;
}
if ( ! ( $ user || $ password || $ cec_name ) ) {
return ( [ [ $ node , "ERROR: This node lack some mandatory attributes for renergy command." , 1 ] ] ) ;
}
# Check the existence of cim client
if ( ( ! - f $ ::CIM_CLIENT_PATH )
|| ( ! - x $ ::CIM_CLIENT_PATH ) ) {
2009-09-21 11:30:05 +00:00
return ( [ [ $ node , "ERROR: Cannot find the xCAT CIM Client [$::CIM_CLIENT_PATH] or it's NOT executable. Please install the xCAT-cimclient package correctly." , 1 ] ] ) ;
2009-09-21 06:33:27 +00:00
}
# Generate the url path for CIM communication
my $ url_path = "https://" . "$user" . ":" . "$password" . "\@" . "$hcphost" . ":5989" ;
my $ verb_arg = "" ;
if ( $ verbose ) {
$ verb_arg = "-V" ;
}
# Execute the request
my $ cmd = "" ;
if ( $ opt - > { 'set' } ) {
$ cmd = "$::CIM_CLIENT_PATH $verb_arg -u $url_path -n $cec_name -o $opt->{'set'}" ;
} elsif ( $ opt - > { 'query' } ) {
$ cmd = "$::CIM_CLIENT_PATH $verb_arg -u $url_path -n $cec_name -o $opt->{'query'}" ;
}
if ( $ verbose ) {
push @ return_msg , [ $ node , "Run following command: $cmd" , 0 ] ;
}
# Disable the CHID signal before run the command. Otherwise the
# $? value of `$cmd` will come from handler of CHID signal
$ SIG { CHLD } = ( ) ;
# Call the xCAT_cim_client to query or set the energy capabilities
2010-05-05 08:15:47 +00:00
$ cmd . = " 2>&1" ;
2009-09-21 11:30:05 +00:00
my @ result = xCAT::Utils - > runcmd ( "$cmd" , - 1 ) ;
2009-09-21 06:33:27 +00:00
foreach my $ line ( @ result ) {
chomp ( $ line ) ;
if ( $ line =~ /^\s*$/ ) {
next ;
}
2009-09-21 11:30:05 +00:00
push @ return_msg , [ $ node , $ line , $ ::RUNCMD_RC ] ;
2009-09-21 06:33:27 +00:00
}
return \ @ return_msg ;
}
1 ;