diff --git a/xCAT-server/lib/xcat/plugins/lsslp.pm b/xCAT-server/lib/xcat/plugins/lsslp.pm index 16980997e..5e1cde433 100644 --- a/xCAT-server/lib/xcat/plugins/lsslp.pm +++ b/xCAT-server/lib/xcat/plugins/lsslp.pm @@ -9,18 +9,32 @@ use xCAT::Usage; use POSIX "WNOHANG"; use Storable qw(freeze thaw); use Time::HiRes qw(gettimeofday); +use xCAT::SvrUtils qw/sendmsg/; use IO::Select; use XML::Simple; $XML::Simple::PREFERRED_PARSER='XML::Parser'; use xCAT::PPCdb; use xCAT::NodeRange; use xCAT::Utils; +use xCAT::MacMap; +use xCAT::IMMUtils; +use xCAT_plugin::blade; +use xCAT::SLP; -#require xCAT::MacMap; -require xCAT_plugin::blade; -require xCAT::SLP; - +my $mpahash; +my $defaultbladeuser; +my $defaultbladepass; +my $currentbladepass; +my $currentbladeuser; +my %nodebymp; +my $macmap; +my %chassisbyuuid; +my %flexchassisuuid; +my %flexchassismap; +my %passwordmap; +my %doneaddrs; +my %btresult; ####################################### # Constants @@ -255,7 +269,7 @@ sub parse_args { # Process command-line flags ############################################# if (!GetOptions( \%opt, - qw(h|help V|Verbose v|version i=s x z w r s=s e=s t=s m c n C=s T=s I updatehosts makedhcp resetnet vpdtable))) { + qw(h|help V|Verbose v|version i=s x z w r s=s e=s t=s m c n C=s T=s I flexdiscover updatehosts vpdtable))) { return( usage() ); } @@ -403,6 +417,14 @@ sub parse_args { if ( exists( $opt{I} )) { $globalopt{I} = 1; } + + ############################################## + # do slp and setup for cmm + ############################################## + if ( exists( $opt{flexdiscover} )) { + $globalopt{flexdiscover} = 1; + } + return (0); } @@ -509,6 +531,11 @@ sub invoke_dodiscover { my %arg; + if ($globalopt{flexdiscover}) { + $arg{SrvTypes} = [ qw/service:management-hardware.IBM:chassis-management-module service:management-hardware.IBM:management-module service:management-hardware.IBM:integrated-management-module2/ ]; + my ($searchmacsref,$sendcount,$rsp) = xCAT::SLP::dodiscover(SrvTypes=>$arg{SrvTypes},Callback=>\&bt_handle_new_slp_entity); + return ($searchmacsref,$sendcount,$rsp); + } $arg{SrvTypes} = $services; #$arg{Callback} = \&handle_new_slp_entity; $arg{Ip} = $globalopt{i} if($globalopt{i}); @@ -1619,6 +1646,10 @@ sub process_request { my ($searchmacsref,$sendcount,$rspc) = invoke_dodiscover(\%request); + if ($globalopt{flexdiscover}) { + bt_process($req, $callback, $searchmacsref); + return ( SUCCESS ); + } ########################################### # Record ending time ########################################### @@ -1710,4 +1741,238 @@ sub filtersamevlan { } return $newhash; } +########################################################################## +# This is the function that merged in from slpdiscover +########################################################################## +sub bt_process { + my $request = shift; + my $callback = shift; + my $searef = shift; + + + + my $mpatab=xCAT::Table->new("mpa",-create=>0); + my @mpaentries; + $mpahash={}; + if (ref $request->{environment} and ref $request->{environment}->[0]->{XCAT_CURRENTPASS}) { + $currentbladepass=$request->{environment}->[0]->{XCAT_CURRENTPASS}->[0]; + } else { + $currentbladepass="PASSW0RD"; + } + if (ref $request->{environment} and ref $request->{environment}->[0]->{XCAT_CURRENTUSER}) { + $currentbladeuser=$request->{environment}->[0]->{XCAT_CURRENTUSER}->[0]; + } else { + $currentbladeuser="USERID"; + } + if ($mpatab) { + @mpaentries = $mpatab->getAllNodeAttribs([qw/mpa username password/]); + foreach (@mpaentries) { + $mpahash->{$_->{mpa}}=$_; + } + } + my $passwdtab=xCAT::Table->new("passwd",-create=>0); + $defaultbladeuser="USERID"; + $defaultbladepass=""; + if ($passwdtab) { + my @ents = $passwdtab->getAttribs({key=>'blade'},'username','password'); + foreach (@ents) { + if ($_->{username} eq "HMC") { next; } + if ($_->{username}) { $defaultbladeuser=$_->{username}; } + if ($_->{password}) { $defaultbladepass=$_->{password}; } + } + } + my $mactab = xCAT::Table->new("mac"); + my %machash; + my %node2machash; + my %macuphash; + my @maclist = $mactab->getAllNodeAttribs([qw/node mac/]); + foreach (@maclist) { + $machash{$_->{node}}=$_->{mac}; + $node2machash{$_->{mac}} = $_->{node}; + } + + + + my $mptab = xCAT::Table->new('mp'); + my $nodecandidates; + if ($mptab) { + my @mpents = $mptab->getAllNodeAttribs(['node','mpa','id']); + foreach (@mpents) { + $nodebymp{$_->{mpa}}->{$_->{id}}=$_->{node}; + } + } + + $macmap = xCAT::MacMap->new(); + $macmap->refresh_table(); + my @toconfig; + foreach my $mac (keys(%btresult)) { + my $node = $macmap->find_mac($mac,1); + unless ($node) { + if (defined $node2machash{$mac}) { + $node = $node2machash{$mac}; + } else { + next; + } + } + my $data = $btresult{$mac}; + $data->{nodename}=$node; + $data->{macaddress}=$mac; + $chassisbyuuid{$data->{attributes}->{"enclosure-uuid"}->[0]}=$node; + push @toconfig,$data; + } + + foreach my $data (@toconfig) { + my $mac = $data->{macaddress}; + my $nodename = $data->{nodename}; + my $addr = $data->{peername}; #todo, use sockaddr and remove the 427 port from it instead? + if ($addr =~ /^fe80/) { #Link local address requires scope index + $addr .= "%".$data->{scopeid}; + } + $flexchassisuuid{$nodename}=$data->{attributes}->{"enclosure-uuid"}->[0]; + + if ($data->{SrvType} eq "service:management-hardware.IBM:chassis-management-module") { + sendmsg(":Found ".$data->{SrvType}." at address $addr",$callback,$nodename); + + setup_cmm_pass($nodename); + if ($machash{$nodename} =~ /$mac/i) { #ignore prospects already known to mac table + configure_hosted_elements($nodename, $callback); + next; + } + + unless (do_blade_setup($data,$callback,curraddr=>$addr)) { + next; + } + configure_hosted_elements($nodename, $callback); + unless (do_blade_setup($data,$callback,curraddr=>$addr,pass2=>1)) { + next; + } + sendmsg(":Configuration complete, configuration may take a few minutes to take effect",$callback,$nodename); + $macuphash{$nodename} = { mac => $mac }; + } + } + $mactab->setNodesAttribs(\%macuphash); +} + + +sub configure_hosted_elements { + my $cmm = shift; + my $callback = shift; + my $uuid=$flexchassisuuid{$cmm}; + my $node; + my $immdata; + my $slot; + my $user = $passwordmap{$cmm}->{username}; + my $pass = $passwordmap{$cmm}->{password}; + foreach $immdata (values %{$flexchassismap{$uuid}}) { + $slot=$immdata->{attributes}->{slot}->[0]; + if ($node = $nodebymp{$cmm}->{$slot}) { + my $addr = $immdata->{peername}; #todo, use sockaddr and remove the 427 port from it instead? + if ($addr =~ /^fe80/) { #Link local address requires scope index + $addr .= "%".$immdata->{scopeid}; + } + if ($doneaddrs{$node}) { next; } + $doneaddrs{$node}=1; + xCAT::IMMUtils::setupIMM($node,nodedata=>$immdata,curraddr=>$addr,cliusername=>$user,clipassword=>$pass,callback=>$callback); + } else { + sendmsg(": Ignoring target in bay $slot, no node found with mp.mpa/mp.id matching",$callback,$cmm); + } + + } + while (wait() > 0) {} +} + +sub setup_cmm_pass { + my $nodename = shift; + my $localuser=$defaultbladeuser; + my $localpass=$defaultbladepass; + if ($mpahash->{$nodename}) { + if ($mpahash->{$nodename}->{username}) { + $localuser = $mpahash->{$nodename}->{username}; + } + if ($mpahash->{$nodename}->{password}) { + $localpass = $mpahash->{$nodename}->{password}; + } + } + $passwordmap{$nodename}->{username}=$localuser; + $passwordmap{$nodename}->{password}=$localpass; +} +sub do_blade_setup { + my $data = shift; + my $callback = shift; + my %args = @_; + my $addr = $args{curraddr}; + my $nodename = $data->{nodename}; + my $localuser=$passwordmap{$nodename}->{username}; + my $localpass=$passwordmap{$nodename}->{password}; + if (not $localpass or $localpass eq "PASSW0RD") { + sendmsg([1,":Password for blade must be specified in either mpa or passwd tables, and it must not be PASSW0RD"],$callback,$nodename); + return 0; + } + require xCAT_plugin::blade; + my @cmds; + my %exargs; + if ($args{pass2}) { + @cmds = qw/initnetwork=*/; + %exargs = ( nokeycheck=>1 ); #still not at the 'right' ip, so the known hosts shouldn't be bothered + } else { + @cmds = qw/snmpcfg=enable sshcfg=enable textid=*/; # initnetwork=*/; defer initnetwork until after chassis members have been configured + %exargs = ( curruser=>$currentbladeuser, currpass=>$currentbladepass ); + } + my $result; + $@=""; + my $rc = eval { $result = xCAT_plugin::blade::clicmds( + $nodename, + $localuser, + $localpass, + $nodename, + 0, + curraddr=>$addr, + %exargs, + cmds=>\@cmds ); + 1; + }; + my $errmsg=$@; + if ($errmsg) { + if ($errmsg =~ /Incorrect Password/) { + sendmsg([1,"Failed to set up Management module due to Incorrect Password (You may try the environment variables XCAT_CURRENTUSER and/or XCAT_CURRENTPASS to try a different value)"],$callback,$nodename); + }else { + sendmsg([1,"Failed to set up Management module due to $errmsg"],$callback,$nodename); + } + return 0; + } + if ($result) { + if ($result->[0]) { + if ($result->[2] =~ /Incorrect Password/) { + sendmsg([1,"Failed to set up Management module due to Incorrect Password (You may try the environment variables XCAT_CURRENTUSER and/or XCAT_CURRENTPASS to try a different value)"],$callback,$nodename); + return 0; + } + my $errors = $result->[2]; + if (ref $errors) { + foreach my $error (@$errors) { + sendmsg([$result->[0],$error],$callback,$nodename); + } + } else { + sendmsg([$result->[0],$result->[2]],$callback,$nodename); + } + return 0; + } + } + return $rc; +} +sub bt_handle_new_slp_entity { + my $data = shift; + delete $data->{sockaddr}; #won't need it + my $mac = xCAT::SLP::get_mac_for_addr($data->{peername}); + if ($data->{SrvType} eq "service:management-hardware.IBM:integrated-management-module2" and $data->{attributes}->{"enclosure-form-factor"}->[0] eq "BC2") { + $data->{macaddress}=$mac; + #this is a Flex ITE, don't go mac searching for it, but remember the chassis UUID for later + if ($flexchassismap{$data->{attributes}->{"chassis-uuid"}->[0]}->{$mac} and $data->{peername} !~ /fe80/) { + return; + } + $flexchassismap{$data->{attributes}->{"chassis-uuid"}->[0]}->{$mac}=$data; + return; + } + unless ($mac) { return; } + $btresult{$mac} = $data; +} 1;