git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@50 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
parent
04631e79b6
commit
c4f6fd4bae
630
perl-xCAT-2.0/xCAT/PPC.pm
Normal file
630
perl-xCAT-2.0/xCAT/PPC.pm
Normal file
@ -0,0 +1,630 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package xCAT::PPC;
|
||||
use strict;
|
||||
use xCAT::Table;
|
||||
use POSIX "WNOHANG";
|
||||
use Storable qw(freeze thaw);
|
||||
use Time::HiRes qw(gettimeofday);
|
||||
use IO::Select;
|
||||
use xCAT::PPCcli;
|
||||
use xCAT::PPCfsp;
|
||||
|
||||
|
||||
##########################################
|
||||
# Globals
|
||||
##########################################
|
||||
my %modules = (
|
||||
rinv => "xCAT::PPCinv",
|
||||
rpower => "xCAT::PPCpower",
|
||||
rvitals => "xCAT::PPCvitals",
|
||||
rscan => "xCAT::PPCscan",
|
||||
mkvm => "xCAT::PPCvm",
|
||||
rmvm => "xCAT::PPCvm",
|
||||
lsvm => "xCAT::PPCvm",
|
||||
chvm => "xCAT::PPCvm",
|
||||
rnetboot => "xCAT::PPCboot",
|
||||
getmacs => "xCAT::PPCmac",
|
||||
reventlog => "xCAT::PPClog"
|
||||
);
|
||||
|
||||
##########################################
|
||||
# Database errors
|
||||
##########################################
|
||||
my %errmsg = (
|
||||
NODE_UNDEF =>"Node not defined in '%s' database",
|
||||
NO_ATTR =>"'%s' not defined in '%s' database",
|
||||
DB_UNDEF =>"'%s' database not defined"
|
||||
);
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Invokes the callback with the specified message
|
||||
##########################################################################
|
||||
sub send_msg {
|
||||
|
||||
my $request = shift;
|
||||
my %output;
|
||||
|
||||
#################################################
|
||||
# Called from child process - send to parent
|
||||
#################################################
|
||||
if ( exists( $request->{pipe} )) {
|
||||
my $out = $request->{pipe};
|
||||
|
||||
$output{data} = \@_;
|
||||
print $out freeze( [\%output] );
|
||||
}
|
||||
#################################################
|
||||
# Called from parent - invoke callback directly
|
||||
#################################################
|
||||
elsif ( exists( $request->{callback} )) {
|
||||
my $callback = $request->{callback};
|
||||
|
||||
$output{data} = \@_;
|
||||
$callback->( \%output );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Fork child to execute remote commands
|
||||
##########################################################################
|
||||
sub process_command {
|
||||
|
||||
my $request = shift;
|
||||
my $maxp = 64;
|
||||
my %nodes = ();
|
||||
my $callback = $request->{callback};
|
||||
my $start;
|
||||
|
||||
if ( exists( $request->{verbose} )) {
|
||||
$start = Time::HiRes::gettimeofday();
|
||||
}
|
||||
#######################################
|
||||
# Group nodes based on command
|
||||
#######################################
|
||||
my $nodes = preprocess_nodes( $request );
|
||||
if ( !defined( $nodes )) {
|
||||
return(1);
|
||||
}
|
||||
#######################################
|
||||
# Fork process
|
||||
#######################################
|
||||
my $children = 0;
|
||||
$SIG{CHLD} = sub { while (waitpid(-1, WNOHANG) > 0) { $children--; } };
|
||||
my $fds = new IO::Select;
|
||||
|
||||
foreach ( @$nodes ) {
|
||||
while ( $children > $maxp ) {
|
||||
sleep(0.1);
|
||||
}
|
||||
my $pipe = fork_cmd( @$_[0], @$_[1], $request );
|
||||
if ( $pipe ) {
|
||||
$fds->add( $pipe );
|
||||
$children++;
|
||||
}
|
||||
}
|
||||
#######################################
|
||||
# Process responses from children
|
||||
#######################################
|
||||
while ( $children > 0 ) {
|
||||
child_response( $callback, $fds );
|
||||
}
|
||||
if ( exists( $request->{verbose} )) {
|
||||
my $elapsed = Time::HiRes::gettimeofday() - $start;
|
||||
printf STDERR "Total Elapsed Time: %.3f sec\n", $elapsed;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Send response from child process back to xCAT client
|
||||
##########################################################################
|
||||
sub child_response {
|
||||
|
||||
my $callback = shift;
|
||||
my $fds = shift;
|
||||
my @ready_fds = $fds->can_read(1);
|
||||
|
||||
foreach my $rfh (@ready_fds) {
|
||||
my $data;
|
||||
|
||||
#################################
|
||||
# Read from child
|
||||
#################################
|
||||
while (<$rfh>) {
|
||||
$data.= $_;
|
||||
}
|
||||
#################################
|
||||
# Command results
|
||||
#################################
|
||||
my $responses = thaw($data);
|
||||
foreach (@$responses) {
|
||||
$callback->($_);
|
||||
}
|
||||
$fds->remove($rfh);
|
||||
close($rfh);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Group nodes depending on command
|
||||
##########################################################################
|
||||
sub preprocess_nodes {
|
||||
|
||||
my $request = shift;
|
||||
my $noderange = $request->{node};
|
||||
my $method = $request->{method};
|
||||
my %nodehash = ();
|
||||
my @nodegroup = ();
|
||||
my %tabs = ();
|
||||
|
||||
########################################
|
||||
# Special cases
|
||||
# rscan - Nodes are hardware control pts
|
||||
# Direct-attached FSP
|
||||
########################################
|
||||
if (( $request->{command} eq "rscan" ) or
|
||||
( $request->{hwtype} eq "fsp" )) {
|
||||
|
||||
my $tab = ($request->{hwtype} eq "fsp") ? "ppcDirect" : "ppchcp";
|
||||
my $db = xCAT::Table->new( $tab );
|
||||
|
||||
if ( !defined( $db )) {
|
||||
send_msg( $request, sprintf( $errmsg{DB_UNDEF}, $tab ));
|
||||
return undef;
|
||||
}
|
||||
####################################
|
||||
# Process each node
|
||||
####################################
|
||||
foreach ( @$noderange ) {
|
||||
my ($ent) = $db->getAttribs( {hcp=>$_},"hcp" );
|
||||
|
||||
if ( !defined( $ent )) {
|
||||
my $msg = sprintf( "$_: $errmsg{NODE_UNDEF}", $tab );
|
||||
send_msg( $request, $msg );
|
||||
next;
|
||||
}
|
||||
################################
|
||||
# Save values
|
||||
################################
|
||||
push @nodegroup,[$_];
|
||||
}
|
||||
return( \@nodegroup );
|
||||
}
|
||||
|
||||
##########################################
|
||||
# Open databases needed
|
||||
##########################################
|
||||
foreach ( qw(ppc vpd nodelist) ) {
|
||||
$tabs{$_} = xCAT::Table->new($_);
|
||||
|
||||
if ( !exists( $tabs{$_} )) {
|
||||
send_msg( $request, sprintf( $errmsg{DB_UNDEF}, $_ ));
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
##########################################
|
||||
# Group nodes
|
||||
##########################################
|
||||
foreach my $node ( @$noderange ) {
|
||||
my $d = resolve( $request, $node, \%tabs );
|
||||
|
||||
######################################
|
||||
# Error locating node attributes
|
||||
######################################
|
||||
if ( ref($d) ne 'ARRAY' ) {
|
||||
send_msg( $request,"$node: $d");
|
||||
next;
|
||||
}
|
||||
######################################
|
||||
# Get data values
|
||||
######################################
|
||||
my $hcp = @$d[3];
|
||||
my $mtms = @$d[2];
|
||||
|
||||
$nodehash{$hcp}{$mtms}{$node} = $d;
|
||||
}
|
||||
##########################################
|
||||
# Group the nodes - we will fork one
|
||||
# process per nodegroup array element.
|
||||
##########################################
|
||||
|
||||
##########################################
|
||||
# These commands are grouped on an
|
||||
# LPAR-by-LPAR basis - fork one process
|
||||
# per LPAR.
|
||||
##########################################
|
||||
if ( $method =~ /^getmacs|rnetboot$/ ) {
|
||||
while (my ($hcp,$hash) = each(%nodehash) ) {
|
||||
while (my ($mtms,$h) = each(%$hash) ) {
|
||||
while (my ($lpar,$d) = each(%$h)) {
|
||||
push @$d, $lpar;
|
||||
push @nodegroup,[$hcp,$d];
|
||||
}
|
||||
}
|
||||
}
|
||||
return( \@nodegroup );
|
||||
}
|
||||
##########################################
|
||||
# Power control commands are grouped
|
||||
# by CEC which is the smallest entity
|
||||
# that commands can be sent to in parallel.
|
||||
# If commands are sent in parallel to a
|
||||
# single CEC, the CEC itself will serialize
|
||||
# them - fork one process per CEC.
|
||||
##########################################
|
||||
elsif ( $method =~ /^powercmd/ ) {
|
||||
while (my ($hcp,$hash) = each(%nodehash) ) {
|
||||
while (my ($mtms,$h) = each(%$hash) ) {
|
||||
push @nodegroup,[$hcp,$h];
|
||||
}
|
||||
}
|
||||
return( \@nodegroup );
|
||||
}
|
||||
##########################################
|
||||
# All other commands are grouped by
|
||||
# hardware control point - fork one
|
||||
# process per hardware control point.
|
||||
##########################################
|
||||
while (my ($hcp,$hash) = each(%nodehash) ) {
|
||||
push @nodegroup,[$hcp,$hash];
|
||||
}
|
||||
return( \@nodegroup );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Findis attributes for given node is various databases
|
||||
##########################################################################
|
||||
sub resolve {
|
||||
|
||||
my $request = shift;
|
||||
my $node = shift;
|
||||
my $tabs = shift;
|
||||
my @attribs = qw(id profile mgt hcp);
|
||||
my @values = ();
|
||||
|
||||
#################################
|
||||
# Get node type
|
||||
#################################
|
||||
my ($ent) = $tabs->{nodelist}->getAttribs({'node'=>$node}, "nodetype" );
|
||||
if ( !defined( $ent )) {
|
||||
return( sprintf( $errmsg{NODE_UNDEF}, "nodelist" ));
|
||||
}
|
||||
#################################
|
||||
# Check for type
|
||||
#################################
|
||||
if ( !exists( $ent->{nodetype} )) {
|
||||
return( sprintf( $errmsg{NO_ATTR}, $ent->{nodetype}, "nodelist" ));
|
||||
}
|
||||
#################################
|
||||
# Check for valid "type"
|
||||
#################################
|
||||
if ( $ent->{nodetype} !~ /^fsp|bpa|osi$/ ) {
|
||||
return( "Invalid node type: $ent->{nodetype}" );
|
||||
}
|
||||
my $type = $ent->{nodetype};
|
||||
|
||||
#################################
|
||||
# Get attributes
|
||||
#################################
|
||||
my ($att) = $tabs->{ppc}->getAttribs({'node'=>$node}, @attribs );
|
||||
|
||||
if ( !defined( $att )) {
|
||||
return( sprintf( $errmsg{NODE_UNDEF}, "ppc" ));
|
||||
}
|
||||
#################################
|
||||
# Special lpar processing
|
||||
#################################
|
||||
if ( $type =~ /^osi$/ ) {
|
||||
$att->{bpa} = 0;
|
||||
$att->{type} = "lpar";
|
||||
$att->{node} = $att->{mgt};
|
||||
|
||||
if ( !exists( $att->{mgt} )) {
|
||||
return( sprintf( $errmsg{NO_ATTR}, "mgt", "ppc" ));
|
||||
}
|
||||
#############################
|
||||
# Get BPA (if any)
|
||||
#############################
|
||||
if (( $request->{command} eq "rvitals" ) &&
|
||||
( $request->{method} =~ /^all|temp$/ )) {
|
||||
my ($ent) = $tabs->{ppc}->getAttribs({'node'=>$att->{mgt}}, "mgt" );
|
||||
|
||||
#############################
|
||||
# Find MTMS in vpd database
|
||||
#############################
|
||||
if (( defined( $ent )) && exists( $ent->{mgt} )) {
|
||||
my @attrs = qw(mtm serial);
|
||||
my ($vpd) = $tabs->{vpd}->getAttribs({node=>$ent->{mgt}},@attrs );
|
||||
|
||||
if ( !defined( $vpd )) {
|
||||
return( sprintf( $errmsg{NO_UNDEF}, "vpd" ));
|
||||
}
|
||||
########################
|
||||
# Verify attributes
|
||||
########################
|
||||
foreach ( @attrs ) {
|
||||
if ( !exists( $vpd->{$_} )) {
|
||||
return( sprintf( $errmsg{NO_ATTR}, $_, "vpd" ));
|
||||
}
|
||||
}
|
||||
$att->{bpa} = "$vpd->{mtm}*$vpd->{serial}";
|
||||
}
|
||||
}
|
||||
}
|
||||
#################################
|
||||
# Optional and N/A fields
|
||||
#################################
|
||||
elsif ( $type =~ /^fsp$/ ) {
|
||||
$att->{profile} = 0;
|
||||
$att->{id} = 0;
|
||||
$att->{fsp} = 0;
|
||||
$att->{node} = $node;
|
||||
$att->{type} = $type;
|
||||
$att->{mgt} = exists($att->{mgt}) ? $att->{mgt} : 0;
|
||||
$att->{bpa} = $att->{mgt};
|
||||
}
|
||||
elsif ( $type =~ /^bpa$/ ) {
|
||||
$att->{profile} = 0;
|
||||
$att->{id} = 0;
|
||||
$att->{bpa} = 0;
|
||||
$att->{mgt} = 0;
|
||||
$att->{fsp} = 0;
|
||||
$att->{node} = $node;
|
||||
$att->{type} = $type;
|
||||
}
|
||||
#################################
|
||||
# Find MTMS in vpd database
|
||||
#################################
|
||||
my @attrs = qw(mtm serial);
|
||||
my ($vpd) = $tabs->{vpd}->getAttribs({node=>$att->{node}}, @attrs );
|
||||
|
||||
if ( !defined( $vpd )) {
|
||||
return( sprintf( $errmsg{NODE_UNDEF}, "vpd" ));
|
||||
}
|
||||
################################
|
||||
# Verify both vpd attributes
|
||||
################################
|
||||
foreach ( @attrs ) {
|
||||
if ( !exists( $vpd->{$_} )) {
|
||||
return( sprintf( $errmsg{NO_ATTR}, $_, "vpd" ));
|
||||
}
|
||||
}
|
||||
$att->{fsp} = "$vpd->{mtm}*$vpd->{serial}";
|
||||
|
||||
#################################
|
||||
# Verify required attributes
|
||||
#################################
|
||||
foreach my $at ( @attribs ) {
|
||||
if ( !exists( $att->{$at} )) {
|
||||
return( sprintf( $errmsg{NO_ATTR}, $at, "ppc" ));
|
||||
}
|
||||
}
|
||||
#################################
|
||||
# Build array of data
|
||||
#################################
|
||||
foreach ( qw(id profile fsp hcp type bpa) ) {
|
||||
push @values, $att->{$_};
|
||||
}
|
||||
return( \@values );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Forks a process to run the ssh command
|
||||
##########################################################################
|
||||
sub fork_cmd {
|
||||
|
||||
my $host = shift;
|
||||
my $nodes = shift;
|
||||
my $request = shift;
|
||||
|
||||
#######################################
|
||||
# Pipe childs output back to parent
|
||||
#######################################
|
||||
my $parent;
|
||||
my $child;
|
||||
pipe $parent, $child;
|
||||
my $pid = fork;
|
||||
|
||||
if ( !defined($pid) ) {
|
||||
###################################
|
||||
# Fork error
|
||||
###################################
|
||||
send_msg( $request, "Fork error: $!" );
|
||||
return undef;
|
||||
}
|
||||
elsif ( $pid == 0 ) {
|
||||
###################################
|
||||
# Child process
|
||||
###################################
|
||||
close( $parent );
|
||||
$request->{pipe} = $child;
|
||||
|
||||
invoke_cmd( $host, $nodes, $request );
|
||||
exit(0);
|
||||
}
|
||||
else {
|
||||
###################################
|
||||
# Parent process
|
||||
###################################
|
||||
close( $child );
|
||||
return( $parent );
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Run the command, process the response, and send to parent
|
||||
##########################################################################
|
||||
sub invoke_cmd {
|
||||
|
||||
my $host = shift;
|
||||
my $nodes = shift;
|
||||
my $request = shift;
|
||||
my $hwtype = $request->{hwtype};
|
||||
my $verbose = $request->{verbose};
|
||||
my @exp;
|
||||
my @outhash;
|
||||
|
||||
########################################
|
||||
# Direct-attached FSP handler
|
||||
########################################
|
||||
if ( $hwtype eq "fsp" ) {
|
||||
my $result = xCAT::PPCfsp::handler( $host, $request );
|
||||
|
||||
my $out = $request->{pipe};
|
||||
print $out freeze( $result );
|
||||
return;
|
||||
}
|
||||
########################################
|
||||
# Connect to list of remote servers
|
||||
########################################
|
||||
foreach ( split /,/, $host ) {
|
||||
@exp = xCAT::PPCcli::connect( $hwtype, $_, $verbose );
|
||||
|
||||
####################################
|
||||
# Successfully connected
|
||||
####################################
|
||||
if ( ref($exp[0]) eq "Expect" ) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
########################################
|
||||
# Error connecting
|
||||
########################################
|
||||
if ( ref($exp[0]) ne "Expect" ) {
|
||||
send_msg( $request, $exp[0] );
|
||||
return;
|
||||
}
|
||||
########################################
|
||||
# Process specific command
|
||||
########################################
|
||||
my $result = runcmd( $request, $nodes, \@exp );
|
||||
|
||||
########################################
|
||||
# Close connection to remote server
|
||||
########################################
|
||||
xCAT::PPCcli::disconnect( \@exp );
|
||||
|
||||
########################################
|
||||
# Return error
|
||||
########################################
|
||||
if ( ref($result) ne 'ARRAY' ) {
|
||||
send_msg( $request, $result );
|
||||
return;
|
||||
}
|
||||
########################################
|
||||
# Send result back to parent process
|
||||
########################################
|
||||
if ( @$result[0] eq "FORMATTED_DATA" ) {
|
||||
shift(@$result);
|
||||
my $out = $request->{pipe};
|
||||
print $out freeze( [@$result] );
|
||||
return;
|
||||
}
|
||||
########################################
|
||||
# Format and send back to parent
|
||||
########################################
|
||||
foreach ( @$result ) {
|
||||
my %output;
|
||||
$output{node}->[0]->{name}->[0] = @$_[0];
|
||||
$output{node}->[0]->{data}->[0]->{contents}->[0] = @$_[1];
|
||||
push @outhash, \%output;
|
||||
}
|
||||
my $out = $request->{pipe};
|
||||
print $out freeze( [@outhash] );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Run the command method specified
|
||||
##########################################################################
|
||||
sub runcmd {
|
||||
|
||||
my $request = shift;
|
||||
my $cmd = $request->{command};
|
||||
my $method = $request->{method};
|
||||
my $modname = $modules{$cmd};
|
||||
|
||||
######################################
|
||||
# Load specific module
|
||||
######################################
|
||||
unless ( eval "require $modname" ) {
|
||||
return( ["Can't locate $modname"] );
|
||||
}
|
||||
######################################
|
||||
# Invoke method
|
||||
######################################
|
||||
no strict 'refs';
|
||||
my $result = ${$modname."::"}{$method}->($request,@_);
|
||||
use strict;
|
||||
|
||||
return( $result );
|
||||
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Process request from xCat daemon
|
||||
##########################################################################
|
||||
sub process_request {
|
||||
|
||||
my $package = shift;
|
||||
my $req = shift;
|
||||
my $callback = shift;
|
||||
|
||||
####################################
|
||||
# Get hwtype
|
||||
####################################
|
||||
$package =~ s/xCAT_plugin:://;
|
||||
|
||||
####################################
|
||||
# Build hash to pass around
|
||||
####################################
|
||||
my %request;
|
||||
$request{command} = $req->{command}->[0];
|
||||
$request{arg} = $req->{arg};
|
||||
$request{node} = $req->{node};
|
||||
$request{stdin} = $req->{stdin}->[0];
|
||||
$request{hwtype} = $package;
|
||||
$request{callback} = $callback;
|
||||
$request{method} = "parse_args";
|
||||
|
||||
####################################
|
||||
# Process command-specific options
|
||||
####################################
|
||||
my $opt = runcmd( \%request );
|
||||
|
||||
####################################
|
||||
# Return error
|
||||
####################################
|
||||
if ( ref($opt) eq 'ARRAY' ) {
|
||||
send_msg( \%request, @$opt );
|
||||
return(1);
|
||||
}
|
||||
####################################
|
||||
# Option -V for verbose output
|
||||
####################################
|
||||
if ( exists( $opt->{V} )) {
|
||||
$request{verbose} = 1;
|
||||
}
|
||||
####################################
|
||||
# Process remote command
|
||||
####################################
|
||||
$request{opt} = $opt;
|
||||
process_command( \%request );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
1;
|
170
perl-xCAT-2.0/xCAT/PPCboot.pm
Normal file
170
perl-xCAT-2.0/xCAT/PPCboot.pm
Normal file
@ -0,0 +1,170 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package xCAT::PPCboot;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Parse the command line for options and operands
|
||||
##########################################################################
|
||||
sub parse_args {
|
||||
|
||||
my $request = shift;
|
||||
my %opt = ();
|
||||
my $cmd = $request->{command};
|
||||
my $args = $request->{arg};
|
||||
my @VERSION = qw( 2.0 );
|
||||
|
||||
#############################################
|
||||
# Responds with usage statement
|
||||
#############################################
|
||||
local *usage = sub {
|
||||
return( [ $_[0],
|
||||
"rnetboot -h|--help",
|
||||
"rnetboot -v|--version",
|
||||
"rnetboot [-V|--verbose] noderange -S server -G gateway -C client -m MAC-address",
|
||||
" -h writes usage information to standard output",
|
||||
" -v displays command version",
|
||||
" -C IP of the partition to network boot",
|
||||
" -G Gateway IP of the partition specified",
|
||||
" -S IP of the machine to retrieve network boot image",
|
||||
" -m MAC address of network adapter to use for network boot",
|
||||
" -V verbose output" ]);
|
||||
};
|
||||
#############################################
|
||||
# Process command-line arguments
|
||||
#############################################
|
||||
if ( !defined( $args )) {
|
||||
return( usage() );
|
||||
}
|
||||
#############################################
|
||||
# Checks case in GetOptions, allows opts
|
||||
# to be grouped (e.g. -vx), and terminates
|
||||
# at the first unrecognized option.
|
||||
#############################################
|
||||
@ARGV = @$args;
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
Getopt::Long::Configure( "bundling" );
|
||||
|
||||
if ( !GetOptions( \%opt,
|
||||
qw(h|help V|Verbose v|version C=s G=s S=s m=s ))) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -h for Help
|
||||
####################################
|
||||
if ( exists( $opt{h} )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -v for version
|
||||
####################################
|
||||
if ( exists( $opt{v} )) {
|
||||
return( \@VERSION );
|
||||
}
|
||||
####################################
|
||||
# Check for "-" with no option
|
||||
####################################
|
||||
if ( grep(/^-$/, @ARGV )) {
|
||||
return(usage( "Missing option: -" ));
|
||||
}
|
||||
####################################
|
||||
# Check for an extra argument
|
||||
####################################
|
||||
if ( defined( $ARGV[0] )) {
|
||||
return(usage( "Invalid Argument: $ARGV[0]" ));
|
||||
}
|
||||
####################################
|
||||
# Option -m required
|
||||
####################################
|
||||
if ( !exists($opt{m}) ) {
|
||||
return(usage( "Missing option: -m" ));
|
||||
}
|
||||
####################################
|
||||
# Options -C -G -S required
|
||||
####################################
|
||||
foreach ( qw(C G S) ) {
|
||||
if ( !exists($opt{$_}) ) {
|
||||
return(usage( "Missing option: -$_" ));
|
||||
}
|
||||
}
|
||||
my $result = validate_ip( $opt{C}, $opt{G}, $opt{S} );
|
||||
if ( @$result[0] ) {
|
||||
return(usage( @$result[1] ));
|
||||
}
|
||||
####################################
|
||||
# Set method to invoke
|
||||
####################################
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Validate list of IPs
|
||||
##########################################################################
|
||||
sub validate_ip {
|
||||
|
||||
foreach (@_) {
|
||||
my $ip = $_;
|
||||
|
||||
###################################
|
||||
# Length is 4 for IPv4 addresses
|
||||
###################################
|
||||
my (@octets) = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
||||
if ( scalar(@octets) != 4 ) {
|
||||
return( [1,"Invalid IP address: $ip"] );
|
||||
}
|
||||
foreach my $octet ( @octets ) {
|
||||
if (( $octet < 0 ) or ( $octet > 255 )) {
|
||||
return( [1,"Invalid IP address: $ip"] );
|
||||
}
|
||||
}
|
||||
}
|
||||
return([0]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Get LPAR MAC addresses
|
||||
##########################################################################
|
||||
sub rnetboot {
|
||||
|
||||
my $request = shift;
|
||||
my $d = shift;
|
||||
my $exp = shift;
|
||||
my $hwtype = @$exp[2];
|
||||
my $opt = $request->{opt};
|
||||
my @output;
|
||||
|
||||
#####################################
|
||||
# Get node data
|
||||
#####################################
|
||||
my $type = @$d[4];
|
||||
my $name = @$d[6];
|
||||
|
||||
#####################################
|
||||
# Invalid target hardware
|
||||
#####################################
|
||||
if ( $type !~ /^lpar$/ ) {
|
||||
return( [[$name,"Not supported"]] );
|
||||
}
|
||||
my $result = xCAT::PPCcli::lpar_netboot(
|
||||
$exp,
|
||||
$name,
|
||||
$d,
|
||||
$opt->{S},
|
||||
$opt->{G},
|
||||
$opt->{C},
|
||||
$opt->{m} );
|
||||
|
||||
my $Rc = shift(@$result);
|
||||
return( [[$name,@$result[0]]] );
|
||||
}
|
||||
|
||||
|
||||
1;
|
808
perl-xCAT-2.0/xCAT/PPCcli.pm
Normal file
808
perl-xCAT-2.0/xCAT/PPCcli.pm
Normal file
@ -0,0 +1,808 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package xCAT::PPCcli;
|
||||
require Exporter;
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT_OK = qw(SUCCESS RC_ERROR EXPECT_ERROR NR_ERROR);
|
||||
use strict;
|
||||
use xCAT::PPCdb;
|
||||
use Expect;
|
||||
|
||||
|
||||
#############################################
|
||||
# Removes Ctrl characters from term output
|
||||
#############################################
|
||||
$ENV{'TERM'} = "vt100";
|
||||
|
||||
##############################################
|
||||
# Constants
|
||||
##############################################
|
||||
use constant {
|
||||
SUCCESS => 0,
|
||||
RC_ERROR => 1,
|
||||
EXPECT_ERROR => 2,
|
||||
NR_ERROR => 3
|
||||
};
|
||||
|
||||
##############################################
|
||||
# lssyscfg supported formats
|
||||
##############################################
|
||||
my %lssyscfg = (
|
||||
fsp =>"lssyscfg -r sys -m %s -F %s",
|
||||
fsps =>"lssyscfg -r sys -F %s",
|
||||
node =>"lssyscfg -r lpar -m %s -F %s --filter lpar_ids=%s",
|
||||
lpar =>"lssyscfg -r lpar -m %s -F %s",
|
||||
bpa =>"lssyscfg -r frame -e %s -F %s",
|
||||
bpas =>"lssyscfg -r frame -F %s",
|
||||
prof =>"lssyscfg -r prof -m %s --filter lpar_ids=%s",
|
||||
cprof =>"lssyscfg -r prof -m %s",
|
||||
cage =>"lssyscfg -r cage -e %s -F %s"
|
||||
);
|
||||
|
||||
##############################################
|
||||
# Power control supported formats
|
||||
##############################################
|
||||
my %powercmd = (
|
||||
hmc => {
|
||||
reset =>"hmcshutdown -t now -r" },
|
||||
ivm => {
|
||||
reset =>"reboot" },
|
||||
lpar => {
|
||||
on =>"chsysstate -r %s -m %s -o on -b norm --id %s -f %s",
|
||||
of =>"chsysstate -r %s -m %s -o on --id %s -f %s -b of",
|
||||
reset =>"chsysstate -r %s -m %s -o shutdown --id %s --immed --restart",
|
||||
off =>"chsysstate -r %s -m %s -o shutdown --id %s --immed",
|
||||
boot =>"undetermined" },
|
||||
sys => {
|
||||
reset =>"chsysstate -r %s -m %s -o off --immed --restart",
|
||||
on =>"chsysstate -r %s -m %s -o on",
|
||||
off =>"chsysstate -r %s -m %s -o off",
|
||||
boot =>"undetermined" }
|
||||
);
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Logon to remote server
|
||||
##########################################################################
|
||||
sub connect {
|
||||
|
||||
my $hwtype = shift;
|
||||
my $server = shift;
|
||||
my $verbose = shift;
|
||||
my $pwd_prompt = 'assword: $';
|
||||
my $continue = 'continue connecting (yes/no)?';
|
||||
my $timeout = 10;
|
||||
my $success = 0;
|
||||
my $pwd_sent = 0;
|
||||
|
||||
##################################################
|
||||
# Shell prompt regexp based on HW Type
|
||||
##################################################
|
||||
my %prompt = (
|
||||
hmc => "~> \$",
|
||||
ivm => "\\\$ \$"
|
||||
);
|
||||
##################################################
|
||||
# Get userid/password based on Hardware Conrol Pt
|
||||
##################################################
|
||||
my @cred = xCAT::PPCdb::credentials( $server, $hwtype );
|
||||
|
||||
##################################################
|
||||
# ssh to remote host
|
||||
##################################################
|
||||
my $parameters = "$cred[0]\@$server";
|
||||
my $ssh = new Expect;
|
||||
|
||||
##################################################
|
||||
# raw_pty() disables command echoing and CRLF
|
||||
# translation and gives a more pipe-like behaviour.
|
||||
# Note that this must be set before spawning
|
||||
# the process. Unfortunately, this does not work
|
||||
# with AIX (IVM). stty(qw(-echo)) will at least
|
||||
# disable command echoing on all platforms but
|
||||
# will not suppress CRLF translation.
|
||||
##################################################
|
||||
#$ssh->raw_pty(1);
|
||||
$ssh->slave->stty(qw(sane -echo));
|
||||
|
||||
##################################################
|
||||
# exp_internal(1) sets exp_internal debugging.
|
||||
# This is similar in nature to its Tcl counterpart
|
||||
##################################################
|
||||
if ( $verbose ) {
|
||||
$ssh->exp_internal(1);
|
||||
}
|
||||
##################################################
|
||||
# log_stdout(0) disables logging to STDOUT. This
|
||||
# corresponds to the Tcl log_user variable.
|
||||
##################################################
|
||||
if ( !$verbose ) {
|
||||
$ssh->log_stdout(0);
|
||||
}
|
||||
unless ( $ssh->spawn( "ssh", $parameters )) {
|
||||
return( "Unable to spawn ssh connection to server" );
|
||||
}
|
||||
##################################################
|
||||
# -re $continue
|
||||
# "The authenticity of host can't be established
|
||||
# RSA key fingerprint is ....
|
||||
# Are you sure you want to continue connecting (yes/no)?"
|
||||
#
|
||||
# -re pwd_prompt
|
||||
# If the keys have already been transferred, we
|
||||
# may already be at the command prompt without
|
||||
# sending the password.
|
||||
#
|
||||
##################################################
|
||||
my @result = $ssh->expect( $timeout,
|
||||
[ $continue,
|
||||
sub {
|
||||
$ssh->send( "yes\r" );
|
||||
$ssh->clear_accum();
|
||||
$ssh->exp_continue();
|
||||
} ],
|
||||
[ $pwd_prompt,
|
||||
sub {
|
||||
if ( ++$pwd_sent == 1 ) {
|
||||
$ssh->send( "$cred[1]\r" );
|
||||
$ssh->exp_continue();
|
||||
}
|
||||
} ],
|
||||
[ $prompt{$hwtype},
|
||||
sub {
|
||||
$success = 1;
|
||||
} ]
|
||||
);
|
||||
##########################################
|
||||
# Expect error
|
||||
##########################################
|
||||
if ( defined( $result[1] )) {
|
||||
$ssh->hard_close();
|
||||
return( expect_error(@result) );
|
||||
}
|
||||
##########################################
|
||||
# Successful logon....
|
||||
# Return:
|
||||
# Expect
|
||||
# HW Shell Prompt regexp
|
||||
# HW Type (hmc/ivm)
|
||||
# Server hostname
|
||||
# UserId
|
||||
# Password
|
||||
##########################################
|
||||
if ( $success ) {
|
||||
return( $ssh,
|
||||
$prompt{$hwtype},
|
||||
$hwtype,
|
||||
$server,
|
||||
$cred[0],
|
||||
$cred[1] );
|
||||
}
|
||||
##########################################
|
||||
# Failed logon - kill ssh process
|
||||
##########################################
|
||||
$ssh->hard_close();
|
||||
return( "Invalid userid/password" );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Logoff to remote server
|
||||
##########################################################################
|
||||
sub disconnect {
|
||||
|
||||
my $exp = shift;
|
||||
my $ssh = @$exp[0];
|
||||
|
||||
$ssh->send( "exit\r" );
|
||||
$ssh->hard_close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# List attributes for resources (lpars, managed system, etc)
|
||||
##########################################################################
|
||||
sub lssyscfg {
|
||||
|
||||
my $exp = shift;
|
||||
my $res = shift;
|
||||
my $d1 = shift;
|
||||
my $d2 = shift;
|
||||
my $d3 = shift;
|
||||
|
||||
###################################
|
||||
# Select command
|
||||
###################################
|
||||
my $cmd = sprintf( $lssyscfg{$res}, $d1, $d2, $d3 );
|
||||
|
||||
###################################
|
||||
# Send command
|
||||
###################################
|
||||
my $result = send_cmd( $exp, $cmd );
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Changes a logical partition configuration data
|
||||
##########################################################################
|
||||
sub chsyscfg {
|
||||
|
||||
my $exp = shift;
|
||||
my $d = shift;
|
||||
my $cfgdata = shift;
|
||||
my $timeout = 60;
|
||||
|
||||
#####################################
|
||||
# Command only support on LPARs
|
||||
#####################################
|
||||
if ( @$d[4] ne "lpar" ) {
|
||||
return( [RC_ERROR,"Command not supported"] );
|
||||
}
|
||||
#####################################
|
||||
# Format command based on CEC name
|
||||
#####################################
|
||||
my $cmd = "chsyscfg -r prof -m @$d[2] -i \"$cfgdata\"";
|
||||
|
||||
#####################################
|
||||
# Send command
|
||||
#####################################
|
||||
my $result = send_cmd( $exp, $cmd, $timeout );
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Creates a logical partition on the managed system
|
||||
##########################################################################
|
||||
sub mksyscfg {
|
||||
|
||||
my $exp = shift;
|
||||
my $d = shift;
|
||||
my $cfgdata = shift;
|
||||
my $timeout = 60;
|
||||
|
||||
#####################################
|
||||
# Command only support on LPARs
|
||||
#####################################
|
||||
if ( @$d[4] ne "lpar" ) {
|
||||
return( [RC_ERROR,"Command not supported"] );
|
||||
}
|
||||
#####################################
|
||||
# Format command based on CEC name
|
||||
#####################################
|
||||
my $cmd = "mksyscfg -r lpar -m @$d[2] -i \"$cfgdata\"";
|
||||
|
||||
#####################################
|
||||
# Send command
|
||||
#####################################
|
||||
my $result = send_cmd( $exp, $cmd, $timeout );
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Removes a logical partition on the managed system
|
||||
##########################################################################
|
||||
sub rmsyscfg {
|
||||
|
||||
my $exp = shift;
|
||||
my $d = shift;
|
||||
my $timeout = 60;
|
||||
|
||||
#####################################
|
||||
# Command only supported on LPARs
|
||||
#####################################
|
||||
if ( @$d[4] ne "lpar" ) {
|
||||
return( [RC_ERROR,"Command not supported"] );
|
||||
}
|
||||
#####################################
|
||||
# Format command based on CEC name
|
||||
#####################################
|
||||
my $cmd = "rmsyscfg -r lpar -m @$d[2] --id @$d[0]";
|
||||
|
||||
#####################################
|
||||
# Send command
|
||||
#####################################
|
||||
my $result = send_cmd( $exp, $cmd, $timeout );
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Lists environmental information
|
||||
##########################################################################
|
||||
sub lshwinfo {
|
||||
|
||||
my $exp = shift;
|
||||
my $res = shift;
|
||||
my $frame = shift;
|
||||
my $filter = shift;
|
||||
|
||||
#####################################
|
||||
# Format command based on CEC name
|
||||
#####################################
|
||||
my $cmd = "lshwinfo -r $res -e $frame -F $filter";
|
||||
|
||||
#####################################
|
||||
# Send command
|
||||
#####################################
|
||||
my $result = send_cmd( $exp, $cmd );
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Changes the state of a partition or managed system
|
||||
##########################################################################
|
||||
sub chsysstate {
|
||||
|
||||
my $exp = shift;
|
||||
my $op = shift;
|
||||
my $d = shift;
|
||||
|
||||
#####################################
|
||||
# Format command based on CEC name
|
||||
#####################################
|
||||
my $cmd = power_cmd( $op, $d );
|
||||
if ( !defined( $cmd )) {
|
||||
return( [RC_ERROR,"'$op' command not supported"] );
|
||||
}
|
||||
#####################################
|
||||
# Special case - return immediately
|
||||
#####################################
|
||||
if ( $cmd =~ /^hmcshutdown|reboot/ ) {
|
||||
my $ssh = @$exp[0];
|
||||
|
||||
$ssh->send( "$cmd\r" );
|
||||
return( [SUCCESS,"Success"] );
|
||||
}
|
||||
#####################################
|
||||
# Increase timeout for power command
|
||||
#####################################
|
||||
my $timeout = 15;
|
||||
|
||||
#####################################
|
||||
# Send command
|
||||
#####################################
|
||||
my $result = send_cmd( $exp, $cmd, $timeout );
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Opens a virtual terminal session
|
||||
##########################################################################
|
||||
sub mkvterm {
|
||||
|
||||
my $exp = shift;
|
||||
my $type = shift;
|
||||
my $lparid = shift;
|
||||
my $mtms = shift;
|
||||
my $ssh = @$exp[0];
|
||||
my $hwtype = @$exp[2];
|
||||
my $failed = 0;
|
||||
my $timeout = 3;
|
||||
|
||||
##########################################
|
||||
# Format command based on HW Type
|
||||
##########################################
|
||||
my %mkvt = (
|
||||
hmc =>"mkvterm --id %s -m %s",
|
||||
ivm =>"mkvt -id %s"
|
||||
);
|
||||
##########################################
|
||||
# HMC returns:
|
||||
# "A terminal session is already open
|
||||
# for this partition. Only one open
|
||||
# session is allowed for a partition.
|
||||
# Exiting...."
|
||||
#
|
||||
# HMCs may also return:
|
||||
# "The open failed.
|
||||
# "-The session may already be open on
|
||||
# another management console"
|
||||
#
|
||||
# But Expect (for some reason) sees each
|
||||
# character preceeded with \000 (blank??)
|
||||
#
|
||||
##########################################
|
||||
my $ivm_open = "Virtual terminal is already connected";
|
||||
my $hmc_open = "\000o\000p\000e\000n\000 \000f\000a\000i\000l\000e\000d";
|
||||
my $hmc_open2 =
|
||||
"\000a\000l\000r\000e\000a\000d\000y\000 \000o\000p\000e\000n";
|
||||
|
||||
##########################################
|
||||
# Set command based on HW type
|
||||
# mkvterm -id lparid -m cecmtms
|
||||
##########################################
|
||||
my $cmd = sprintf( $mkvt{$hwtype}, $lparid, $mtms );
|
||||
if ( $type ne "lpar" ) {
|
||||
return( [RC_ERROR,"Command not supported"] );
|
||||
}
|
||||
##########################################
|
||||
# For IVM, console sessions must explicitly
|
||||
# be closed after each open using rmvt
|
||||
# or they will remain open indefinitely.
|
||||
# For example, if the session is opened
|
||||
# using xterm and closed with the [x] in
|
||||
# the windows upper-right corner, we will
|
||||
# not be able to catch (INT,HUP,QUIT,TERM)
|
||||
# before the window closes in order to
|
||||
# send an rmvt - so force any IVM sessions
|
||||
# closed before we start.
|
||||
#
|
||||
# For HMC, apparently, once the console
|
||||
# session connection is broken, the HMC
|
||||
# closes the session. Therefore, it is not
|
||||
# necessary to explicitly close the session.
|
||||
#
|
||||
##########################################
|
||||
if ( $hwtype eq "ivm" ) {
|
||||
rmvterm( $exp, $lparid, $mtms );
|
||||
sleep 1;
|
||||
}
|
||||
##########################################
|
||||
# Send command
|
||||
##########################################
|
||||
$ssh->clear_accum();
|
||||
$ssh->send( "$cmd\r" );
|
||||
|
||||
##########################################
|
||||
# Expect result
|
||||
##########################################
|
||||
my @result = $ssh->expect( $timeout,
|
||||
[ "$hmc_open|$hmc_open2|$ivm_open",
|
||||
sub {
|
||||
$failed = 1;
|
||||
} ]
|
||||
);
|
||||
|
||||
if ( $failed ) {
|
||||
$ssh->hard_close();
|
||||
return( [RC_ERROR,"Virtual terminal is already connected"] );
|
||||
}
|
||||
|
||||
##########################################
|
||||
# Success...
|
||||
# Give control to the user and intercept
|
||||
# the Ctrl-X (\030), and "~." sequences.
|
||||
##########################################
|
||||
my $escape = "\030|~.";
|
||||
$ssh->send( "\r" );
|
||||
$ssh->interact( \*STDIN, $escape );
|
||||
|
||||
##########################################
|
||||
# Close session
|
||||
##########################################
|
||||
rmvterm( $exp, $lparid, $mtms );
|
||||
$ssh->hard_close();
|
||||
|
||||
return( [SUCCESS,"Success"] );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Force close a virtual terminal session
|
||||
##########################################################################
|
||||
sub rmvterm {
|
||||
|
||||
my $exp = shift;
|
||||
my $lparid = shift;
|
||||
my $mtms = shift;
|
||||
my $ssh = @$exp[0];
|
||||
my $hwtype = @$exp[2];
|
||||
|
||||
#####################################
|
||||
# Format command based on HW Type
|
||||
#####################################
|
||||
my %rmvt = (
|
||||
hmc =>"rmvterm --id %s -m %s",
|
||||
ivm =>"rmvt -id %s"
|
||||
);
|
||||
#####################################
|
||||
# Set command based on HW type
|
||||
# rmvt(erm) -id lparid -m cecmtms
|
||||
#####################################
|
||||
my $cmd = sprintf( $rmvt{$hwtype}, $lparid, $mtms );
|
||||
|
||||
#####################################
|
||||
# Send command
|
||||
#####################################
|
||||
$ssh->clear_accum();
|
||||
$ssh->send( "$cmd\r" );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Lists the hardware resources of a managed system
|
||||
##########################################################################
|
||||
sub lshwres {
|
||||
|
||||
my $exp = shift;
|
||||
my $d = shift;
|
||||
my $mtms = shift;
|
||||
my $cmd = "lshwres -r @$d[1] -m $mtms -F @$d[2]";
|
||||
my $level = @$d[0];
|
||||
|
||||
#####################################
|
||||
# level may be "sys" or "lpar"
|
||||
#####################################
|
||||
if ( defined( $level )) {
|
||||
$cmd .=" --level $level";
|
||||
}
|
||||
#####################################
|
||||
# Send command
|
||||
#####################################
|
||||
my $result = send_cmd( $exp, $cmd );
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Retrieve MAC-address from network adapter or network boots an LPAR
|
||||
##########################################################################
|
||||
sub lpar_netboot {
|
||||
|
||||
my $exp = shift;
|
||||
my $name = shift;
|
||||
my $d = shift;
|
||||
my $server = shift;
|
||||
my $gateway = shift;
|
||||
my $client = shift;
|
||||
my $mac = shift;
|
||||
my $timeout = 300;
|
||||
my $cmd = "lpar_netboot -t ent";
|
||||
|
||||
#####################################
|
||||
# Get MAC-address or network boot
|
||||
#####################################
|
||||
$cmd.= (defined( $mac )) ? " -m $mac" : " -M -n";
|
||||
|
||||
#####################################
|
||||
# Command only supported on LPARs
|
||||
#####################################
|
||||
if ( @$d[4] ne "lpar" ) {
|
||||
return( [RC_ERROR,"Command not supported"] );
|
||||
}
|
||||
#####################################
|
||||
# Network specified (-D ping test)
|
||||
#####################################
|
||||
if ( defined( $server )) {
|
||||
$cmd.= (!defined( $mac )) ? " -D" : "";
|
||||
$cmd.= " -s auto -d auto -S $server -G $gateway -C $client";
|
||||
}
|
||||
#####################################
|
||||
# Add lpar name, profile, CEC name
|
||||
#####################################
|
||||
$cmd.= " \"$name\" \"@$d[1]\" \"@$d[2]\"";
|
||||
|
||||
#####################################
|
||||
# Send command
|
||||
#####################################
|
||||
my $result = send_cmd( $exp, $cmd, $timeout );
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# List Hardware Management Console configuration information
|
||||
##########################################################################
|
||||
sub lshmc {
|
||||
|
||||
my $exp = shift;
|
||||
my $hwtype = @$exp[2];
|
||||
my $timeout = 10;
|
||||
|
||||
#####################################
|
||||
# Format command based on HW Type
|
||||
#####################################
|
||||
my %cmd = (
|
||||
hmc =>"lshmc -v",
|
||||
ivm =>"lsivm"
|
||||
);
|
||||
|
||||
#####################################
|
||||
# Send command
|
||||
#####################################
|
||||
my $result = send_cmd( $exp, $cmd{$hwtype}, $timeout );
|
||||
|
||||
#####################################
|
||||
# Return error
|
||||
#####################################
|
||||
if ( @$result[0] != SUCCESS ) {
|
||||
return( $result );
|
||||
}
|
||||
#####################################
|
||||
# IVM returns:
|
||||
# 9133-55A,10B7D1G,1
|
||||
#
|
||||
# HMC returns:
|
||||
# "vpd=*FC ????????
|
||||
# *VC 20.0
|
||||
# *N2 Mon Sep 24 13:54:00 GMT 2007
|
||||
# *FC ????????
|
||||
# *DS Hardware Management Console
|
||||
# *TM 7310-CR4
|
||||
# *SE 1017E6B
|
||||
# *MN IBM
|
||||
# *PN Unknown
|
||||
# *SZ 1058721792
|
||||
# *OS Embedded Operating Systems
|
||||
# *NA 9.114.222.111
|
||||
# *FC ????????
|
||||
# *DS Platform Firmware
|
||||
# *RM V7R3.1.0.1
|
||||
#####################################
|
||||
if ( $hwtype eq "ivm" ) {
|
||||
my ($model,$serial,$lparid) = split /,/, @$result[1];
|
||||
return( [SUCCESS,"$model,$serial"] );
|
||||
}
|
||||
my @values;
|
||||
my $vpd = join( ",", @$result );
|
||||
|
||||
#####################################
|
||||
# Type-Model may be in the formats:
|
||||
# "eserver xSeries 336 -[7310CR3]-"
|
||||
# "7310-CR4"
|
||||
#####################################
|
||||
if ( $vpd =~ /\*TM ([^,]+)/ ) {
|
||||
my $temp = $1;
|
||||
my $model = ($temp =~ /\[(.*)\]/) ? $1 : $temp;
|
||||
push @values, $model;
|
||||
}
|
||||
#####################################
|
||||
# Serial number
|
||||
#####################################
|
||||
if ( $vpd =~ /\*SE ([^,]+)/ ) {
|
||||
push @values, $1;
|
||||
}
|
||||
return( [SUCCESS,join( ",",@values)] );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Sends command and waits for response
|
||||
##########################################################################
|
||||
sub send_cmd {
|
||||
|
||||
my $exp = shift;
|
||||
my $cmd = shift;
|
||||
my $timeout = shift;
|
||||
my $ssh = @$exp[0];
|
||||
my $prompt = @$exp[1];
|
||||
|
||||
##########################################
|
||||
# Set default Expect timeout
|
||||
##########################################
|
||||
if ( !defined( $timeout )) {
|
||||
$timeout = 10;
|
||||
}
|
||||
##########################################
|
||||
# Send command
|
||||
##########################################
|
||||
$ssh->clear_accum();
|
||||
$ssh->send( "$cmd; echo Rc=\$\?\r" );
|
||||
|
||||
##########################################
|
||||
# The first element is the number of the
|
||||
# pattern or string that matched, the
|
||||
# same as its return value in scalar
|
||||
# context. The second argument is a
|
||||
# string indicating why expect returned.
|
||||
# If there were no error, the second
|
||||
# argument will be undef. Possible errors
|
||||
# are 1:TIMEOUT, 2:EOF, 3:spawn id(...)died,
|
||||
# and "4:..." (see Expect (3) manpage for
|
||||
# the precise meaning of these messages)
|
||||
# The third argument of expects return list
|
||||
# is the string matched. The fourth argument
|
||||
# is text before the match, and the fifth
|
||||
# argument is text after the match.
|
||||
##########################################
|
||||
my @result = $ssh->expect( $timeout, "-re", "(.*$prompt)" );
|
||||
|
||||
##########################################
|
||||
# Expect error
|
||||
##########################################
|
||||
if ( defined( $result[1] )) {
|
||||
return( [EXPECT_ERROR,expect_error( @result )] );
|
||||
}
|
||||
##########################################
|
||||
# Extract error code
|
||||
##########################################
|
||||
if ( $result[3] =~ s/Rc=([0-9])+\r\n// ) {
|
||||
if ( $1 != 0 ) {
|
||||
return( [RC_ERROR,$result[3]] );
|
||||
}
|
||||
}
|
||||
##########################################
|
||||
# No data found - return error
|
||||
##########################################
|
||||
if ( $result[3] =~ /No results were found/ ) {
|
||||
return( [NR_ERROR,"No results were found"] );
|
||||
}
|
||||
##########################################
|
||||
# If no command output, return "Success"
|
||||
##########################################
|
||||
if ( length( $result[3] ) == 0 ) {
|
||||
$result[3] = "Success";
|
||||
}
|
||||
##########################################
|
||||
# Success
|
||||
##########################################
|
||||
my @values = ( SUCCESS );
|
||||
push @values, split /\r\n/, $result[3];
|
||||
return( \@values );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Return Expect error
|
||||
##########################################################################
|
||||
sub expect_error {
|
||||
|
||||
my @error = @_;
|
||||
|
||||
##########################################
|
||||
# The first element is the number of the
|
||||
# pattern or string that matched, the
|
||||
# same as its return value in scalar
|
||||
# context. The second argument is a
|
||||
# string indicating why expect returned.
|
||||
# If there were no error, the second
|
||||
# argument will be undef. Possible errors
|
||||
# are 1:TIMEOUT, 2:EOF, 3:spawn id(...)died,
|
||||
# and "4:..." (see Expect (3) manpage for
|
||||
# the precise meaning of these messages)
|
||||
# The third argument of expects return list
|
||||
# is the string matched. The fourth argument
|
||||
# is text before the match, and the fifth
|
||||
# argument is text after the match.
|
||||
##########################################
|
||||
if ( $error[1] eq "1:TIMEOUT" ) {
|
||||
return( "Timeout waiting for prompt" );
|
||||
}
|
||||
if ( $error[1] eq "2:EOF" ) {
|
||||
if ( $error[3] ) {
|
||||
return( $error[3] );
|
||||
}
|
||||
return( "ssh connection terminated unexpectedly" );
|
||||
}
|
||||
return( "Logon failed" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns built command based on CEC/LPAR action
|
||||
##########################################################################
|
||||
sub power_cmd {
|
||||
|
||||
my $op = shift;
|
||||
my $d = shift;
|
||||
my $type = @$d[4];
|
||||
|
||||
##############################
|
||||
# Build command
|
||||
##############################
|
||||
my $cmd = $powercmd{$type}{$op};
|
||||
|
||||
if ( defined( $cmd )) {
|
||||
return( sprintf( $cmd, $type, @$d[2],@$d[0],@$d[1] ));
|
||||
}
|
||||
##############################
|
||||
# Command not supported
|
||||
##############################
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
1;
|
178
perl-xCAT-2.0/xCAT/PPCdb.pm
Normal file
178
perl-xCAT-2.0/xCAT/PPCdb.pm
Normal file
@ -0,0 +1,178 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package xCAT::PPCdb;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use xCAT::Table;
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Adds an LPAR to the xCAT databases
|
||||
##########################################################################
|
||||
sub add_ppc {
|
||||
|
||||
my $hwtype = shift;
|
||||
my $values = shift;
|
||||
my @tabs = qw(ppc vpd nodehm nodelist);
|
||||
my %db = ();
|
||||
|
||||
###################################
|
||||
# Open database needed
|
||||
###################################
|
||||
foreach ( @tabs ) {
|
||||
$db{$_} = xCAT::Table->new( $_, -create=>1, -autocommit=>0 );
|
||||
if ( !$db{$_} ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
###################################
|
||||
# Update tables
|
||||
###################################
|
||||
foreach ( @$values ) {
|
||||
my ($type,
|
||||
$name,
|
||||
$id,
|
||||
$model,
|
||||
$serial,
|
||||
$server,
|
||||
$profile,
|
||||
$mgt,
|
||||
$ips ) = split /,/;
|
||||
|
||||
|
||||
###############################
|
||||
# Update ppc table
|
||||
###############################
|
||||
if ( $type =~ /^fsp|bpa|lpar$/ ) {
|
||||
my ($k,$u);
|
||||
$k->{node} = $name;
|
||||
$u->{hcp} = $server;
|
||||
$u->{id} = $id;
|
||||
$u->{profile} = $profile;
|
||||
$u->{mgt} = $mgt;
|
||||
$db{ppc}->setAttribs( $k, $u );
|
||||
$db{ppc}{commit} = 1;
|
||||
|
||||
###########################
|
||||
# Update nodelist table
|
||||
###########################
|
||||
my ($k1,$u1);
|
||||
my %nodetype = (
|
||||
fsp => "fsp",
|
||||
bpa => "bpa",
|
||||
lpar => "osi"
|
||||
);
|
||||
$k1->{node} = $name;
|
||||
$u1->{groups} = lc($hwtype).",all";
|
||||
$u1->{nodetype} = $nodetype{$type};
|
||||
$db{nodelist}->setAttribs( $k1,$u1 );
|
||||
$db{nodelist}{commit} = 1;
|
||||
|
||||
###########################
|
||||
# Update nodehm table
|
||||
###########################
|
||||
my ($k2,$u2);
|
||||
$k2->{node} = $name;
|
||||
$u2->{mgt} = $hwtype;
|
||||
$db{nodehm}->setAttribs( $k2,$u2 );
|
||||
$db{nodehm}{commit} = 1;
|
||||
}
|
||||
###############################
|
||||
# Update vpd table
|
||||
###############################
|
||||
if ( $type =~ /^fsp|bpa$/ ) {
|
||||
my ($k,$u);
|
||||
$k->{node} = $name;
|
||||
$u->{serial} = $serial;
|
||||
$u->{mtm} = $model;
|
||||
$db{vpd}->setAttribs( $k,$u );
|
||||
$db{vpd}{commit} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
###################################
|
||||
# Commit changes
|
||||
###################################
|
||||
foreach ( @tabs ) {
|
||||
if ( exists( $db{$_}{commit} )) {
|
||||
$db{$_}->commit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Adds a hardware control point to the xCAT database
|
||||
##########################################################################
|
||||
sub add_ppch {
|
||||
|
||||
my $hwtype = shift;
|
||||
my $uid = shift;
|
||||
my $pw = shift;
|
||||
my $name = shift;
|
||||
my $k;
|
||||
my $u;
|
||||
|
||||
###################################
|
||||
# Update HWCtrl Point table
|
||||
###################################
|
||||
my $tab = xCAT::Table->new( 'ppch', -create=>1, -autocommit=>0 );
|
||||
if ( !$tab ) {
|
||||
return;
|
||||
}
|
||||
$k->{hcp} = $name;
|
||||
$u->{username} = $uid;
|
||||
$u->{password} = $pw;
|
||||
|
||||
$tab->setAttribs( $k, $u );
|
||||
$tab->commit;
|
||||
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Get userids and passwords from tables
|
||||
##########################################################################
|
||||
sub credentials {
|
||||
|
||||
my $server = shift;
|
||||
my $hwtype = shift;
|
||||
my %db = (
|
||||
hmc => "ppchcp",
|
||||
ivm => "ppchcp",
|
||||
fsp => "ppcDirect"
|
||||
);
|
||||
|
||||
###########################################
|
||||
# Get userid/password based on HwCtrl Pt
|
||||
###########################################
|
||||
my $tab = xCAT::Table->new( $db{$hwtype} );
|
||||
if ( $tab ) {
|
||||
my ($ent) = $tab->getAttribs({'hcp'=>$server},'username','password');
|
||||
if ( defined( $ent ) ) {
|
||||
return( $ent->{username},$ent->{password} );
|
||||
}
|
||||
}
|
||||
###########################################
|
||||
# Get userid/password based on type
|
||||
###########################################
|
||||
$tab = xCAT::Table->new( 'passwd' );
|
||||
if ( $tab ) {
|
||||
my ($ent) = $tab->getAttribs({'key'=>$hwtype},'username','password');
|
||||
if ( defined( $ent ) ) {
|
||||
return( $ent->{username},$ent->{password} );
|
||||
}
|
||||
}
|
||||
###########################################
|
||||
# Use factory defaults
|
||||
###########################################
|
||||
my %logon = (
|
||||
hmc => ["hscroot","abc123"],
|
||||
ivm => ["padmin", "padmin"],
|
||||
fsp => ["dev", "FipSdev"]
|
||||
);
|
||||
return( @{$logon{$hwtype}}[0], @{$logon{$hwtype}}[1] );
|
||||
}
|
||||
|
||||
|
||||
1;
|
568
perl-xCAT-2.0/xCAT/PPCfsp.pm
Normal file
568
perl-xCAT-2.0/xCAT/PPCfsp.pm
Normal file
@ -0,0 +1,568 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package xCAT::PPCfsp;
|
||||
use strict;
|
||||
use LWP;
|
||||
use HTTP::Cookies;
|
||||
|
||||
|
||||
##########################################
|
||||
# Globals
|
||||
##########################################
|
||||
my %cmds = (
|
||||
rpower => {
|
||||
state => ["Power On/Off System", \&state],
|
||||
on => ["Power On/Off System", \&on],
|
||||
off => ["Power On/Off System", \&off],
|
||||
reset => ["System Reboot", \&reset],
|
||||
boot => ["Power On/Off System", \&boot] },
|
||||
reventlog => {
|
||||
all => ["Error/Event Logs", \&all],
|
||||
all_clear => ["Error/Event Logs", \&all_clear],
|
||||
entries => ["Error/Event Logs", \&entries],
|
||||
clear => ["Error/Event Logs", \&clear] }
|
||||
);
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# FSP command handler through HTTP interface
|
||||
##########################################################################
|
||||
sub handler {
|
||||
|
||||
my $server = shift;
|
||||
my $request = shift;
|
||||
my $command = $request->{command};
|
||||
my $verbose = $request->{verbose};
|
||||
my $method = $request->{method};
|
||||
my $start;
|
||||
|
||||
##################################
|
||||
# Check command
|
||||
##################################
|
||||
if ( !exists( $cmds{$command}{$method} )) {
|
||||
my %output;
|
||||
$output{node}->[0]->{name}->[0] = $server;
|
||||
$output{node}->[0]->{data}->[0]->{contents}->[0]= "Unsupported command";
|
||||
return( [\%output] );
|
||||
}
|
||||
##################################
|
||||
# Start timer
|
||||
##################################
|
||||
if ( $verbose ) {
|
||||
$start = Time::HiRes::gettimeofday();
|
||||
}
|
||||
##################################
|
||||
# Connect to remote FSP
|
||||
##################################
|
||||
my @exp = xCAT::PPCfsp::connect( $server, $verbose );
|
||||
|
||||
if ( ref($exp[0]) ne "LWP::UserAgent" ) {
|
||||
my %output;
|
||||
$output{node}->[0]->{name}->[0] = $server;
|
||||
$output{node}->[0]->{data}->[0]->{contents}->[0] = $exp[0];
|
||||
return( [\%output] );
|
||||
}
|
||||
##################################
|
||||
# Process FSP command
|
||||
##################################
|
||||
my $result = process_cmd( \@exp, $request );
|
||||
|
||||
my %output;
|
||||
$output{node}->[0]->{name}->[0] = $server;
|
||||
$output{node}->[0]->{data}->[0]->{contents}->[0] = $result;
|
||||
|
||||
##################################
|
||||
# Disconnect from FSP
|
||||
##################################
|
||||
xCAT::PPCfsp::disconnect( \@exp );
|
||||
|
||||
##################################
|
||||
# Record Total time
|
||||
##################################
|
||||
if ( $verbose ) {
|
||||
my $elapsed = Time::HiRes::gettimeofday() - $start;
|
||||
my $total = sprintf( "Total Elapsed Time: %.3f sec\n", $elapsed );
|
||||
print STDERR $total;
|
||||
}
|
||||
return( [\%output] );
|
||||
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Logon through remote FSP HTTP-interface
|
||||
##########################################################################
|
||||
sub connect {
|
||||
|
||||
my $server = shift;
|
||||
my $verbose = shift;
|
||||
|
||||
##################################
|
||||
# Get userid/password
|
||||
##################################
|
||||
my @cred = xCAT::PPCdb::credentials( $server, "fsp" );
|
||||
|
||||
##################################
|
||||
# Turn on tracing
|
||||
##################################
|
||||
if ( $verbose ) {
|
||||
LWP::Debug::level( '+' );
|
||||
}
|
||||
##################################
|
||||
# Create cookie
|
||||
##################################
|
||||
my $cookie = HTTP::Cookies->new();
|
||||
$cookie->set_cookie( 0,'asm_session','0','cgi-bin','','443',0,0,3600,0 );
|
||||
|
||||
##################################
|
||||
# Create UserAgent
|
||||
##################################
|
||||
my $ua = LWP::UserAgent->new();
|
||||
|
||||
##################################
|
||||
# Set options
|
||||
##################################
|
||||
my $url = "https://$server/cgi-bin/cgi?form=2";
|
||||
$ua->cookie_jar( $cookie );
|
||||
$ua->timeout(30);
|
||||
|
||||
##################################
|
||||
# Submit logon
|
||||
##################################
|
||||
my $res = $ua->post( $url,
|
||||
[ user => $cred[0],
|
||||
password => $cred[1],
|
||||
lang => "0",
|
||||
submit => "Log in"
|
||||
]
|
||||
);
|
||||
|
||||
##################################
|
||||
# Logon failed
|
||||
##################################
|
||||
if ( !$res->is_success() ) {
|
||||
return( $res->status_line );
|
||||
}
|
||||
##################################
|
||||
# To minimize number of GET/POSTs,
|
||||
# if we successfully logon, we should
|
||||
# get back a valid cookie:
|
||||
# Set-Cookie: asm_session=3038839768778613290
|
||||
#
|
||||
##################################
|
||||
|
||||
if ( $res->as_string =~ /Set-Cookie: asm_session=(\d+)/ ) {
|
||||
##############################
|
||||
# Successful logon....
|
||||
# Return:
|
||||
# UserAgent
|
||||
# Server hostname
|
||||
# UserId
|
||||
##############################
|
||||
return( $ua,
|
||||
$server,
|
||||
$cred[0] );
|
||||
}
|
||||
##############################
|
||||
# Logon error
|
||||
##############################
|
||||
$res = $ua->get( $url );
|
||||
|
||||
if ( !$res->is_success() ) {
|
||||
return( $res->status_line );
|
||||
}
|
||||
##############################
|
||||
# Check for specific failures
|
||||
##############################
|
||||
my @error = (
|
||||
"Invalid user ID or password",
|
||||
"Too many users"
|
||||
);
|
||||
foreach ( @error ) {
|
||||
if ( $res->content =~ /$_/i ) {
|
||||
return( $_ );
|
||||
}
|
||||
}
|
||||
return( "Logon failure" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Logoff through remote FSP HTTP-interface
|
||||
##########################################################################
|
||||
sub disconnect {
|
||||
|
||||
my $exp = shift;
|
||||
my $ua = @$exp[0];
|
||||
my $server = @$exp[1];
|
||||
my $uid = @$exp[2];
|
||||
|
||||
##################################
|
||||
# POST Logoff
|
||||
##################################
|
||||
my $res = $ua->post(
|
||||
"https://$server/cgi-bin/cgi?form=1",
|
||||
[submit => "Log out"]);
|
||||
|
||||
##################################
|
||||
# Logoff failed
|
||||
##################################
|
||||
if ( !$res->is_success() ) {
|
||||
return( $res->status_line );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Execute FSP command
|
||||
##########################################################################
|
||||
sub process_cmd {
|
||||
|
||||
my $exp = shift;
|
||||
my $request = shift;
|
||||
my $ua = @$exp[0];
|
||||
my $server = @$exp[1];
|
||||
my $uid = @$exp[2];
|
||||
my $command = $request->{command};
|
||||
my $method = $request->{method};
|
||||
my %menu = ();
|
||||
|
||||
##################################
|
||||
# We have to expand the main
|
||||
# menu since unfortunately, the
|
||||
# the forms numbers are not the
|
||||
# same across FSP models/firmware
|
||||
# versions.
|
||||
##################################
|
||||
my $url = "https://$server/cgi-bin/cgi";
|
||||
my $res = $ua->post( $url,
|
||||
[form => "2",
|
||||
e => "1" ]
|
||||
);
|
||||
##################################
|
||||
# Return error
|
||||
##################################
|
||||
if ( !$res->is_success() ) {
|
||||
return( $res->status_line );
|
||||
}
|
||||
##################################
|
||||
# Build hash of expanded menus
|
||||
##################################
|
||||
foreach ( split /\n/, $res->content ) {
|
||||
if ( /form=(\d+).*window.status='(.*)'/ ) {
|
||||
$menu{$2} = $1;
|
||||
}
|
||||
}
|
||||
##################################
|
||||
# Get form id
|
||||
##################################
|
||||
my $form = $menu{$cmds{$command}{$method}[0]};
|
||||
|
||||
if ( !defined( $form )) {
|
||||
return( "Cannot find '$cmds{$command}{$method}[0]' menu" );
|
||||
}
|
||||
##################################
|
||||
# Run command
|
||||
##################################
|
||||
my $result = $cmds{$command}{$method}[1]($exp, $request, $form, \%menu);
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns current power state
|
||||
##########################################################################
|
||||
sub state {
|
||||
|
||||
my $exp = shift;
|
||||
my $request = shift;
|
||||
my $form = shift;
|
||||
my $menu = shift;
|
||||
my $ua = @$exp[0];
|
||||
my $server = @$exp[1];
|
||||
|
||||
##################################
|
||||
# Get current power status
|
||||
##################################
|
||||
my $res = $ua->get( "https://$server/cgi-bin/cgi?form=$form" );
|
||||
|
||||
##################################
|
||||
# Return error
|
||||
##################################
|
||||
if ( !$res->is_success() ) {
|
||||
return( $res->status_line );
|
||||
}
|
||||
##################################
|
||||
# Get power state
|
||||
##################################
|
||||
if ( $res->content =~ /Current system power state: (.*)<br>/) {
|
||||
return( $1 );
|
||||
}
|
||||
return( "unknown" );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Powers FSP On
|
||||
##########################################################################
|
||||
sub on {
|
||||
return( power(@_,"on","on") );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Powers FSP Off
|
||||
##########################################################################
|
||||
sub off {
|
||||
return( power(@_,"off","of") );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Powers FSP On/Off
|
||||
##########################################################################
|
||||
sub power {
|
||||
|
||||
my $exp = shift;
|
||||
my $request = shift;
|
||||
my $form = shift;
|
||||
my $menu = shift;
|
||||
my $state = shift;
|
||||
my $button = shift;
|
||||
my $command = $request->{command};
|
||||
my $ua = @$exp[0];
|
||||
my $server = @$exp[1];
|
||||
|
||||
##################################
|
||||
# Send Power On command
|
||||
##################################
|
||||
my $res = $ua->post( "https://$server/cgi-bin/cgi",
|
||||
[form => $form,
|
||||
sp => "255", # System boot speed: Fast
|
||||
is => "1", # Firmware boot side for the next boot: Temporary
|
||||
om => "4", # System operating mode: Normal
|
||||
ip => "2", # Boot to system server firmware: Running
|
||||
plt => "3", # System power off policy: Stay on
|
||||
$button => "Save settings and power $state"]
|
||||
);
|
||||
##################################
|
||||
# Return error
|
||||
##################################
|
||||
if ( !$res->is_success() ) {
|
||||
return( $res->status_line );
|
||||
}
|
||||
if ( $res->content =~
|
||||
/(Powering on or off not allowed: invalid system state)/) {
|
||||
|
||||
##############################
|
||||
# Check current power state
|
||||
##############################
|
||||
my $state = xCAT::PPCfsp::state(
|
||||
$exp,
|
||||
$request,
|
||||
$menu->{$cmds{$command}{state}[0]},
|
||||
$menu );
|
||||
|
||||
if ( $state eq $state ) {
|
||||
return( "Success" );
|
||||
}
|
||||
return( $1 );
|
||||
}
|
||||
##################################
|
||||
# Success
|
||||
##################################
|
||||
if ( $res->content =~ /(Operation completed successfully)/ ) {
|
||||
return( $1 );
|
||||
}
|
||||
return( "Unknown error" );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Reset FSP
|
||||
##########################################################################
|
||||
sub reset {
|
||||
|
||||
my $exp = shift;
|
||||
my $request = shift;
|
||||
my $form = shift;
|
||||
my $menu = shift;
|
||||
my $ua = @$exp[0];
|
||||
my $server = @$exp[1];
|
||||
|
||||
##################################
|
||||
# Send Reset command
|
||||
##################################
|
||||
my $res = $ua->post( "https://$server/cgi-bin/cgi",
|
||||
[form => $form,
|
||||
submit => "Continue" ]
|
||||
);
|
||||
##################################
|
||||
# Return error
|
||||
##################################
|
||||
if ( !$res->is_success()) {
|
||||
print STDERR $res->status_line();
|
||||
return;
|
||||
}
|
||||
if ( $res->content =~
|
||||
/(This feature is only available when the system is powered on)/ ) {
|
||||
return( $1 );
|
||||
}
|
||||
##################################
|
||||
# Success
|
||||
##################################
|
||||
if ( $res->content =~ /(Operation completed successfully)/ ) {
|
||||
return( $1 );
|
||||
}
|
||||
return( "Unknown error" );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Boots FSP (Off->On, On->Reset)
|
||||
##########################################################################
|
||||
sub boot {
|
||||
|
||||
my $exp = shift;
|
||||
my $request = shift;
|
||||
my $form = shift;
|
||||
my $menu = shift;
|
||||
my $command = $request->{command};
|
||||
|
||||
##################################
|
||||
# Check current power state
|
||||
##################################
|
||||
my $state = xCAT::PPCfsp::state(
|
||||
$exp,
|
||||
$request,
|
||||
$menu->{$cmds{$command}{state}[0]},
|
||||
$menu );
|
||||
|
||||
if ( $state !~ /^on|off$/ ) {
|
||||
return( "Unable to boot in state: '$state'" );
|
||||
}
|
||||
##################################
|
||||
# Get command
|
||||
##################################
|
||||
my $method = ($state eq "on") ? "reset" : "off";
|
||||
|
||||
##################################
|
||||
# Get command form id
|
||||
##################################
|
||||
$form = $menu->{$cmds{$command}{$method}[0]};
|
||||
|
||||
##################################
|
||||
# Run command
|
||||
##################################
|
||||
my $result = $cmds{$method}[1]( $exp, $state, $form );
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Clears Error/Event Logs
|
||||
##########################################################################
|
||||
sub clear {
|
||||
|
||||
my $exp = shift;
|
||||
my $request = shift;
|
||||
my $form = shift;
|
||||
my $menu = shift;
|
||||
my $ua = @$exp[0];
|
||||
my $server = @$exp[1];
|
||||
|
||||
##################################
|
||||
# Send Clear command
|
||||
##################################
|
||||
my $url = "https://$server/cgi-bin/cgi";
|
||||
my $res = $ua->post( $url,
|
||||
[form => $form,
|
||||
submit => "Clear all error/event log entries" ]
|
||||
);
|
||||
##################################
|
||||
# Return error
|
||||
##################################
|
||||
if ( !$res->is_success() ) {
|
||||
return( $res->status_line );
|
||||
}
|
||||
return( "Success" );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Gets the number of Error/Event Logs entries specified
|
||||
##########################################################################
|
||||
sub entries {
|
||||
|
||||
my $exp = shift;
|
||||
my $request = shift;
|
||||
my $form = shift;
|
||||
my $menu = shift;
|
||||
my $ua = @$exp[0];
|
||||
my $server = @$exp[1];
|
||||
my $opt = $request->{opt};
|
||||
my $count = (exists($opt->{e})) ? $opt->{e} : 9999;
|
||||
my $result;
|
||||
my $i = 1;
|
||||
|
||||
##################################
|
||||
# Get log entries
|
||||
##################################
|
||||
my $url = "https://$server/cgi-bin/cgi?form=$form";
|
||||
my $res = $ua->get( $url );
|
||||
|
||||
##################################
|
||||
# Return error
|
||||
##################################
|
||||
if ( !$res->is_success() ) {
|
||||
return( $res->status_line );
|
||||
}
|
||||
my @entries = split /\n/, $res->content;
|
||||
|
||||
##################################
|
||||
# Prepend header
|
||||
##################################
|
||||
$result = (@entries) ?
|
||||
"#Log ID Time Failing subsystem Severity SRC\n" :
|
||||
"No entries";
|
||||
|
||||
##################################
|
||||
# Parse log entries
|
||||
##################################
|
||||
foreach ( @entries ) {
|
||||
if ( /tabindex=[\d]+><\/td><td>(.*)<\/td><td / ) {
|
||||
my $values = $1;
|
||||
$values =~ s/<\/td><td>/ /g;
|
||||
$result.= "$values\n";
|
||||
|
||||
if ( $i++ == $count ) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Gets all Error/Event Logs entries
|
||||
##########################################################################
|
||||
sub all {
|
||||
return( entries(@_) );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Gets all Error/Event Logs entries then clears the logs
|
||||
##########################################################################
|
||||
sub all_clear {
|
||||
|
||||
my $result = entries( @_ );
|
||||
clear( @_);
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
||||
1;
|
527
perl-xCAT-2.0/xCAT/PPCinv.pm
Normal file
527
perl-xCAT-2.0/xCAT/PPCinv.pm
Normal file
@ -0,0 +1,527 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package xCAT::PPCinv;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Parse the command line for options and operands
|
||||
##########################################################################
|
||||
sub parse_args {
|
||||
|
||||
my $request = shift;
|
||||
my $args = $request->{arg};
|
||||
my %opt = ();
|
||||
my @rinv = qw(bus config model serial all);
|
||||
my @VERSION = qw( 2.0 );
|
||||
|
||||
#############################################
|
||||
# Responds with usage statement
|
||||
#############################################
|
||||
local *usage = sub {
|
||||
return( [ $_[0],
|
||||
"rinv -h|--help",
|
||||
"rinv -v|--version",
|
||||
"rinv [-V|--verbose] noderange " . join( '|', @rinv ),
|
||||
" -h writes usage information to standard output",
|
||||
" -v displays command version",
|
||||
" -V verbose output" ]);
|
||||
};
|
||||
#############################################
|
||||
# Process command-line arguments
|
||||
#############################################
|
||||
if ( !defined( $args )) {
|
||||
return(usage( "No command specified" ));
|
||||
}
|
||||
#############################################
|
||||
# Checks case in GetOptions, allows opts
|
||||
# to be grouped (e.g. -vx), and terminates
|
||||
# at the first unrecognized option.
|
||||
#############################################
|
||||
@ARGV = @$args;
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
Getopt::Long::Configure( "bundling" );
|
||||
|
||||
if ( !GetOptions( \%opt, qw(h|help V|Verbose v|version) )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -h for Help
|
||||
####################################
|
||||
if ( exists( $opt{h} )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -v for version
|
||||
####################################
|
||||
if ( exists( $opt{v} )) {
|
||||
return( \@VERSION );
|
||||
}
|
||||
####################################
|
||||
# Check for "-" with no option
|
||||
####################################
|
||||
if ( grep(/^-$/, @ARGV )) {
|
||||
return(usage( "Missing option: -" ));
|
||||
}
|
||||
####################################
|
||||
# Unsupported command
|
||||
####################################
|
||||
my ($cmd) = grep(/^$ARGV[0]$/, @rinv );
|
||||
if ( !defined( $cmd )) {
|
||||
return(usage( "Invalid command: $ARGV[0]" ));
|
||||
}
|
||||
####################################
|
||||
# Check for an extra argument
|
||||
####################################
|
||||
shift @ARGV;
|
||||
if ( defined( $ARGV[0] )) {
|
||||
return(usage( "Invalid Argument: $ARGV[0]" ));
|
||||
}
|
||||
####################################
|
||||
# Set method to invoke
|
||||
####################################
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns VPD (model-type,serial-number)
|
||||
##########################################################################
|
||||
sub enumerate_vpd {
|
||||
|
||||
my $exp = shift;
|
||||
my $mtms = shift;
|
||||
my $hash = shift;
|
||||
my $filter = shift;
|
||||
my $cecname;
|
||||
my @vpd;
|
||||
|
||||
my ($name) = keys %{$hash->{$mtms}};
|
||||
my $type = @{$hash->{$mtms}->{$name}}[4];
|
||||
|
||||
######################################
|
||||
# HMCs and IVMs
|
||||
######################################
|
||||
if ( $type =~ /^hmc|ivm$/ ) {
|
||||
my $hcp = xCAT::PPCcli::lshmc( $exp );
|
||||
my $Rc = shift(@$hcp);
|
||||
|
||||
##############################
|
||||
# Return error
|
||||
##############################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
return( [$Rc,@$hcp[0]] );
|
||||
}
|
||||
##############################
|
||||
# Success
|
||||
##############################
|
||||
@vpd = split /,/, @$hcp[0];
|
||||
}
|
||||
######################################
|
||||
# BPAs
|
||||
######################################
|
||||
elsif ( $type =~ /^bpa$/ ) {
|
||||
my $filter = "type_model,serial_num";
|
||||
my $frame = xCAT::PPCcli::lssyscfg( $exp, $type, $mtms, $filter );
|
||||
my $Rc = shift(@$frame);
|
||||
|
||||
##############################
|
||||
# Return error
|
||||
##############################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
return( [$Rc,@$frame[0]] );
|
||||
}
|
||||
##############################
|
||||
# Success
|
||||
##############################
|
||||
@vpd = split /,/, @$frame[0];
|
||||
}
|
||||
######################################
|
||||
# CECs and LPARs
|
||||
######################################
|
||||
else {
|
||||
##############################
|
||||
# Send command for CEC only
|
||||
##############################
|
||||
my $cec = xCAT::PPCcli::lssyscfg( $exp, "fsp", $mtms, $filter );
|
||||
my $Rc = shift(@$cec);
|
||||
|
||||
##############################
|
||||
# Return error
|
||||
##############################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
return( [$Rc,@$cec[0]] );
|
||||
}
|
||||
##############################
|
||||
# Success
|
||||
##############################
|
||||
@vpd = split /,/, @$cec[0];
|
||||
}
|
||||
my %outhash = (
|
||||
model => $vpd[0],
|
||||
serial => $vpd[1]
|
||||
);
|
||||
return( [SUCCESS,\%outhash] );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns memory/processor information for CEC/LPARs
|
||||
##########################################################################
|
||||
sub enumerate_cfg {
|
||||
|
||||
my $exp = shift;
|
||||
my $mtms = shift;
|
||||
my $hash = shift;
|
||||
my %outhash = ();
|
||||
my $sys = 0;
|
||||
my @cmds = (
|
||||
[ "sys", "proc", "installed_sys_proc_units" ],
|
||||
[ "sys", "mem", "installed_sys_mem" ],
|
||||
[ "lpar","proc", "lpar_name,curr_procs" ],
|
||||
[ "lpar","mem", "lpar_name,curr_mem" ]
|
||||
);
|
||||
my $cecname;
|
||||
|
||||
my ($name) = keys %{$hash->{$mtms}};
|
||||
my $type = @{$hash->{$mtms}->{$name}}[4];
|
||||
|
||||
######################################
|
||||
# Invalid target hardware
|
||||
######################################
|
||||
if ( $type !~ /^fsp|lpar$/ ) {
|
||||
return( [RC_ERROR,"Information only available for CEC/LPAR"] );
|
||||
}
|
||||
######################################
|
||||
# Check for CECs in list
|
||||
######################################
|
||||
while (my ($name,$d) = each(%{$hash->{$mtms}}) ) {
|
||||
if ( @$d[4] eq "fsp" ) {
|
||||
$cecname = $name;
|
||||
last;
|
||||
}
|
||||
}
|
||||
######################################
|
||||
# No CECs - Skip command for CEC
|
||||
######################################
|
||||
if ( !defined( $cecname )) {
|
||||
shift @cmds;
|
||||
shift @cmds;
|
||||
}
|
||||
######################################
|
||||
# No LPARs - Skip command for LPAR
|
||||
######################################
|
||||
if (( keys %{$hash->{$mtms}} == 1 ) and ( scalar(@cmds) == 4 )) {
|
||||
pop @cmds;
|
||||
pop @cmds;
|
||||
}
|
||||
|
||||
foreach my $cmd( @cmds ) {
|
||||
my $result = xCAT::PPCcli::lshwres( $exp, $cmd, $mtms );
|
||||
my $Rc = shift(@$result);
|
||||
|
||||
##################################
|
||||
# Expect error
|
||||
##################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
return( [$Rc,@$result[0]] );
|
||||
}
|
||||
##################################
|
||||
# Success...
|
||||
# lshwres does not return CEC name
|
||||
# For CEC commands, insert name
|
||||
##################################
|
||||
if ( @$cmd[0] eq "sys" ) {
|
||||
foreach ( @$result[0] ) {
|
||||
s/(.*)/$cecname,$1/;
|
||||
}
|
||||
}
|
||||
##################################
|
||||
# Save by CEC/LPAR name
|
||||
##################################
|
||||
foreach ( @$result ) {
|
||||
my ($name,$value) = split /,/;
|
||||
push @{$outhash{ $name }}, $value;
|
||||
}
|
||||
}
|
||||
return( [SUCCESS,\%outhash] );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns I/O bus information
|
||||
##########################################################################
|
||||
sub enumerate_bus {
|
||||
|
||||
my $exp = shift;
|
||||
my $mtms = shift;
|
||||
my $hash = shift;
|
||||
my $filter = shift;
|
||||
my %outhash = ();
|
||||
my @res = qw(lpar);
|
||||
my @cmds = (
|
||||
undef,
|
||||
"io --rsubtype slot",
|
||||
$filter
|
||||
);
|
||||
my $cecname;
|
||||
|
||||
my ($name) = keys %{$hash->{$mtms}};
|
||||
my $type = @{$hash->{$mtms}->{$name}}[4];
|
||||
|
||||
##################################
|
||||
# Invalid target hardware
|
||||
##################################
|
||||
if ( $type !~ /^fsp|lpar$/ ) {
|
||||
return( [RC_ERROR,"Bus information only available for CEC/LPAR"] );
|
||||
}
|
||||
##################################
|
||||
# Send command for CEC only
|
||||
##################################
|
||||
my $cecs = xCAT::PPCcli::lshwres( $exp, \@cmds, $mtms );
|
||||
my $Rc = shift(@$cecs);
|
||||
|
||||
##################################
|
||||
# Return error
|
||||
##################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
return( [$Rc,@$cecs[0]] );
|
||||
}
|
||||
##################################
|
||||
# Success
|
||||
##################################
|
||||
my @bus = @$cecs;
|
||||
|
||||
##################################
|
||||
# Check for CECs in list
|
||||
##################################
|
||||
foreach ( keys %{$hash->{$mtms}} ) {
|
||||
if ( @{$hash->{$mtms}->{$_}}[4] eq "fsp" ) {
|
||||
$cecname = $_;
|
||||
last;
|
||||
}
|
||||
}
|
||||
##################################
|
||||
# Get LPAR names
|
||||
##################################
|
||||
my $lpars = xCAT::PPCcli::lssyscfg( $exp, "lpar", $mtms, "name" );
|
||||
$Rc = shift(@$lpars);
|
||||
|
||||
##################################
|
||||
# Return error
|
||||
##################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
return( [$Rc,@$lpars[0]] );
|
||||
}
|
||||
##################################
|
||||
# Save LPARs by name
|
||||
##################################
|
||||
foreach ( @$lpars ) {
|
||||
$outhash{$_} = \@bus;
|
||||
}
|
||||
##################################
|
||||
# Save CEC by name too
|
||||
##################################
|
||||
if ( defined( $cecname )) {
|
||||
$outhash{$cecname} = \@bus;
|
||||
}
|
||||
return( [SUCCESS,\%outhash] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns I/O bus information
|
||||
##########################################################################
|
||||
sub bus {
|
||||
|
||||
my $request = shift;
|
||||
my $hash = shift;
|
||||
my $exp = shift;
|
||||
my @result = ();
|
||||
my $filter = "drc_name,bus_id,description";
|
||||
|
||||
while (my ($mtms,$h) = each(%$hash) ) {
|
||||
#####################################
|
||||
# Get information for this CEC
|
||||
#####################################
|
||||
my $bus = enumerate_bus( $exp, $mtms, $hash, $filter );
|
||||
my $Rc = shift(@$bus);
|
||||
my $data = @$bus[0];
|
||||
|
||||
while (my ($name) = each(%$h) ) {
|
||||
#################################
|
||||
# Output header
|
||||
#################################
|
||||
push @result, [$name,"I/O Bus Information"];
|
||||
|
||||
#################################
|
||||
# Output error
|
||||
#################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
push @result, [$name,@$bus[0]];
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
# Node not found
|
||||
#################################
|
||||
if ( !exists( $data->{$name} )) {
|
||||
push @result, [$name,"Node not found"];
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
# Output values
|
||||
#################################
|
||||
foreach ( @{$data->{$name}} ) {
|
||||
s/,/:/;
|
||||
push @result, [$name,$_];
|
||||
}
|
||||
}
|
||||
}
|
||||
return( \@result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns VPD information
|
||||
##########################################################################
|
||||
sub vpd {
|
||||
|
||||
my $request = shift;
|
||||
my $hash = shift;
|
||||
my $exp = shift;
|
||||
my @cmds = $request->{method};
|
||||
my @result = ();
|
||||
my $filter = "type_model,serial_num";
|
||||
my %prefix = (
|
||||
model => ["Machine Type/Model",0],
|
||||
serial => ["Serial Number", 1]
|
||||
);
|
||||
|
||||
#########################################
|
||||
# Convert "all"
|
||||
#########################################
|
||||
if ( $cmds[0] eq "all" ) {
|
||||
@cmds = qw( model serial );
|
||||
}
|
||||
|
||||
while (my ($mtms,$h) = each(%$hash) ) {
|
||||
#####################################
|
||||
# Get information for this CEC
|
||||
#####################################
|
||||
my $vpd = enumerate_vpd( $exp, $mtms, $hash, $filter );
|
||||
my $Rc = shift(@$vpd);
|
||||
my $data = @$vpd[0];
|
||||
|
||||
while (my ($name) = each(%$h) ) {
|
||||
foreach ( @cmds ) {
|
||||
#############################
|
||||
# Output error
|
||||
#############################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
push @result, [$name,"@{$prefix{$_}}[0]: @$vpd[0]"];
|
||||
next;
|
||||
}
|
||||
#############################
|
||||
# Output value
|
||||
#############################
|
||||
my $value = "@{$prefix{$_}}[0]: $data->{$_}";
|
||||
push @result, [$name,$value];
|
||||
}
|
||||
}
|
||||
}
|
||||
return( \@result );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns memory/processor information
|
||||
##########################################################################
|
||||
sub config {
|
||||
|
||||
my $request = shift;
|
||||
my $hash = shift;
|
||||
my $exp = shift;
|
||||
my @result = ();
|
||||
my @prefix = (
|
||||
"Number of Processors: %s",
|
||||
"Total Memory (MB): %s"
|
||||
);
|
||||
|
||||
while (my ($mtms,$h) = each(%$hash) ) {
|
||||
#####################################
|
||||
# Get information for this CEC
|
||||
#####################################
|
||||
my $cfg = enumerate_cfg( $exp, $mtms, $hash );
|
||||
my $Rc = shift(@$cfg);
|
||||
my $data = @$cfg[0];
|
||||
|
||||
while (my ($name) = each(%$h) ) {
|
||||
#################################
|
||||
# Output header
|
||||
#################################
|
||||
push @result, [$name,"Machine Configuration Info"];
|
||||
my $i;
|
||||
|
||||
foreach ( @prefix ) {
|
||||
#############################
|
||||
# Output error
|
||||
#############################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
my $value = sprintf( "$_", $data );
|
||||
push @result, [$name,$value];
|
||||
next;
|
||||
}
|
||||
#############################
|
||||
# Node not found
|
||||
#############################
|
||||
if (!exists( $data->{$name} )) {
|
||||
push @result, [$name,"Node not found"];
|
||||
next;
|
||||
}
|
||||
#############################
|
||||
# Output value
|
||||
#############################
|
||||
my $value = sprintf( $_, @{$data->{$name}}[$i++] );
|
||||
push @result, [$name,$value];
|
||||
}
|
||||
}
|
||||
}
|
||||
return( \@result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns serial-number
|
||||
##########################################################################
|
||||
sub serial {
|
||||
return( vpd(@_) );
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Returns machine-type-model
|
||||
##########################################################################
|
||||
sub model {
|
||||
return( vpd(@_) );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns all inventory information
|
||||
##########################################################################
|
||||
sub all {
|
||||
|
||||
my @result = (
|
||||
@{vpd(@_)},
|
||||
@{bus(@_)},
|
||||
@{config(@_)}
|
||||
);
|
||||
return( \@result );
|
||||
}
|
||||
|
||||
|
||||
1;
|
109
perl-xCAT-2.0/xCAT/PPClog.pm
Normal file
109
perl-xCAT-2.0/xCAT/PPClog.pm
Normal file
@ -0,0 +1,109 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package xCAT::PPClog;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Parse the command line for options and operands
|
||||
##########################################################################
|
||||
sub parse_args {
|
||||
|
||||
my $request = shift;
|
||||
my $args = $request->{arg};
|
||||
my %opt = ();
|
||||
my @reventlog = qw(clear all all_clear);
|
||||
my @VERSION = qw( 2.0 );
|
||||
my $cmd;
|
||||
|
||||
#############################################
|
||||
# Responds with usage statement
|
||||
#############################################
|
||||
local *usage = sub {
|
||||
return( [ $_[0],
|
||||
"reventlog -h|--help",
|
||||
"reventlog -v|--version",
|
||||
"reventlog [-V|--verbose] noderange " . join( '|', @reventlog ),
|
||||
" -h writes usage information to standard output",
|
||||
" -v displays command version",
|
||||
" -V verbose output",
|
||||
" -e Reads number of entries specified, starting with first"])
|
||||
};
|
||||
#############################################
|
||||
# Process command-line arguments
|
||||
#############################################
|
||||
if ( !defined( $args )) {
|
||||
return(usage( "No command specified" ));
|
||||
}
|
||||
#############################################
|
||||
# Checks case in GetOptions, allows opts
|
||||
# to be grouped (e.g. -vx), and terminates
|
||||
# at the first unrecognized option.
|
||||
#############################################
|
||||
@ARGV = @$args;
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
Getopt::Long::Configure( "bundling" );
|
||||
|
||||
if ( !GetOptions( \%opt, qw(h|help V|Verbose v|version e=s) )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -v for version
|
||||
####################################
|
||||
if ( exists( $opt{v} )) {
|
||||
return( \@VERSION );
|
||||
}
|
||||
####################################
|
||||
# Option -h for Help
|
||||
####################################
|
||||
if ( exists( $opt{h} )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -v for version
|
||||
####################################
|
||||
if ( exists( $opt{v} )) {
|
||||
return( \@VERSION );
|
||||
}
|
||||
####################################
|
||||
# Check for "-" with no option
|
||||
####################################
|
||||
if ( grep(/^-$/, @ARGV )) {
|
||||
return(usage( "Missing option: -" ));
|
||||
}
|
||||
####################################
|
||||
# Check for non-zero integer
|
||||
####################################
|
||||
if ( exists( $opt{e} )) {
|
||||
if ( $opt{e} !~ /^[1-9]{1}$|^[1-9]{1}[0-9]+$/ ) {
|
||||
return(usage( "Invalid entry: $opt{e}" ));
|
||||
}
|
||||
$cmd = "entries";
|
||||
}
|
||||
else {
|
||||
################################
|
||||
# Unsupported commands
|
||||
################################
|
||||
($cmd) = grep(/^$ARGV[0]$/, @reventlog );
|
||||
if ( !defined( $cmd )) {
|
||||
return(usage( "Invalid command: $ARGV[0]" ));
|
||||
}
|
||||
shift @ARGV;
|
||||
}
|
||||
####################################
|
||||
# Check for an extra argument
|
||||
####################################
|
||||
if ( defined( $ARGV[0] )) {
|
||||
return(usage( "Invalid Argument: $ARGV[0]" ));
|
||||
}
|
||||
####################################
|
||||
# Set method to invoke
|
||||
####################################
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
|
||||
|
||||
|
||||
1;
|
227
perl-xCAT-2.0/xCAT/PPCmac.pm
Normal file
227
perl-xCAT-2.0/xCAT/PPCmac.pm
Normal file
@ -0,0 +1,227 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package xCAT::PPCmac;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Parse the command line for options and operands
|
||||
##########################################################################
|
||||
sub parse_args {
|
||||
|
||||
my $request = shift;
|
||||
my %opt = ();
|
||||
my $cmd = $request->{command};
|
||||
my $args = $request->{arg};
|
||||
my @VERSION = qw( 2.0 );
|
||||
|
||||
#############################################
|
||||
# Responds with usage statement
|
||||
#############################################
|
||||
local *usage = sub {
|
||||
return( [ $_[0],
|
||||
"getmacs -h|--help",
|
||||
"getmacs -v|--version",
|
||||
"getmacs [-V|--verbose] noderange [-S server -G gateway -C client]",
|
||||
" -h writes usage information to standard output",
|
||||
" -v displays command version",
|
||||
" -C IP of the partition",
|
||||
" -G Gateway IP of the partition specified",
|
||||
" -S Server IP to ping",
|
||||
" -V verbose output" ]);
|
||||
};
|
||||
#############################################
|
||||
# Process command-line arguments
|
||||
#############################################
|
||||
if ( !defined( $args )) {
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
#############################################
|
||||
# Checks case in GetOptions, allows opts
|
||||
# to be grouped (e.g. -vx), and terminates
|
||||
# at the first unrecognized option.
|
||||
#############################################
|
||||
@ARGV = @$args;
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
Getopt::Long::Configure( "bundling" );
|
||||
|
||||
if ( !GetOptions( \%opt, qw(h|help V|Verbose v|version C=s G=s S=s) )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -h for Help
|
||||
####################################
|
||||
if ( exists( $opt{h} )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -v for version
|
||||
####################################
|
||||
if ( exists( $opt{v} )) {
|
||||
return( \@VERSION );
|
||||
}
|
||||
####################################
|
||||
# Check for "-" with no option
|
||||
####################################
|
||||
if ( grep(/^-$/, @ARGV )) {
|
||||
return(usage( "Missing option: -" ));
|
||||
}
|
||||
####################################
|
||||
# Check for an extra argument
|
||||
####################################
|
||||
if ( defined( $ARGV[0] )) {
|
||||
return(usage( "Invalid Argument: $ARGV[0]" ));
|
||||
}
|
||||
####################################
|
||||
# If one specified, all required
|
||||
####################################
|
||||
my @network;
|
||||
foreach ( qw(C G S) ) {
|
||||
if ( exists($opt{$_}) ) {
|
||||
push @network, $_;
|
||||
}
|
||||
}
|
||||
if ( @network ) {
|
||||
if ( scalar(@network) != 3 ) {
|
||||
return( usage() );
|
||||
}
|
||||
my $result = validate_ip( $opt{C}, $opt{G}, $opt{S} );
|
||||
if ( @$result[0] ) {
|
||||
return(usage( @$result[1] ));
|
||||
}
|
||||
}
|
||||
####################################
|
||||
# Set method to invoke
|
||||
####################################
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Validate list of IPs
|
||||
##########################################################################
|
||||
sub validate_ip {
|
||||
|
||||
foreach my $ip (@_) {
|
||||
###################################
|
||||
# Length is 4 for IPv4 addresses
|
||||
###################################
|
||||
my (@octets) = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
||||
if ( scalar(@octets) != 4 ) {
|
||||
return( [1,"Invalid IP address: $ip"] );
|
||||
}
|
||||
foreach my $octet ( @octets ) {
|
||||
if (( $octet < 0 ) or ( $octet > 255 )) {
|
||||
return( [1,"Invalid IP address: $ip"] );
|
||||
}
|
||||
}
|
||||
}
|
||||
return([0]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# IVM get LPAR MAC addresses
|
||||
##########################################################################
|
||||
sub ivm_getmacs {
|
||||
|
||||
my $request = shift;
|
||||
my $d = shift;
|
||||
my $exp = shift;
|
||||
my $name = shift;
|
||||
|
||||
return( [[RC_ERROR,"Not Implemented"]] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Get LPAR MAC addresses
|
||||
##########################################################################
|
||||
sub getmacs {
|
||||
|
||||
my $request = shift;
|
||||
my $d = shift;
|
||||
my $exp = shift;
|
||||
my $opt = $request->{opt};
|
||||
my $hwtype = @$exp[2];
|
||||
my @output;
|
||||
|
||||
#########################################
|
||||
# Get node data
|
||||
#########################################
|
||||
my $type = @$d[4];
|
||||
my $name = @$d[6];
|
||||
|
||||
#########################################
|
||||
# Invalid target hardware
|
||||
#########################################
|
||||
if ( $type ne "lpar" ) {
|
||||
return( [[$name,"Node must be LPAR"]] );
|
||||
}
|
||||
#########################################
|
||||
# IVM does not have lpar_netboot command
|
||||
# so we have to manually collect MAC
|
||||
# addresses.
|
||||
#########################################
|
||||
if ( $hwtype eq "ivm" ) {
|
||||
return( ivm_getmacs( $request, $d, $exp, $name ));
|
||||
}
|
||||
my $result = xCAT::PPCcli::lpar_netboot(
|
||||
$exp,
|
||||
$name,
|
||||
$d,
|
||||
$opt->{S},
|
||||
$opt->{G},
|
||||
$opt->{C} );
|
||||
|
||||
my $Rc = shift(@$result);
|
||||
|
||||
##################################
|
||||
# Return error
|
||||
##################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
return( [[$name,@$result]] );
|
||||
}
|
||||
##################################
|
||||
# Success - verbose output
|
||||
##################################
|
||||
my $data = join( '',@$result );
|
||||
|
||||
if ( exists($request->{verbose}) ) {
|
||||
return( [[$name,$data]] );
|
||||
}
|
||||
##################################
|
||||
# lpar_netboot returns:
|
||||
#
|
||||
# Connecting to lpar4\r\n
|
||||
# Connected\r\n
|
||||
# Checking for power off.\r\n
|
||||
# Power off complete.\r\n
|
||||
# Power on lpar4 to Open Firmware.\r\n
|
||||
# Power on complete.\r\n
|
||||
# Getting adapter location codes.\r\n
|
||||
# Type\t Location Code\t MAC Address\t Full Path Name\t
|
||||
# Ping Result\t Device Type\r\nent U9117.MMA.10F6F3D-V5-C3-T1
|
||||
# 1e0e122a930d /vdevice/l-lan@30000003 virtual\r\n
|
||||
#####################################
|
||||
$data =~ /Device Type(.*)/;
|
||||
my $values;
|
||||
|
||||
foreach ( split /\r\n/, $1 ) {
|
||||
if ( /ent ([^\s]+) ([^\s]+)/ ) {
|
||||
$values.= "$1:".uc($2);
|
||||
}
|
||||
}
|
||||
return( [[$name,$values]] );
|
||||
}
|
||||
|
||||
|
||||
1;
|
331
perl-xCAT-2.0/xCAT/PPCpower.pm
Normal file
331
perl-xCAT-2.0/xCAT/PPCpower.pm
Normal file
@ -0,0 +1,331 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package xCAT::PPCpower;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Parse the command line for options and operands
|
||||
##########################################################################
|
||||
sub parse_args {
|
||||
|
||||
my $request = shift;
|
||||
my $args = $request->{arg};
|
||||
my %opt = ();
|
||||
my @rpower = qw(on off stat state reset boot of);
|
||||
my @VERSION = qw( 2.0 );
|
||||
|
||||
#############################################
|
||||
# Responds with usage statement
|
||||
#############################################
|
||||
local *usage = sub {
|
||||
return( [ $_[0],
|
||||
"rpower -h|--help",
|
||||
"rpower -v|--version",
|
||||
"rpower [-V|--verbose] noderange " . join( '|', @rpower ),
|
||||
" -h writes usage information to standard output",
|
||||
" -v displays command version",
|
||||
" -V verbose output" ]);
|
||||
};
|
||||
#############################################
|
||||
# Process command-line arguments
|
||||
#############################################
|
||||
if ( !defined( $args )) {
|
||||
return(usage( "No command specified" ));
|
||||
}
|
||||
#############################################
|
||||
# Checks case in GetOptions, allows opts
|
||||
# to be grouped (e.g. -vx), and terminates
|
||||
# at the first unrecognized option.
|
||||
#############################################
|
||||
@ARGV = @$args;
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
Getopt::Long::Configure( "bundling" );
|
||||
|
||||
if ( !GetOptions( \%opt, qw(h|help V|Verbose v|version) )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -v for version
|
||||
####################################
|
||||
if ( exists( $opt{v} )) {
|
||||
return( \@VERSION );
|
||||
}
|
||||
####################################
|
||||
# Option -h for Help
|
||||
####################################
|
||||
if ( exists( $opt{h} )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -v for version
|
||||
####################################
|
||||
if ( exists( $opt{v} )) {
|
||||
return( \@VERSION );
|
||||
}
|
||||
####################################
|
||||
# Check for "-" with no option
|
||||
####################################
|
||||
if ( grep(/^-$/, @ARGV )) {
|
||||
return(usage( "Missing option: -" ));
|
||||
}
|
||||
####################################
|
||||
# Unsupported commands
|
||||
####################################
|
||||
my ($cmd) = grep(/^$ARGV[0]$/, @rpower );
|
||||
if ( !defined( $cmd )) {
|
||||
return(usage( "Invalid command: $ARGV[0]" ));
|
||||
}
|
||||
####################################
|
||||
# Check for an extra argument
|
||||
####################################
|
||||
shift @ARGV;
|
||||
if ( defined( $ARGV[0] )) {
|
||||
return(usage( "Invalid Argument: $ARGV[0]" ));
|
||||
}
|
||||
####################################
|
||||
# Change "stat" to "state"
|
||||
####################################
|
||||
$request->{op} = $cmd;
|
||||
$cmd =~ s/^stat$/state/;
|
||||
|
||||
####################################
|
||||
# Power commands special case
|
||||
####################################
|
||||
if ( $cmd ne "state" ) {
|
||||
$cmd = ($cmd eq "boot") ? "powercmd_boot" : "powercmd";
|
||||
}
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Builds a hash of CEC/LPAR information returned from HMC/IVM
|
||||
##########################################################################
|
||||
sub enumerate {
|
||||
|
||||
my $exp = shift;
|
||||
my $node = shift;
|
||||
my $mtms = shift;
|
||||
my $filter = shift;
|
||||
my %outhash = ();
|
||||
my %cmds = ();
|
||||
|
||||
######################################
|
||||
# Check for CEC/LPAR/BPAs in list
|
||||
######################################
|
||||
while (my ($name,$d) = each(%$node) ) {
|
||||
if ( @$d[4] =~ /^fsp|lpar|bpa$/ ) {
|
||||
$cmds{@$d[4]} = 1;
|
||||
}
|
||||
}
|
||||
######################################
|
||||
# Check for HMC/IVMs in list
|
||||
######################################
|
||||
my ($name) = keys %$node;
|
||||
my $type = @{$node->{$name}}[4];
|
||||
|
||||
if ( $type =~ /^hmc|ivm$/ ) {
|
||||
$outhash{$name} = "Running";
|
||||
}
|
||||
|
||||
foreach ( keys %cmds ) {
|
||||
my $values = xCAT::PPCcli::lssyscfg( $exp, $_, $mtms, $filter );
|
||||
my $Rc = shift(@$values);
|
||||
|
||||
##################################
|
||||
# Return error
|
||||
##################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
return( [$Rc,@$values[0]] );
|
||||
}
|
||||
##################################
|
||||
# Save LPARs by name
|
||||
##################################
|
||||
foreach ( @$values ) {
|
||||
my ($name,$state) = split /,/;
|
||||
$outhash{ $name } = $state;
|
||||
}
|
||||
}
|
||||
return( [SUCCESS,\%outhash] );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Performs boot operation (Off->On, On->Reset)
|
||||
##########################################################################
|
||||
sub powercmd_boot {
|
||||
|
||||
my $request = shift;
|
||||
my $hash = shift;
|
||||
my $exp = shift;
|
||||
my $filter = "name,state";
|
||||
my @output = ();
|
||||
|
||||
######################################
|
||||
# Power commands are grouped by CEC
|
||||
# not Hardware Control Point
|
||||
######################################
|
||||
|
||||
######################################
|
||||
# Get CEC MTMS
|
||||
######################################
|
||||
my ($name) = keys %$hash;
|
||||
my $mtms = @{$hash->{$name}}[2];
|
||||
|
||||
######################################
|
||||
# Build CEC/LPAR information hash
|
||||
######################################
|
||||
my $stat = enumerate( $exp, $hash, $mtms, $filter );
|
||||
my $Rc = shift(@$stat);
|
||||
my $data = @$stat[0];
|
||||
|
||||
while (my ($name,$d) = each(%$hash) ) {
|
||||
##################################
|
||||
# Output error
|
||||
##################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
push @output, [$name,$data];
|
||||
next;
|
||||
}
|
||||
##################################
|
||||
# Node not found
|
||||
##################################
|
||||
if ( !exists( $data->{$name} )) {
|
||||
push @output, [$name,"Node not found"];
|
||||
next;
|
||||
}
|
||||
##################################
|
||||
# Convert state to on/off
|
||||
##################################
|
||||
my $state = power_status($data->{$name});
|
||||
my $op = ($state =~ /^Off|Not Activated$/) ? "on" : "reset";
|
||||
|
||||
##############################
|
||||
# Send power command
|
||||
##############################
|
||||
my $result = xCAT::PPCcli::chsysstate(
|
||||
$exp,
|
||||
$op,
|
||||
$d );
|
||||
push @output, [$name,@$result[1]];
|
||||
}
|
||||
return( \@output );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Performs power control operations (on,off,reboot,etc)
|
||||
##########################################################################
|
||||
sub powercmd {
|
||||
|
||||
my $request = shift;
|
||||
my $hash = shift;
|
||||
my $exp = shift;
|
||||
my @result = ();
|
||||
|
||||
####################################
|
||||
# Power commands are grouped by CEC
|
||||
# not Hardware Control Point
|
||||
####################################
|
||||
|
||||
while (my ($name,$d) = each(%$hash) ) {
|
||||
################################
|
||||
# Send command to each LPAR
|
||||
################################
|
||||
my $values = xCAT::PPCcli::chsysstate(
|
||||
$exp,
|
||||
$request->{op},
|
||||
$d );
|
||||
my $Rc = shift(@$values);
|
||||
|
||||
################################
|
||||
# Return result
|
||||
################################
|
||||
push @result, [$name,@$values[0]];
|
||||
}
|
||||
return( \@result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Queries CEC/LPAR power status (On or Off)
|
||||
##########################################################################
|
||||
sub power_status {
|
||||
|
||||
my @states = (
|
||||
"Operating",
|
||||
"Running",
|
||||
"Open Firmware"
|
||||
);
|
||||
foreach ( @states ) {
|
||||
if ( /^$_[0]$/ ) {
|
||||
return("on");
|
||||
}
|
||||
}
|
||||
return("off");
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Queries CEC/LPAR power state
|
||||
##########################################################################
|
||||
sub state {
|
||||
|
||||
my $request = shift;
|
||||
my $hash = shift;
|
||||
my $exp = shift;
|
||||
my $prefix = shift;
|
||||
my $convert = shift;
|
||||
my $filter = "name,state";
|
||||
my @result = ();
|
||||
|
||||
if ( !defined( $prefix )) {
|
||||
$prefix = "";
|
||||
}
|
||||
while (my ($mtms,$h) = each(%$hash) ) {
|
||||
######################################
|
||||
# Build CEC/LPAR information hash
|
||||
######################################
|
||||
my $stat = enumerate( $exp, $h, $mtms, $filter );
|
||||
my $Rc = shift(@$stat);
|
||||
my $data = @$stat[0];
|
||||
|
||||
while (my ($name,$d) = each(%$h) ) {
|
||||
##################################
|
||||
# Output error
|
||||
##################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
push @result, [$name, "$prefix$data"];
|
||||
next;
|
||||
}
|
||||
##################################
|
||||
# Node not found
|
||||
##################################
|
||||
if ( !exists( $data->{$name} )) {
|
||||
push @result, [$name, $prefix."Node not found"];
|
||||
next;
|
||||
}
|
||||
##################################
|
||||
# Output value
|
||||
##################################
|
||||
my $value = $data->{$name};
|
||||
|
||||
##############################
|
||||
# Convert state to on/off
|
||||
##############################
|
||||
if ( defined( $convert )) {
|
||||
$value = power_status( $value );
|
||||
}
|
||||
push @result, [$name,"$prefix$value"];
|
||||
}
|
||||
}
|
||||
return( \@result );
|
||||
}
|
||||
|
||||
|
||||
|
||||
1;
|
488
perl-xCAT-2.0/xCAT/PPCscan.pm
Normal file
488
perl-xCAT-2.0/xCAT/PPCscan.pm
Normal file
@ -0,0 +1,488 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package xCAT::PPCscan;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use XML::Simple;
|
||||
use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
|
||||
use xCAT::PPCdb;
|
||||
|
||||
##############################################
|
||||
# Globals
|
||||
##############################################
|
||||
my @header = (
|
||||
["type", "%-8s" ],
|
||||
["name", "placeholder" ],
|
||||
["id", "%-8s" ],
|
||||
["type-model", "%-12s" ],
|
||||
["serial-number", "%-15s" ],
|
||||
["address", "%s\n" ]);
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Parse the command line for options and operands
|
||||
##########################################################################
|
||||
sub parse_args {
|
||||
|
||||
my $request = shift;
|
||||
my %opt = ();
|
||||
my $cmd = $request->{command};
|
||||
my $args = $request->{arg};
|
||||
my @VERSION = qw( 2.0 );
|
||||
|
||||
#############################################
|
||||
# Responds with usage statement
|
||||
#############################################
|
||||
local *usage = sub {
|
||||
return( [ $_[0],
|
||||
"rscan -h",
|
||||
"rscan -v|--version",
|
||||
"rscan [-V|--verbose] noderange [-w][-x]",
|
||||
" -h writes usage information to standard output",
|
||||
" -v displays command version",
|
||||
" -V verbose output",
|
||||
" -w writes output to xCat database",
|
||||
" -x xml formatted output",
|
||||
" -z stanza formatted output." ]);
|
||||
};
|
||||
#############################################
|
||||
# Process command-line arguments
|
||||
#############################################
|
||||
if ( !defined( $args )) {
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
#############################################
|
||||
# Checks case in GetOptions, allows opts
|
||||
# to be grouped (e.g. -vx), and terminates
|
||||
# at the first unrecognized option.
|
||||
#############################################
|
||||
@ARGV = @$args;
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
Getopt::Long::Configure( "bundling" );
|
||||
|
||||
if ( !GetOptions( \%opt, qw(h|help V|Verbose v|version w x z) )){
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -h for Help
|
||||
####################################
|
||||
if ( exists( $opt{h} )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -v for version
|
||||
####################################
|
||||
if ( exists( $opt{v} )) {
|
||||
return( \@VERSION );
|
||||
}
|
||||
####################################
|
||||
# Check for "-" with no option
|
||||
####################################
|
||||
if ( grep(/^-$/, @ARGV )) {
|
||||
return(usage( "Missing option: -" ));
|
||||
}
|
||||
####################################
|
||||
# Check for an argument
|
||||
####################################
|
||||
if ( defined( $ARGV[0] )) {
|
||||
return(usage( "Invalid Argument: $ARGV[0]" ));
|
||||
}
|
||||
#############################################
|
||||
# Check for mutually-exclusive formatting
|
||||
#############################################
|
||||
if (( exists($opt{x}) + exists($opt{z})) > 1 ) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# No operands - add command name
|
||||
####################################
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns I/O bus information
|
||||
##########################################################################
|
||||
sub enumerate {
|
||||
|
||||
my $exp = shift;
|
||||
my $hwtype = @$exp[2];
|
||||
my $server = @$exp[3];
|
||||
my @values = ();
|
||||
my %cage = ();
|
||||
|
||||
#####################################################
|
||||
# Cache all type information as:
|
||||
# type,name,id,model,serial,hcp,profile,frame,ips
|
||||
#####################################################
|
||||
|
||||
#########################################
|
||||
# Get hardware control point info
|
||||
#########################################
|
||||
my $hcp = xCAT::PPCcli::lshmc( $exp );
|
||||
my $Rc = shift(@$hcp);
|
||||
|
||||
#########################################
|
||||
# Return error
|
||||
#########################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
return( @$hcp[0] );
|
||||
}
|
||||
#########################################
|
||||
# Success
|
||||
#########################################
|
||||
my ($model,$serial) = split /,/, @$hcp[0];
|
||||
my ($prof,$id,$ips,$bpa) = undef;
|
||||
|
||||
push @values, join( ",",
|
||||
$hwtype,$server,$id,$model,$serial,$server,$prof,$bpa,$ips );
|
||||
|
||||
#########################################
|
||||
# Enumerate frames (IVM has no frame)
|
||||
#########################################
|
||||
if ( $hwtype ne "ivm" ) {
|
||||
my $filter = "type_model,serial_num,name,frame_num,ipaddr_a,ipaddr_b";
|
||||
my $frames = xCAT::PPCcli::lssyscfg( $exp, "bpas", $filter );
|
||||
my $Rc = shift(@$frames);
|
||||
|
||||
#####################################
|
||||
# Expect error
|
||||
#####################################
|
||||
if ( $Rc == EXPECT_ERROR ) {
|
||||
return( @$frames[0] );
|
||||
}
|
||||
#####################################
|
||||
# CLI error
|
||||
#####################################
|
||||
if ( $Rc == RC_ERROR ) {
|
||||
return( @$frames[0] );
|
||||
}
|
||||
#####################################
|
||||
# If frames found, enumerate cages
|
||||
#####################################
|
||||
if ( $Rc != NR_ERROR ) {
|
||||
my $filter = "cage_num,type_model_serial_num";
|
||||
|
||||
foreach my $values ( @$frames ) {
|
||||
my ($model,$serial) = split /,/, $values;
|
||||
my $mtms = "$model*$serial";
|
||||
|
||||
my $cages = xCAT::PPCcli::lssyscfg($exp,"cage",$mtms,$filter);
|
||||
$Rc = shift(@$cages);
|
||||
|
||||
#############################
|
||||
# Return error
|
||||
#############################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
return( @$cages[0] );
|
||||
}
|
||||
#############################
|
||||
# Success
|
||||
#############################
|
||||
foreach ( @$cages ) {
|
||||
my ($cageid,$mtms) = split /,/;
|
||||
$cage{$mtms} = "$cageid,$values";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#########################################
|
||||
# Enumerate CECs
|
||||
#########################################
|
||||
my $filter = "name,type_model,serial_num,ipaddr";
|
||||
my $cecs = xCAT::PPCcli::lssyscfg( $exp, "fsps", $filter );
|
||||
$Rc = shift(@$cecs);
|
||||
|
||||
#########################################
|
||||
# Return error
|
||||
#########################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
return( @$cecs[0] );
|
||||
}
|
||||
foreach ( @$cecs ) {
|
||||
#####################################
|
||||
# Get CEC information
|
||||
#####################################
|
||||
my ($fsp,$model,$serial,$ips) = split /,/;
|
||||
my $mtms = "$model*$serial";
|
||||
my $cageid = undef;
|
||||
|
||||
#####################################
|
||||
# Get cage CEC is in
|
||||
#####################################
|
||||
my $frame = $cage{$mtms};
|
||||
|
||||
#####################################
|
||||
# Save frame information
|
||||
#####################################
|
||||
if ( defined($frame)) {
|
||||
my ($cage,$model,$serial,$fname,$id,$ipa,$ipb) = split /,/, $frame;
|
||||
my $prof = undef;
|
||||
my $bpa = undef;
|
||||
my $ips = "$ipa $ipb";
|
||||
$cageid = $cage;
|
||||
$frame = $fname;
|
||||
|
||||
push @values, join( ",",
|
||||
"bpa",$fname,$id,$model,$serial,$server,$prof,$bpa,$ips );
|
||||
}
|
||||
#####################################
|
||||
# Save CEC information
|
||||
#####################################
|
||||
my $prof = undef;
|
||||
|
||||
push @values, join( ",",
|
||||
"fsp",$fsp,$cageid,$model,$serial,$server,$prof,$frame,$ips );
|
||||
|
||||
#####################################
|
||||
# Enumerate LPARs
|
||||
#####################################
|
||||
my $filter = "name,lpar_id,default_profile,curr_profile";
|
||||
my $lpars = xCAT::PPCcli::lssyscfg( $exp, "lpar", $mtms, $filter );
|
||||
$Rc = shift(@$lpars);
|
||||
|
||||
####################################
|
||||
# Expect error
|
||||
####################################
|
||||
if ( $Rc == EXPECT_ERROR ) {
|
||||
return( @$lpars[0] );
|
||||
}
|
||||
####################################
|
||||
# Skip...
|
||||
# CEC could be "Incomplete" state
|
||||
####################################
|
||||
if ( $Rc == RC_ERROR ) {
|
||||
next;
|
||||
}
|
||||
####################################
|
||||
# No results found
|
||||
####################################
|
||||
if ( $Rc == NR_ERROR ) {
|
||||
next;
|
||||
}
|
||||
foreach ( @$lpars ) {
|
||||
my ($name,$lparid,$dprof,$curprof) = split /,/;
|
||||
my $prof = (length($curprof)) ? $curprof : $dprof;
|
||||
my $ips = undef;
|
||||
|
||||
#####################################
|
||||
# Save LPAR information
|
||||
#####################################
|
||||
push @values, join( ",",
|
||||
"lpar",$name,$lparid,$serial,$model,$server,$prof,$fsp,$ips );
|
||||
}
|
||||
}
|
||||
return( \@values );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Format responses
|
||||
##########################################################################
|
||||
sub format_output {
|
||||
|
||||
my $request = shift;
|
||||
my $exp = shift;
|
||||
my $values = shift;
|
||||
my $opt = $request->{opt};
|
||||
my %output = ();
|
||||
my $max_length = 0;
|
||||
my $result;
|
||||
|
||||
###########################################
|
||||
# -w flag for write to xCat database
|
||||
###########################################
|
||||
if ( exists( $opt->{w} )) {
|
||||
my $hwtype = @$exp[2];
|
||||
my $server = @$exp[3];
|
||||
my $uid = @$exp[4];
|
||||
my $pw = @$exp[5];
|
||||
|
||||
xCAT::PPCdb::add_ppc( $hwtype, $values );
|
||||
}
|
||||
###########################################
|
||||
# -x flag for xml format
|
||||
###########################################
|
||||
if ( exists( $opt->{x} )) {
|
||||
$result = format_xml( $values );
|
||||
}
|
||||
###########################################
|
||||
# -z flag for schema format
|
||||
###########################################
|
||||
elsif ( exists( $opt->{z} )) {
|
||||
$result = format_schema( $values );
|
||||
}
|
||||
else {
|
||||
#######################################
|
||||
# Get longest name for formatting
|
||||
#######################################
|
||||
foreach ( @$values ) {
|
||||
/[^\,]+,([^\,]+),/;
|
||||
my $length = length( $1 );
|
||||
$max_length = ($length > $max_length) ? $length : $max_length;
|
||||
}
|
||||
my $format = sprintf "%%-%ds", ($max_length + 2 );
|
||||
$header[1][1] = $format;
|
||||
|
||||
#######################################
|
||||
# Add header
|
||||
#######################################
|
||||
foreach ( @header ) {
|
||||
$result .= sprintf @$_[1], @$_[0];
|
||||
}
|
||||
#######################################
|
||||
# Add node information
|
||||
#######################################
|
||||
foreach ( @$values ) {
|
||||
my @data = split /,/;
|
||||
my $i = 0;
|
||||
|
||||
foreach ( @header ) {
|
||||
my $d = $data[$i++];
|
||||
|
||||
###############################
|
||||
# Use IPs instead of
|
||||
# hardware control address
|
||||
###############################
|
||||
if ( @$_[0] eq "address" ) {
|
||||
if ( $data[0] !~ /^hmc|ivm$/ ) {
|
||||
$d = $data[8];
|
||||
}
|
||||
}
|
||||
$result .= sprintf @$_[1], $d;
|
||||
}
|
||||
}
|
||||
}
|
||||
$output{data} = [$result];
|
||||
return( [\%output] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Schema formatting
|
||||
##########################################################################
|
||||
sub format_schema {
|
||||
|
||||
my $values = shift;
|
||||
my $result;
|
||||
|
||||
foreach ( @$values ) {
|
||||
my @data = split /,/;
|
||||
my $i = 0;
|
||||
|
||||
#################################
|
||||
# Node attributes
|
||||
#################################
|
||||
$result .= "$data[1]:\n\tobjtype=node\n";
|
||||
|
||||
#################################
|
||||
# Add each attribute
|
||||
#################################
|
||||
foreach ( @header ) {
|
||||
my $d = $data[$i++];
|
||||
|
||||
if ( @$_[0] eq "name" ) {
|
||||
next;
|
||||
}
|
||||
#############################
|
||||
# Use IPs instead of
|
||||
# hardware control address
|
||||
#############################
|
||||
if ( @$_[0] eq "address" ) {
|
||||
if ( $data[0] !~ /^hmc|ivm$/ ) {
|
||||
$d = $data[8];
|
||||
}
|
||||
}
|
||||
$result .= "\t@$_[0]=$d\n";
|
||||
}
|
||||
}
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# XML formatting
|
||||
##########################################################################
|
||||
sub format_xml {
|
||||
|
||||
my $values = shift;
|
||||
my $xml;
|
||||
|
||||
#####################################
|
||||
# Create XML formatted attributes
|
||||
#####################################
|
||||
foreach ( @$values ) {
|
||||
my @data = split /,/;
|
||||
my $i = 0;
|
||||
|
||||
#################################
|
||||
# Initialize hash reference
|
||||
#################################
|
||||
my $href = {
|
||||
Node => { }
|
||||
};
|
||||
#################################
|
||||
# Add each attribute
|
||||
#################################
|
||||
foreach ( @header ) {
|
||||
my $d = $data[$i++];
|
||||
|
||||
#############################
|
||||
# Use IPs instead of
|
||||
# hardware control address
|
||||
#############################
|
||||
if ( @$_[0] eq "address" ) {
|
||||
if ( $data[0] !~ /^hmc|ivm$/ ) {
|
||||
$d = $data[8];
|
||||
}
|
||||
}
|
||||
$href->{Node}->{@$_[0]} = $d;
|
||||
}
|
||||
#################################
|
||||
# XML encoding
|
||||
#################################
|
||||
$xml.= XMLout($href,
|
||||
NoAttr => 1,
|
||||
KeyAttr => [],
|
||||
RootName => undef );
|
||||
}
|
||||
return( $xml );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns I/O bus information
|
||||
##########################################################################
|
||||
sub rscan {
|
||||
|
||||
my $request = shift;
|
||||
my $dummy = shift;
|
||||
my $exp = shift;
|
||||
my $args = $request->{arg};
|
||||
my $server = @$exp[3];
|
||||
|
||||
###################################
|
||||
# Enumerate all the hardware
|
||||
###################################
|
||||
my $values = enumerate( $exp );
|
||||
if ( ref($values) ne 'ARRAY' ) {
|
||||
return( [[$server,$values]] );
|
||||
}
|
||||
###################################
|
||||
# Success
|
||||
###################################
|
||||
my $result = format_output( $request, $exp, $values );
|
||||
unshift @$result, "FORMATTED_DATA";
|
||||
return( $result );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
1;
|
329
perl-xCAT-2.0/xCAT/PPCvitals.pm
Normal file
329
perl-xCAT-2.0/xCAT/PPCvitals.pm
Normal file
@ -0,0 +1,329 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package xCAT::PPCvitals;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
|
||||
use xCAT::PPCpower;
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Parse the command line for options and operands
|
||||
##########################################################################
|
||||
sub parse_args {
|
||||
|
||||
my $request = shift;
|
||||
my $args = $request->{arg};
|
||||
my %opt = ();
|
||||
my @rvitals = qw(temp voltage power state all);
|
||||
my @VERSION = qw( 2.0 );
|
||||
|
||||
#############################################
|
||||
# Responds with usage statement
|
||||
#############################################
|
||||
local *usage = sub {
|
||||
return( [ $_[0],
|
||||
"rvitals -h|--help",
|
||||
"rvitals -v|--version",
|
||||
"rvitals [-V|--verbose] noderange " . join( '|', @rvitals ),
|
||||
" -h writes usage information to standard output",
|
||||
" -v displays command version",
|
||||
" -V verbose output" ]);
|
||||
};
|
||||
#############################################
|
||||
# Process command-line arguments
|
||||
#############################################
|
||||
if ( !defined( $args )) {
|
||||
return(usage( "No command specified" ));
|
||||
}
|
||||
#############################################
|
||||
# Checks case in GetOptions, allows opts
|
||||
# to be grouped (e.g. -vx), and terminates
|
||||
# at the first unrecognized option.
|
||||
#############################################
|
||||
@ARGV = @$args;
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
Getopt::Long::Configure( "bundling" );
|
||||
|
||||
if ( !GetOptions( \%opt, qw(h|help V|Verbose v|version) )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -h for Help
|
||||
####################################
|
||||
if ( exists( $opt{h} )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -v for version
|
||||
####################################
|
||||
if ( exists( $opt{v} )) {
|
||||
return( \@VERSION );
|
||||
}
|
||||
####################################
|
||||
# Check for "-" with no option
|
||||
####################################
|
||||
if ( grep(/^-$/, @ARGV )) {
|
||||
return(usage( "Missing option: -" ));
|
||||
}
|
||||
####################################
|
||||
# Unsupported command
|
||||
####################################
|
||||
my ($cmd) = grep(/^$ARGV[0]$/, @rvitals );
|
||||
if ( !defined( $cmd )) {
|
||||
return(usage( "Invalid command: $ARGV[0]" ));
|
||||
}
|
||||
####################################
|
||||
# Check for an extra argument
|
||||
####################################
|
||||
shift @ARGV;
|
||||
if ( defined( $ARGV[0] )) {
|
||||
return(usage( "Invalid Argument: $ARGV[0]" ));
|
||||
}
|
||||
####################################
|
||||
# Set method to invoke
|
||||
####################################
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns Frame voltages/currents
|
||||
##########################################################################
|
||||
sub enumerate_volt {
|
||||
|
||||
my $exp = shift;
|
||||
my $d = shift;
|
||||
|
||||
my $mtms = @$d[2];
|
||||
my $volt = xCAT::PPCcli::lshwinfo( $exp, "frame", $mtms );
|
||||
my $Rc = shift(@$volt);
|
||||
|
||||
####################################
|
||||
# Return error
|
||||
####################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
return( [RC_ERROR, @$volt[0]] );
|
||||
}
|
||||
####################################
|
||||
# Success - return voltages
|
||||
####################################
|
||||
return( [SUCCESS, @$volt[0]] );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns cage temperatures
|
||||
##########################################################################
|
||||
sub enumerate_temp {
|
||||
|
||||
my $exp = shift;
|
||||
my $frame = shift;
|
||||
my %outhash = ();
|
||||
|
||||
####################################
|
||||
# Get cage information for frame
|
||||
####################################
|
||||
my $filter = "type_model_serial_num,temperature";
|
||||
my $cages = xCAT::PPCcli::lshwinfo( $exp, "sys", $frame, $filter );
|
||||
my $Rc = shift(@$cages);
|
||||
|
||||
####################################
|
||||
# Expect error
|
||||
####################################
|
||||
if ( $Rc == EXPECT_ERROR ) {
|
||||
return( [$Rc,@$cages[0]] );
|
||||
}
|
||||
####################################
|
||||
# Save frame by CEC MTMS in cage
|
||||
####################################
|
||||
foreach ( @$cages ) {
|
||||
my ($mtms,$temp) = split /,/;
|
||||
$outhash{$mtms} = $temp;
|
||||
}
|
||||
return( [SUCCESS,\%outhash] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns voltages/currents
|
||||
##########################################################################
|
||||
sub voltage {
|
||||
|
||||
my $request = shift;
|
||||
my $hash = shift;
|
||||
my $exp = shift;
|
||||
my $hwtype = @$exp[2];
|
||||
my @result = ();
|
||||
my $text = "Frame Voltages: ";
|
||||
my @prefix = (
|
||||
"Frame Voltage (Vab): %sV",
|
||||
"Frame Voltage (Vbc): %sV",
|
||||
"Frame Voltage (Vca): %sV",
|
||||
"Frame Current (Ia): %sA",
|
||||
"Frame Current (Ib): %sA",
|
||||
"Frame Current (Ic): %sA",
|
||||
);
|
||||
|
||||
while (my ($mtms,$h) = each(%$hash) ) {
|
||||
while (my ($name,$d) = each(%$h) ) {
|
||||
#################################
|
||||
# No frame command on IVM
|
||||
#################################
|
||||
if ( $hwtype eq "ivm" ) {
|
||||
push @result, [$name,"$text Not available"];
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
# Voltages available in frame
|
||||
#################################
|
||||
if ( @$d[4] ne "bpa" ) {
|
||||
push @result, [$name,"$text Only available for BPA"];
|
||||
next;
|
||||
}
|
||||
my $volt = enumerate_volt( $exp, $d );
|
||||
my $Rc = shift(@$volt);
|
||||
|
||||
#################################
|
||||
# Output error
|
||||
#################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
push @result, [$name,"$text @$volt[0]"];
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
# Output value
|
||||
#################################
|
||||
my @values = split /,/, @$volt[0];
|
||||
my $i = 0;
|
||||
|
||||
foreach ( @prefix ) {
|
||||
my $value = sprintf($_, $values[$i++]);
|
||||
push @result, [$name,$value];
|
||||
}
|
||||
}
|
||||
}
|
||||
return( \@result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns temperatures for CEC
|
||||
##########################################################################
|
||||
sub temp {
|
||||
|
||||
my $request = shift;
|
||||
my $hash = shift;
|
||||
my $exp = shift;
|
||||
my $hwtype = @$exp[2];
|
||||
my @result = ();
|
||||
my %frame = ();
|
||||
my $prefix = "System Temperature:";
|
||||
|
||||
#########################################
|
||||
# Group by frame
|
||||
#########################################
|
||||
while (my ($mtms,$h) = each(%$hash) ) {
|
||||
while (my ($name,$d) = each(%$h) ) {
|
||||
my $mtms = @$d[5];
|
||||
|
||||
#################################
|
||||
# No frame commands for IVM
|
||||
#################################
|
||||
if ( $hwtype eq "ivm" ) {
|
||||
push @result, [$name,"$prefix Not available (No BPA)"];
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
# Temperatures not available
|
||||
#################################
|
||||
if ( @$d[4] !~ /^fsp|lpar$/ ) {
|
||||
my $text = "$prefix Only available for CEC/LPAR";
|
||||
push @result, [$name,$text];
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
# Error - No frame
|
||||
#################################
|
||||
if ( $mtms eq "0" ) {
|
||||
push @result, [$name,"$prefix Not available (No BPA)"];
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
# Save node
|
||||
#################################
|
||||
$frame{$mtms}{$name} = $d;
|
||||
}
|
||||
}
|
||||
|
||||
while (my ($mtms,$h) = each(%frame) ) {
|
||||
#################################
|
||||
# Get temperatures this frame
|
||||
#################################
|
||||
my $temp = enumerate_temp( $exp, $mtms );
|
||||
my $Rc = shift(@$temp);
|
||||
my $data = @$temp[0];
|
||||
|
||||
while (my ($name,$d) = each(%$h) ) {
|
||||
my $mtms = @$d[2];
|
||||
|
||||
#############################
|
||||
# Output error
|
||||
#############################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
push @result, [$name,"$prefix $data"];
|
||||
next;
|
||||
}
|
||||
#############################
|
||||
# CEC not in frame
|
||||
#############################
|
||||
if ( !exists( $data->{$mtms} )) {
|
||||
push @result, [$name,"$prefix CEC '$mtms' not found"];
|
||||
next;
|
||||
}
|
||||
#############################
|
||||
# Output value
|
||||
#############################
|
||||
my $cel = $data->{$mtms};
|
||||
my $fah = ($cel * 1.8) + 32;
|
||||
my $value = "$prefix $cel C ($fah F)";
|
||||
push @result, [$name,$value];
|
||||
}
|
||||
}
|
||||
return( \@result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns system power status (on or off)
|
||||
##########################################################################
|
||||
sub power {
|
||||
return( xCAT::PPCpower::state(@_,"Current Power Status: ",1));
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Returns system state
|
||||
##########################################################################
|
||||
sub state {
|
||||
return( xCAT::PPCpower::state(@_,"System State: "));
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Returns all vitals
|
||||
##########################################################################
|
||||
sub all {
|
||||
|
||||
my @values = (
|
||||
@{temp(@_)},
|
||||
@{voltage(@_)},
|
||||
@{state(@_)},
|
||||
@{power(@_)}
|
||||
);
|
||||
return( \@values );
|
||||
}
|
||||
|
||||
|
||||
1;
|
824
perl-xCAT-2.0/xCAT/PPCvm.pm
Normal file
824
perl-xCAT-2.0/xCAT/PPCvm.pm
Normal file
@ -0,0 +1,824 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
package xCAT::PPCvm;
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
|
||||
use xCAT::PPCdb;
|
||||
|
||||
|
||||
##############################################
|
||||
# Globals
|
||||
##############################################
|
||||
my %method = (
|
||||
mkvm => \&mkvm_parse_args,
|
||||
lsvm => \&lsvm_parse_args,
|
||||
rmvm => \&rmvm_parse_args,
|
||||
chvm => \&chvm_parse_args
|
||||
);
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Parse the command line for options and operands
|
||||
##########################################################################
|
||||
sub parse_args {
|
||||
|
||||
my $request = shift;
|
||||
my $cmd = $request->{command};
|
||||
|
||||
###############################
|
||||
# Invoke correct parse_args
|
||||
###############################
|
||||
my $result = $method{$cmd}( $request );
|
||||
return( $result );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Parse the chvm command line for options and operands
|
||||
##########################################################################
|
||||
sub chvm_parse_args {
|
||||
|
||||
my $request = shift;
|
||||
my %opt = ();
|
||||
my $cmd = $request->{command};
|
||||
my $args = $request->{arg};
|
||||
my @VERSION = qw( 2.0 );
|
||||
|
||||
#############################################
|
||||
# Responds with usage statement
|
||||
#############################################
|
||||
local *usage = sub {
|
||||
return( [ $_[0],
|
||||
"chvm -h|--help",
|
||||
"chvm -v|--version",
|
||||
"chvm [-V|--verbose] noderange",
|
||||
" -h writes usage information to standard output",
|
||||
" -v displays command version",
|
||||
" -V verbose output" ]);
|
||||
};
|
||||
####################################
|
||||
# Configuration file required
|
||||
####################################
|
||||
if ( !exists( $request->{stdin} ) ) {
|
||||
return(usage( "Configuration file not specified" ));
|
||||
}
|
||||
#############################################
|
||||
# Process command-line arguments
|
||||
#############################################
|
||||
if ( !defined( $args )) {
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
#############################################
|
||||
# Checks case in GetOptions, allows opts
|
||||
# to be grouped (e.g. -vx), and terminates
|
||||
# at the first unrecognized option.
|
||||
#############################################
|
||||
@ARGV = @$args;
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
Getopt::Long::Configure( "bundling" );
|
||||
|
||||
if ( !GetOptions( \%opt, qw(h|help V|Verbose v|version) )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -h for Help
|
||||
####################################
|
||||
if ( exists( $opt{h} )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -v for version
|
||||
####################################
|
||||
if ( exists( $opt{v} )) {
|
||||
return( \@VERSION );
|
||||
}
|
||||
####################################
|
||||
# Check for "-" with no option
|
||||
####################################
|
||||
if ( grep(/^-$/, @ARGV )) {
|
||||
return(usage( "Missing option: -" ));
|
||||
}
|
||||
####################################
|
||||
# Check for an extra argument
|
||||
####################################
|
||||
if ( defined( $ARGV[0] )) {
|
||||
return(usage( "Invalid Argument: $ARGV[0]" ));
|
||||
}
|
||||
####################################
|
||||
# No operands - add command name
|
||||
####################################
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Parse the mkvm command line for options and operands
|
||||
##########################################################################
|
||||
sub mkvm_parse_args {
|
||||
|
||||
my $request = shift;
|
||||
my %opt = ();
|
||||
my $cmd = $request->{command};
|
||||
my $args = $request->{arg};
|
||||
my @VERSION = qw( 2.0 );
|
||||
|
||||
#############################################
|
||||
# Responds with usage statement
|
||||
#############################################
|
||||
local *usage = sub {
|
||||
return( [ $_[0],
|
||||
"mkvm -h|--help",
|
||||
"mkvm -v|--version",
|
||||
"mkvm [-V|--verbose] singlenode -i id -n name",
|
||||
"mkvm [-V|--verbose] singlecec -c cec",
|
||||
" -h writes usage information to standard output",
|
||||
" -c target cec",
|
||||
" -i new partition numeric id",
|
||||
" -n new partition name",
|
||||
" -v displays command version",
|
||||
" -V verbose output" ]);
|
||||
};
|
||||
#############################################
|
||||
# Process command-line arguments
|
||||
#############################################
|
||||
if ( !defined( $args )) {
|
||||
return(usage( "No command specified" ));
|
||||
}
|
||||
#############################################
|
||||
# Only 1 node allowed
|
||||
#############################################
|
||||
if ( scalar( @{$request->{node}} ) > 1) {
|
||||
return(usage( "multiple nodes specified" ));
|
||||
}
|
||||
#############################################
|
||||
# Checks case in GetOptions, allows opts
|
||||
# to be grouped (e.g. -vx), and terminates
|
||||
# at the first unrecognized option.
|
||||
#############################################
|
||||
@ARGV = @$args;
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
Getopt::Long::Configure( "bundling" );
|
||||
|
||||
if ( !GetOptions( \%opt, qw(h|help V|Verbose v|version i=s n=s c=s) )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -h for Help
|
||||
####################################
|
||||
if ( exists( $opt{h} )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -v for version
|
||||
####################################
|
||||
if ( exists( $opt{v} )) {
|
||||
return( \@VERSION );
|
||||
}
|
||||
####################################
|
||||
# Check for "-" with no option
|
||||
####################################
|
||||
if ( grep(/^-$/, @ARGV )) {
|
||||
return(usage( "Missing option: -" ));
|
||||
}
|
||||
####################################
|
||||
# Check for non-zero integer
|
||||
####################################
|
||||
if ( exists( $opt{i} )) {
|
||||
if ( $opt{i} =~ /^[1-9]{1}$|^[1-9]{1}[0-9]+$/ ) {
|
||||
return(usage( "Invalid entry: $opt{i}" ));
|
||||
}
|
||||
}
|
||||
####################################
|
||||
# -i and -n not valid with -c
|
||||
####################################
|
||||
if ( exists( $opt{c} ) ) {
|
||||
if ( exists($opt{i}) or exists($opt{n})) {
|
||||
return( usage() );
|
||||
}
|
||||
}
|
||||
####################################
|
||||
# If -i and -n, both required
|
||||
####################################
|
||||
elsif ( !exists($opt{n}) or !exists($opt{i})) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Check for an extra argument
|
||||
####################################
|
||||
if ( defined( $ARGV[0] )) {
|
||||
return(usage( "Invalid Argument: $ARGV[0]" ));
|
||||
}
|
||||
####################################
|
||||
# No operands - add command name
|
||||
####################################
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Parse the rmvm command line for options and operands
|
||||
##########################################################################
|
||||
sub rmvm_parse_args {
|
||||
|
||||
my $request = shift;
|
||||
my %opt = ();
|
||||
my $cmd = $request->{command};
|
||||
my $args = $request->{arg};
|
||||
my @VERSION = qw( 2.0 );
|
||||
|
||||
#############################################
|
||||
# Responds with usage statement
|
||||
#############################################
|
||||
local *usage = sub {
|
||||
return( [ $_[0],
|
||||
"rmvm -h|--help",
|
||||
"rmvm -v|--version",
|
||||
"rmvm [-V|--verbose] noderange",
|
||||
" -h writes usage information to standard output",
|
||||
" -v displays command version",
|
||||
" -V verbose output" ]);
|
||||
};
|
||||
#############################################
|
||||
# Process command-line arguments
|
||||
#############################################
|
||||
if ( !defined( $args )) {
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
#############################################
|
||||
# Checks case in GetOptions, allows opts
|
||||
# to be grouped (e.g. -vx), and terminates
|
||||
# at the first unrecognized option.
|
||||
#############################################
|
||||
@ARGV = @$args;
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
Getopt::Long::Configure( "bundling" );
|
||||
|
||||
if ( !GetOptions( \%opt, qw(h|help V|Verbose v|version) )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -h for Help
|
||||
####################################
|
||||
if ( exists( $opt{h} )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -v for version
|
||||
####################################
|
||||
if ( exists( $opt{v} )) {
|
||||
return( \@VERSION );
|
||||
}
|
||||
####################################
|
||||
# Check for "-" with no option
|
||||
####################################
|
||||
if ( grep(/^-$/, @ARGV )) {
|
||||
return(usage( "Missing option: -" ));
|
||||
}
|
||||
####################################
|
||||
# Check for an extra argument
|
||||
####################################
|
||||
if ( defined( $ARGV[0] )) {
|
||||
return(usage( "Invalid Argument: $ARGV[0]" ));
|
||||
}
|
||||
####################################
|
||||
# No operands - add command name
|
||||
####################################
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Parse the lsvm command line for options and operands
|
||||
##########################################################################
|
||||
sub lsvm_parse_args {
|
||||
|
||||
my $request = shift;
|
||||
my %opt = ();
|
||||
my $cmd = $request->{command};
|
||||
my $args = $request->{arg};
|
||||
my @VERSION = qw( 2.0 );
|
||||
|
||||
#############################################
|
||||
# Responds with usage statement
|
||||
#############################################
|
||||
local *usage = sub {
|
||||
return( [ $_[0],
|
||||
"lsvm -h|--help",
|
||||
"lsvm -v|--version",
|
||||
"lsvm [-V|--verbose] noderange",
|
||||
" -h writes usage information to standard output",
|
||||
" -v displays command version",
|
||||
" -V verbose output" ]);
|
||||
};
|
||||
#############################################
|
||||
# Process command-line arguments
|
||||
#############################################
|
||||
if ( !defined( $args )) {
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
#############################################
|
||||
# Checks case in GetOptions, allows opts
|
||||
# to be grouped (e.g. -vx), and terminates
|
||||
# at the first unrecognized option.
|
||||
#############################################
|
||||
@ARGV = @$args;
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
Getopt::Long::Configure( "bundling" );
|
||||
|
||||
if ( !GetOptions( \%opt, qw(h|help V|Verbose v|version) )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -h for Help
|
||||
####################################
|
||||
if ( exists( $opt{h} )) {
|
||||
return( usage() );
|
||||
}
|
||||
####################################
|
||||
# Option -v for version
|
||||
####################################
|
||||
if ( exists( $opt{v} )) {
|
||||
return( \@VERSION );
|
||||
}
|
||||
####################################
|
||||
# Check for "-" with no option
|
||||
####################################
|
||||
if ( grep(/^-$/, @ARGV )) {
|
||||
return(usage( "Missing option: -" ));
|
||||
}
|
||||
####################################
|
||||
# Check for an extra argument
|
||||
####################################
|
||||
if ( defined( $ARGV[0] )) {
|
||||
return(usage( "Invalid Argument: $ARGV[0]" ));
|
||||
}
|
||||
####################################
|
||||
# No operands - add command name
|
||||
####################################
|
||||
$request->{method} = $cmd;
|
||||
return( \%opt );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Clones all the partitions from one CEC to another
|
||||
##########################################################################
|
||||
sub clone {
|
||||
|
||||
my $cfgdata = shift;
|
||||
my $d = shift;
|
||||
my $exp = shift;
|
||||
my $opt = shift;
|
||||
my $hwtype = @$exp[2];
|
||||
my $target = $opt->{c};
|
||||
my @values = ();
|
||||
my $cecname;
|
||||
|
||||
#####################################
|
||||
# Always one source CEC specified
|
||||
#####################################
|
||||
my $lparid = @$d[0];
|
||||
my $mtms = @$d[2];
|
||||
my $type = @$d[4];
|
||||
|
||||
if ( $type ne "fsp" ) {
|
||||
return( ["Node must be an FSP"] );
|
||||
}
|
||||
#####################################
|
||||
# Enumerate CECs
|
||||
#####################################
|
||||
my $cecs = xCAT::PPCcli::lssyscfg( $exp, "fsps", "name" );
|
||||
my $Rc = shift(@$cecs);
|
||||
|
||||
#####################################
|
||||
# Return error
|
||||
#####################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
return( [@$cecs[0]] );
|
||||
}
|
||||
#####################################
|
||||
# Find target CEC
|
||||
#####################################
|
||||
foreach ( @$cecs ) {
|
||||
if ( $target eq $_ ) {
|
||||
$cecname = $_;
|
||||
last;
|
||||
}
|
||||
}
|
||||
#####################################
|
||||
# Target CEC not found
|
||||
#####################################
|
||||
if ( !defined( $cecname )) {
|
||||
return( ["CEC '$target' not found"] );
|
||||
}
|
||||
#####################################
|
||||
# Modify read-back profile:
|
||||
# - Rename "name" to "profile_name"
|
||||
# - Rename "lpar_name" to "name"
|
||||
# - Delete "virtual_serial_adapters"
|
||||
# completely, these adapters are
|
||||
# created automatically.
|
||||
# - Preceed all double-quotes with
|
||||
# backslashes.
|
||||
#
|
||||
#####################################
|
||||
foreach ( @$cfgdata ) {
|
||||
s/^name=([^,]+)/profile_name=$1/;
|
||||
s/lpar_name=/name=/;
|
||||
s/\"virtual_serial_adapters=[^\"]+\",//;
|
||||
s/\"/\\"/g;
|
||||
my $name = $1;
|
||||
|
||||
/lpar_id=([^,]+)/;
|
||||
$lparid = $1;
|
||||
|
||||
#################################
|
||||
# Create new LPAR
|
||||
#################################
|
||||
my @temp = @$d;
|
||||
$temp[0] = $lparid;
|
||||
|
||||
my $result = xCAT::PPCcli::mksyscfg( $exp, \@temp, $_ );
|
||||
$Rc = shift(@$result);
|
||||
|
||||
#################################
|
||||
# Success - add LPAR to database
|
||||
#################################
|
||||
if ( $Rc == SUCCESS ) {
|
||||
xCATdB( "mkvm", $d, $lparid, $name, $hwtype );
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
# Error - Save error
|
||||
#################################
|
||||
push @values, @$result[0];
|
||||
}
|
||||
if ( !scalar(@values) ) {
|
||||
@values = qw(Success);
|
||||
}
|
||||
return( \@values );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Removes logical partitions
|
||||
##########################################################################
|
||||
sub remove {
|
||||
|
||||
my $exp = shift;
|
||||
my $d = shift;
|
||||
my $lpar = shift;
|
||||
my $lparid = @$d[0];
|
||||
my $mtms = @$d[2];
|
||||
my $type = @$d[4];
|
||||
my @lpars = ();
|
||||
my @values = ();
|
||||
|
||||
####################################
|
||||
# This is a single LPAR
|
||||
####################################
|
||||
if ( $type eq "lpar" ) {
|
||||
$lpars[0] = "$lpar,$lparid";
|
||||
}
|
||||
####################################
|
||||
# This is a CEC - remove all LPARs
|
||||
####################################
|
||||
else {
|
||||
my $filter = "name,lpar_id";
|
||||
my $result = xCAT::PPCcli::lssyscfg( $exp, "lpar", $mtms, $filter );
|
||||
my $Rc = shift(@$result);
|
||||
|
||||
################################
|
||||
# Expect error
|
||||
################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
return( [@$result[0]] );
|
||||
}
|
||||
################################
|
||||
# Success - save LPARs
|
||||
################################
|
||||
foreach ( @$result ) {
|
||||
push @lpars, $_;
|
||||
}
|
||||
}
|
||||
####################################
|
||||
# Remove the LPARs
|
||||
####################################
|
||||
foreach ( @lpars ) {
|
||||
my ($name,$id) = split /,/;
|
||||
my $mtms = @$d[2];
|
||||
|
||||
################################
|
||||
# id profile mtms hcp type frame
|
||||
################################
|
||||
my @d = ( $id,0,$mtms,0,"lpar",0 );
|
||||
|
||||
################################
|
||||
# Send remove command
|
||||
################################
|
||||
my $result = xCAT::PPCcli::rmsyscfg( $exp, \@d );
|
||||
my $Rc = shift(@$result);
|
||||
|
||||
################################
|
||||
# Remove LPAR from database
|
||||
################################
|
||||
if ( $Rc == SUCCESS ) {
|
||||
xCATdB( "rmvm", $name );
|
||||
}
|
||||
push @values, @$result[0];
|
||||
}
|
||||
return( \@values );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Changes the configuration of an existing partition
|
||||
##########################################################################
|
||||
sub chcfg {
|
||||
|
||||
my $request = shift;
|
||||
my $hash = shift;
|
||||
my $exp = shift;
|
||||
my $name = @{$request->{node}}[0];
|
||||
my $cfgdata = $request->{stdin};
|
||||
my @values;
|
||||
|
||||
#######################################
|
||||
# Remove "node: " in case the
|
||||
# configuration file was created as
|
||||
# the result of an "lsvm" command.
|
||||
# "lpar9: name=lpar9, lpar_name=..."
|
||||
#######################################
|
||||
$cfgdata =~ s/^[\w]+: //;
|
||||
|
||||
if ( $cfgdata !~ /^name=/ ) {
|
||||
my $text = "Invalid file format: must begin with 'name='";
|
||||
return( [[$name,$text]] );
|
||||
}
|
||||
#######################################
|
||||
# Preceed double-quotes with '\'
|
||||
#######################################
|
||||
$cfgdata =~ s/\"/\\"/g;
|
||||
$cfgdata =~ s/\n//g;
|
||||
|
||||
while (my ($cec,$h) = each(%$hash) ) {
|
||||
while (my ($lpar,$d) = each(%$h) ) {
|
||||
|
||||
###############################
|
||||
# Change configuration
|
||||
###############################
|
||||
my $result = xCAT::PPCcli::chsyscfg( $exp, $d, $cfgdata );
|
||||
my $Rc = shift(@$result);
|
||||
|
||||
push @values, [$lpar,@$result[0]];
|
||||
return( [[$lpar,@$result[0]]] );
|
||||
}
|
||||
}
|
||||
return( \@values );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Creates/Removes/Lists logical partitions
|
||||
##########################################################################
|
||||
sub vm {
|
||||
|
||||
my $request = shift;
|
||||
my $hash = shift;
|
||||
my $exp = shift;
|
||||
my $hwtype = @$exp[2];
|
||||
my $opt = $request->{opt};
|
||||
my $cmd = $request->{command};
|
||||
my @values = ();
|
||||
my $result;
|
||||
|
||||
while (my ($mtms,$h) = each(%$hash) ) {
|
||||
while (my ($lpar,$d) = each(%$h) ) {
|
||||
my $lparid = @$d[0];
|
||||
my $mtms = @$d[2];
|
||||
my $type = @$d[4];
|
||||
|
||||
#####################################
|
||||
# Must be CEC or LPAR
|
||||
#####################################
|
||||
if ( $type !~ /^lpar|fsp$/ ) {
|
||||
push @values, [$lpar,"Node must be LPAR or CEC"];
|
||||
next;
|
||||
}
|
||||
#####################################
|
||||
# Remove LPAR
|
||||
#####################################
|
||||
if ( $cmd eq "rmvm" ) {
|
||||
$result = remove( $exp, $d, $lpar );
|
||||
|
||||
#################################
|
||||
# Return result
|
||||
#################################
|
||||
foreach ( @$result ) {
|
||||
push @values, [$lpar, $_];
|
||||
}
|
||||
next;
|
||||
}
|
||||
#####################################
|
||||
# Get source LPAR profile
|
||||
#####################################
|
||||
my $prof = xCAT::PPCcli::lssyscfg(
|
||||
$exp,
|
||||
($lparid) ? "prof" : "cprof",
|
||||
$mtms,
|
||||
$lparid );
|
||||
my $Rc = shift(@$prof);
|
||||
|
||||
#####################################
|
||||
# Return error
|
||||
#####################################
|
||||
if ( $Rc != SUCCESS ) {
|
||||
push @values, [$lpar, @$prof[0]];
|
||||
next;
|
||||
}
|
||||
#####################################
|
||||
# List LPAR profile
|
||||
#####################################
|
||||
if ( $cmd eq "lsvm" ) {
|
||||
my $text = join "\n\n", @$prof[0];
|
||||
push @values, [$lpar, $text];
|
||||
next;
|
||||
}
|
||||
#####################################
|
||||
# Clone all the LPARs on CEC
|
||||
#####################################
|
||||
if ( exists( $opt->{c} )) {
|
||||
if ( $hwtype eq "ivm" ) {
|
||||
push @values, [$lpar, "Not supported for IVM"];
|
||||
}
|
||||
else {
|
||||
my $result = clone( $prof, $d, $exp, $opt );
|
||||
foreach ( @$result ) {
|
||||
push @values, [$lpar, $_];
|
||||
}
|
||||
}
|
||||
next;
|
||||
}
|
||||
#################################
|
||||
# Get command-line options
|
||||
#################################
|
||||
my $id = $opt->{i};
|
||||
my $name = $opt->{n};
|
||||
my $cfgdata = @$prof[0];
|
||||
|
||||
if ( $hwtype eq "hmc" ) {
|
||||
#####################################
|
||||
# Modify read-back profile. See
|
||||
# HMC mksyscfg man page for valid
|
||||
# attributes:
|
||||
#
|
||||
# - Rename "name" to "profile_name"
|
||||
# - Rename "lpar_name" to "name"
|
||||
# - Delete "virtual_serial_adapters"
|
||||
# completely, these adapters are
|
||||
# created automatically.
|
||||
# - Preceed all double-quotes with
|
||||
# backslashes.
|
||||
#
|
||||
#####################################
|
||||
$cfgdata =~ s/^name=[^,]+/profile_name=$name/;
|
||||
$cfgdata =~ s/lpar_name=[^,]+/name=$name/;
|
||||
$cfgdata =~ s/lpar_id=[^,]+/lpar_id=$id/;
|
||||
$cfgdata =~ s/\"virtual_serial_adapters=[^\"]+\",//;
|
||||
$cfgdata =~ s/\"/\\"/g;
|
||||
}
|
||||
elsif ( $hwtype eq "ivm" ) {
|
||||
#####################################
|
||||
# Modify read-back profile. See
|
||||
# IVM mksyscfg man page for valid
|
||||
# attributes:
|
||||
#
|
||||
# - Delete
|
||||
# lpar_name
|
||||
# virtual_serial_adapters
|
||||
# lpar_name
|
||||
# os_type
|
||||
# all_resources
|
||||
# lpar_io_pool_ids
|
||||
# conn_monitoring
|
||||
# power_ctrl_lpar_ids
|
||||
# - Preceed all double-quotes with
|
||||
# backslashes.
|
||||
#
|
||||
#####################################
|
||||
$cfgdata =~ s/^name=[^,]+/name=$name/;
|
||||
$cfgdata =~ s/lpar_id=[^,]+/lpar_id=$id/;
|
||||
$cfgdata =~ s/lpar_name=[^,]+,//;
|
||||
$cfgdata =~ s/os_type=/lpar_env=/;
|
||||
$cfgdata =~ s/all_resources=[^,]+,//;
|
||||
$cfgdata =~ s/\"virtual_serial_adapters=[^\"]+\",//;
|
||||
$cfgdata =~ s/lpar_io_pool_ids=[^,]+,//;
|
||||
$cfgdata =~ s/virtual_scsi_adapters=[^,]+,//;
|
||||
$cfgdata =~ s/conn_monitoring=[^,]+,//;
|
||||
$cfgdata =~ s/,power_ctrl_lpar_ids=.*$//;
|
||||
$cfgdata =~ s/\"/\\"/g;
|
||||
}
|
||||
#####################################
|
||||
# Create target LPAR
|
||||
#####################################
|
||||
$result = xCAT::PPCcli::mksyscfg( $exp, $d, $cfgdata );
|
||||
$Rc = shift(@$result);
|
||||
|
||||
#####################################
|
||||
# Add new LPAR to database
|
||||
#####################################
|
||||
if ( $Rc == SUCCESS ) {
|
||||
xCATdB( $cmd, $name, $id, $d, $hwtype );
|
||||
}
|
||||
push @values, [$name,@$result[0]];
|
||||
}
|
||||
}
|
||||
return( \@values );
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Adds/removes LPARs from the xCAT database
|
||||
##########################################################################
|
||||
sub xCATdB {
|
||||
|
||||
my $cmd = shift;
|
||||
my $name = shift;
|
||||
my $lparid = shift;
|
||||
my $d = shift;
|
||||
my $hwtype = shift;
|
||||
|
||||
#######################################
|
||||
# Remove entry
|
||||
#######################################
|
||||
if ( $cmd eq "rmvm" ) {
|
||||
xCAT::PPCdb::rm_ppchardware( $name );
|
||||
}
|
||||
#######################################
|
||||
# Add entry
|
||||
#######################################
|
||||
else {
|
||||
my ($model,$serial) = split /\*/,@$d[2];
|
||||
my $prof = $name;
|
||||
my $frame = @$d[4];
|
||||
my $server = @$d[3];
|
||||
|
||||
my $values = join( ",",
|
||||
"lpar",
|
||||
$name,
|
||||
$lparid,
|
||||
$model,
|
||||
$serial,
|
||||
$server,
|
||||
$prof,
|
||||
$frame );
|
||||
|
||||
xCAT::PPCdb::add_ppc( $hwtype, [$values] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Creates logical partitions
|
||||
##########################################################################
|
||||
sub mkvm {
|
||||
return( vm(@_) );
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Change logical partition
|
||||
##########################################################################
|
||||
sub chvm {
|
||||
return( chcfg(@_) );
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Removes logical partitions
|
||||
##########################################################################
|
||||
sub rmvm {
|
||||
return( vm(@_) );
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# Lists logical partition profile
|
||||
##########################################################################
|
||||
sub lsvm {
|
||||
return( vm(@_) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
1;
|
Loading…
x
Reference in New Issue
Block a user