#!/usr/bin/env perl # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html use strict; use Getopt::Long; use xCAT::Table; use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR); ############################################## # Globals ############################################## my $verbose = 0; my $node; ########################################## # 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" ); ########################################################################## # Parse the command line for options and operands ########################################################################## sub parse_args { my %opt = (); my @VERSION = qw( 2.0 ); ############################################# # Responds with usage statement ############################################# local *usage = sub { my $cmd = __FILE__; $cmd =~ s/.*([\w]{3}$)/$1/; if ( defined( $_[0] )) { print STDERR "$_[0]\n"; } my @msg = ( "$cmd -h|--help\n", "$cmd -v|--version\n", "$cmd singlenode [-V|-Verbose]\n" ); print STDERR @msg; }; ############################################# # Process command-line arguments ############################################# if ( !defined( @ARGV )) { usage( "No node specified" ); return(1); } ############################################# # Checks case in GetOptions, allows opts # to be grouped (e.g. -vx), and terminates # at the first unrecognized option. ############################################# $Getopt::Long::ignorecase = 0; Getopt::Long::Configure( "bundling" ); if ( !GetOptions( \%opt, qw(h|help V|Verbose v|version) )) { usage(); return(1); } ####################################### # Option -h for Help ####################################### if ( exists( $opt{h} )) { usage(); return(1); } ####################################### # Option -v for version ####################################### if ( exists( $opt{v} )) { print STDERR \@VERSION; return(1); } ####################################### # Option -V for verbose output ####################################### if ( exists( $opt{V} )) { $verbose = 1; } ####################################### # Check for "-" with no option ####################################### if ( grep(/^-$/, @ARGV )) { usage( "Missing option: -" ); return(1); } ####################################### # Get node ####################################### if ( !defined( $ARGV[0] )) { usage( "No node specified" ); return(1); } $node = shift @ARGV; ####################################### # Check for multiple nodes specified ####################################### my @nodes = split /-|,| /, $node; if ( scalar(@nodes) > 1 ) { usage( "multiple nodes specified" ); return(1); } ####################################### # Check for extra argument ####################################### if ( defined( $ARGV[0] )) { usage( "Invalid Argument: $ARGV[0]" ); return(1); } return(0); } ########################################################################## # Open remote console ########################################################################## sub invoke_cmd { my @attribs = qw(id parent hcp); my %tabs = (); ################################## # Open databases needed ################################## foreach ( qw(ppc vpd nodelist) ) { $tabs{$_} = xCAT::Table->new($_); if ( !exists( $tabs{$_} )) { return( sprintf( $errmsg{DB_UNDEF}, $_ )); } } ################################## # Get node power type ################################## my $hwtype = __FILE__; $hwtype =~ s/.*([\w]{3})$/$1/; ################################# # 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} !~ s/^(osi)$/lpar/ ) { return( "Invalid node type: $ent->{nodetype}" ); } ################################# # Get attributes ################################# my ($att) = $tabs{ppc}->getAttribs({'node'=>$node}, @attribs ); if ( !defined( $att )) { return( sprintf( $errmsg{NODE_UNDEF}, "ppc" )); } ################################# # Verify required attributes ################################# foreach my $at ( @attribs ) { if ( !exists( $att->{$at} )) { return( sprintf( $errmsg{NO_ATTR}, $at, "ppc" )); } } ################################# # Find MTMS in vpd database ################################# my @attrs = qw(mtm serial); my ($vpd) = $tabs{vpd}->getAttribs({node=>$att->{parent}}, @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" )); } } my $mtms = "$vpd->{mtm}*$vpd->{serial}"; my $host = $att->{hcp}; my $lparid = $att->{id}; my $type = $ent->{nodetype}; ################################# # Connect to the remote server ################################# my @exp = xCAT::PPCcli::connect( $hwtype, $host, $verbose ); if ( ref(@exp[0]) ne "Expect" ) { return( @exp[0] ); } ################################# # Open console connection ################################# my $result = xCAT::PPCcli::mkvterm( \@exp, $type, $lparid, $mtms ); my $Rc = shift(@$result); if ( $Rc != SUCCESS ) { return( @$result[0] ); } return(0); } ############################################## # Start main body of code ############################################## if ( parse_args() ) { exit(1); } my $result = invoke_cmd(); if ( $result ne "0" ) { print STDERR "$node: $result\n"; exit(1); } exit(0);