From 0b0c9235191a1a8597abf9d8680d42636bae394a Mon Sep 17 00:00:00 2001 From: John Simpson Date: Fri, 18 Oct 2013 16:13:52 -0400 Subject: [PATCH] Adding a new plugin confgifpc to support discovery and configuring of NeXtScale FPCs --- xCAT-client/xCAT-client.spec | 1 + xCAT-server/lib/xcat/plugins/configfpc.pm | 350 ++++++++++++++++++++++ 2 files changed, 351 insertions(+) create mode 100644 xCAT-server/lib/xcat/plugins/configfpc.pm diff --git a/xCAT-client/xCAT-client.spec b/xCAT-client/xCAT-client.spec index fe86a0131..a76dd8ef2 100644 --- a/xCAT-client/xCAT-client.spec +++ b/xCAT-client/xCAT-client.spec @@ -229,6 +229,7 @@ ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/bin/nodediscoverstatus ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/bin/nodediscoverdef ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/bin/nodeaddunmged ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/bin/geninitrd +ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/bin/configfpc ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/bin/nodepurge ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/bin/nodechprofile ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/bin/noderegenips diff --git a/xCAT-server/lib/xcat/plugins/configfpc.pm b/xCAT-server/lib/xcat/plugins/configfpc.pm new file mode 100644 index 000000000..7ba94c4ff --- /dev/null +++ b/xCAT-server/lib/xcat/plugins/configfpc.pm @@ -0,0 +1,350 @@ +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html +package xCAT_plugin::configfpc; + +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use strict; +use lib "$::XCATROOT/lib/perl"; +use xCAT::Utils; +use xCAT::MsgUtils; +use xCAT::SvrUtils; +use Sys::Hostname; +use xCAT::Table; +use xCAT::TableUtils; +use xCAT::NetworkUtils; +use Data::Dumper; +use xCAT::MacMap; +use Socket; + +########################################################################## +## Command handler method from tables +########################################################################### +sub handled_commands { + return { + configfpc => "configfpc", + }; +} + +sub process_request { + my $request = shift; + my $callback = shift; + my $subreq = shift; + + $::CALLBACK = $callback; + + my $command = $request->{command}->[0]; + my $localhostname = hostname(); + + if ($command eq "configfpc") + { + my $rc; + $rc = configfpc($request, $callback, $subreq); + } + else + { + my %rsp; + push@{ $rsp{data} }, "$localhostname: Unsupported command: $command"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + return 1; + } + +return 0; +} + +# +# Main process subroutine +# +########################################################################### +# This routine will look for NeXtWcale Fan Power Controllers (FPC) that have +# a default IP address of 192.169.0.100 +# +# For each FPC found the code will +# 1 - ping the default IP address to get the default IP and MAC in the arp table +# 2 - use arp to get the MAC address +# 3 - lookup the MAC address +# ------ check for the MAC on the switch adn save the port number +# ------ lookup the node with that switch port number +# 4 - get the IP address for the node name found +# 5 - determine the assocaited netmask and gateway for this node IP +# 6 - use rspconfig (IPMI) to set the netmask, gateway, and IP address +# 7 - check to make sure that the new FPC IP address is responding +# 8 - remove the default FPC IP from the arp table +# 9 - use ping to determine if there is another default FPC IP and if so start this process again +########################################################################### +sub configfpc { + my $request = shift; + my $callback = shift; + my $subreq = shift; + + + # Use default userid and passwd + my $ipmiuser = 'USERID'; + my $ipmipass = 'PASSW0RD'; + my $fpcip = '192.168.0.100'; + my $defnode = "deffpc"; + + # This is the default FPC IP that we are looking for + my $foundfpc = 0; + + # + # check for an FPC - this ping will also add the FPC IP and MAC to the ARP table + # + my $res = `LANG=C ping -c 1 -w 5 $fpcip`; + #my $res = system("LANG=C ping -c 1 -w 5 $fpcip 2>&1"); + if ( $res =~ /100% packet loss/g) { +# xCAT::MsgUtils->message ("I", "There are no default $fpcip FPC IP addresses to process"); + $foundfpc = 0; + exit; # EXIT if we find no more default IP addresses on the network + } + else { +# xCAT::MsgUtils->message ("I", "Found $fpcip FPC IP addresses to process"); + $foundfpc = 1; + } + + # + # make the FPC node definition - this is removed at the end of processing the FPCs + # this default FPC node definition is used by rspconfig to change the netmask, default route, and IP address of the default FPC + # + # Object name: deffpc + # bmc=deffpc + # bmcpassword=PASSW0RD + # bmcusername=USERID + # cons=ipmi + # groups=deffpc + # mgt=ipmi + # mpa=deffpc + # + my $out = xCAT::Utils->runxcmd( + { + command => ["mkdef"], + arg => [ "-t","node","-o",$defnode,"bmc=deffpc","bmcpassword=Passw0rd","bmcusername=USERID","cons=ipmi","groups=deffpc","mgt=ipmi","mpa=deffpc" ] + }, + $subreq, 0,1); + + # + # Main loop - check to see if we found an FPC and continue to set the FPC infomration and look for the next one + # + while ($foundfpc){ + + # Process the default FPC IP to find the node associated with this FPC MAC + my ($node,$fpcmac) = &get_node($callback); + + # Found the Node and MAC associated with this MAC - continue to setup this FPC + if ($node) { + + # get the network settings for this node + my ($netmask,$gateway,$newfpcip) = &get_network_parms($node,$callback); + + # Change the FPC network netmask, gateway, and ip + &set_FPC_network_parms($defnode,$netmask,$gateway,$newfpcip,$callback,$subreq); + + # sleep for 4 seconds to allow rspconfig to change the IP value before validating with ping + sleep 5; + + # + # Validate that new IP is working - Use ping to check if the new IP has been set + # + $res = `LANG=C ping -c 1 -w 5 $newfpcip`; + #$res = system("LANG=C ping -c 1 -w 5 $fpcip 2>&1"); + if ( $res =~ /100% packet loss/g) { + my %rsp; + push@{ $rsp{data} }, "The new ip $newfpcip was not accessible"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + #xCAT::MsgUtils->message("I","The new ip $newfpcip was not accessible"); + } else { + my %rsp; + push@{ $rsp{data} }, "Changed the IP address for the FPC with $fpcmac MAC to $newfpcip IP for node $node"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + #xCAT::MsgUtils->message("I","Changed the IP address for the FPC with $fpcmac MAC to $newfpcip IP for node $node"); + } + # The Node associated with this MAC was not found - print an infomrational message and continue + } else { + my %rsp; + push@{ $rsp{data} }, "No FPC node found that is associated with MAC address $fpcmac\nCheck to see if the switch and switch table conta ins the information needed to locate this FPC MAC"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + # xCAT::MsgUtils->message("I","No FPC node found that is associated with MAC address $fpcmac\nCheck to see if the switch and switch table contains the information needed to locate this FPC MAC"); + } + + # + # Delete this FPC default IP Arp entry to get ready to look for another defautl FPC + # + my $arpout = `arp -d $fpcip`; + + # check for another FPC + $res = `LANG=C ping -c 1 -w 5 $fpcip 2>&1`; + if ( $res =~ /100% packet loss/g) { + my %rsp; + push@{ $rsp{data} }, "There are no more default $fpcip FPC IP addresses to process"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + #xCAT::MsgUtils->message("I","There are no more default $fpcip FPC IP addresses to process"); + $foundfpc = 0; + } + else { + $foundfpc = 1; + } + } + + # + # Cleanup on the way out - Remove the deffpc node definition + # + $out=xCAT::Utils->runxcmd( + { + command => ['rmdef'], + arg => [ "deffpc"] + }, + $subreq, 0,1); + + return 1; +} + +# +# The get_network_parms subroutine +# takes the node name and gets the IP address for this node +# and collects the netmask and gateway and returns netmask, gateway, and IP address +# +sub get_network_parms { + + my $node = shift; + my $callback = shift; + # Get the new ip address for this FPC + my $newfpc = `getent hosts $node`; + my ($newfpcip, $junk) = split(/\s/,$newfpc); + + # collect gateway and netmask + my $ip = $newfpcip; + my $gateway; + my $netmask; + if (inet_aton($ip)) { + $ip = inet_ntoa(inet_aton($ip)); + } else { + my %rsp; + push@{ $rsp{data} }, "Unable to resolve $ip"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + #xCAT::MsgUtils->message("S","Unable to resolve $ip"); + return undef; + } + my $nettab = xCAT::Table->new('networks'); + unless ($nettab) { return undef }; + my @nets = $nettab->getAllAttribs('net','mask','gateway'); + foreach (@nets) { + my $net = $_->{'net'}; + my $mask =$_->{'mask'}; + my $gw = $_->{'gateway'}; + $ip =~ /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/; + my $ipnum = ($1<<24)+($2<<16)+($3<<8)+$4; + $mask =~ /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/; + my $masknum = ($1<<24)+($2<<16)+($3<<8)+$4; + $net =~ /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/ or next; #next if ipv6, TODO: IPv6 support + my $netnum = ($1<<24)+($2<<16)+($3<<8)+$4; + if ($gw eq '') { + $gw=xCAT::NetworkUtils->my_ip_facing($ip); + } + if (($ipnum & $masknum)==$netnum) { + $netmask = $mask; + $gateway = $gw; + } + } + return ($netmask,$gateway,$newfpcip); +} + +# +# The set_FPC_network_parms subroutine +# uses rspconfig to set the netmask, gateway, and new ip address for this FPC +# +sub set_FPC_network_parms { + + my $defnode = shift; + my $netmask = shift; + my $gateway = shift; + my $newfpcip = shift; + my $callback = shift; + my $request = shift; + my $error; + + # Proceed with changing the FPC network parameters. + # Set FPC Netmask + + + my $netmaskout = xCAT::Utils->runxcmd( + { + command => ["rspconfig"], + node => [$defnode], + arg => [ "netmask=$netmask" ] + }, + $request, 0,1); + + if ($::RUNCMD_RC != 0) { + my %rsp; + push@{ $rsp{data} }, "Could not change nemask $netmask on default FPC"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + $error++; + } + + # Set FPC gateway + my $gatewayout = xCAT::Utils->runxcmd( + { + command => ["rspconfig"], + node => [$defnode], + arg => [ "gateway=$gateway" ] + }, + $request, 0,1); + + if ($::RUNCMD_RC != 0) { + my %rsp; + push@{ $rsp{data} }, "Could not change gateway $gateway on default FPC"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + $error++; + } + + + # Set FPC Ip address + my $ipout = xCAT::Utils->runxcmd( + { + command => ["rspconfig"], + node => [$defnode], + arg => [ "ip=$newfpcip" ] + }, + $request, 0,1); + + if ($::RUNCMD_RC != 0) { + my %rsp; + push@{ $rsp{data} }, "Could not change ip address $newfpcip on default FPC"; + xCAT::MsgUtils->message( "S", \%rsp, $callback ); + $error++; + } + return 1; +} + +# +# This subroutine +# 1) gets the MAC from the arp table +# 2) uses Macmap to find the node associated with this MAC +# 3) returns the node and MAC +sub get_node { + my $callback = shift; + + my $fpcip = '192.168.0.100'; + + # get the FPC from the arp table + my $arpout = `arp -a | grep $fpcip`; + + # format of arp command is: feihu-fpc (10.1.147.170) at 6c:ae:8b:08:20:35 [ether] on eth0 + # extract the MAC address + my ($junk1, $junk2, $junk3, $fpcmac, $junk4, $junk5, $junk6) = split(" ", $arpout); + + # Print a message that this MAC has been found + my %rsp; + push@{ $rsp{data} }, "Found FPC with default IP $fpcip and MAC $fpcmac"; + xCAT::MsgUtils->message( "I", \%rsp, $callback ); + + # Usee find_mac to 1) look for which switch port contains this MAC address + # and 2) look in the xcat DB to find the node associated with the switch port this MAC was found in + my $macmap = xCAT::MacMap->new(); + my $node = ''; + $node = $macmap->find_mac($fpcmac,0); + + return ($node,$fpcmac); +} +1;