From 83d5fe80bcf60921b4f74586c127f86637a05b28 Mon Sep 17 00:00:00 2001 From: bp-sawyers Date: Thu, 24 Jan 2013 16:46:15 +0000 Subject: [PATCH] updated pasu to get the ipmi attribs from the db git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@14985 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- xCAT-client/bin/pasu | 141 +++++++++++++++++++++++++------ xCAT-client/pods/man1/pasu.1.pod | 32 +++---- 2 files changed, 124 insertions(+), 49 deletions(-) diff --git a/xCAT-client/bin/pasu b/xCAT-client/bin/pasu index 02c23917c..d8c380c7a 100755 --- a/xCAT-client/bin/pasu +++ b/xCAT-client/bin/pasu @@ -13,7 +13,7 @@ use lib "$::XCATROOT/lib/perl"; use IO::Socket::SSL; use XML::Simple; $XML::Simple::PREFERRED_PARSER='XML::Parser'; -#use Data::Dumper; +use Data::Dumper; use IO::Handle; use IO::Select; use xCAT::Utils; @@ -63,21 +63,34 @@ my @nodes=(); #print "fanout=$fanout, username=$username, noderange=$noderange\n"; +my $nodeattrs; if ($::NONODECHECK) { @nodes=split(/,/, $noderange); } -else { # contact xcatd to expand noderange - @nodes = expandnoderange(); +else { # contact xcatd to expand noderange and get ipmi attrs + # do not need to do this call, because getting the ipmi atts will also give us a list of nodes + #@nodes = expandnoderange($noderange); + + # this is reference to a hash, each key is the nodename and the value is a reference to a hash of attr values + $nodeattrs = getipmiattrs($noderange); + #print Dumper($nodeattrs); + #foreach my $k (keys(%$nodeattrs)) { + # print "$k:\n"; + # my $subhash = $nodeattrs->{$k}; + # foreach my $k2 (keys(%$subhash)) { print " $k2=", $subhash->{$k2}, "\n"; } + #} + #exit; + @nodes = keys(%$nodeattrs); } +my ($defaultuser, $defaultpw); if (!defined($username) || !defined($passwd)) { - my ($user, $pw) = getcredentials(); - if (!defined($username)) { $username = $user; } - if (!defined($passwd)) { $passwd = $pw; } + ($defaultuser, $defaultpw) = getdefaultcredentials(); + #if (!defined($username)) { $username = $user; } + #if (!defined($passwd)) { $passwd = $pw; } + if ($::VERBOSE) { print "default username=$defaultuser, passwd=$defaultpw\n"; } } -if ($::VERBOSE) { print "username=$username, passwd=$passwd\n"; } - my $children = 0; my $inputs = new IO::Select; my %pids; # pid => node @@ -99,24 +112,44 @@ if ($interface) { while (scalar(@retries)) { @nodes = @retries; @retries = (); -foreach (@nodes) { - my $node=$_; - while ($children > $pasumaxp) { processoutput($inputs); } - my $child; - $children++; - #asunode(\$child,$node,$username,$passwd,@ARGV[1 .. $#ARGV]); - asunode(\$child,$node,$username,$passwd,$batchfile,@ARGV); # child is the fd of the child process - $inputs->add($child); - $nodehdl{$child} = $node; - #sleep 3; -} -while ($inputs->count) { - processoutput($inputs); -} -while (processoutput($inputs)) {}; -while (wait != -1) { - yield; -} + foreach (@nodes) { + my $node=$_; + my $ipmiattrs = $nodeattrs->{$node}; + my $bmc = $ipmiattrs->{bmc}; + if (!defined($bmc)) { + print "$node: the ipmi.bmc attribute is not defined, skipping.\n"; + next; + } + + # if we have already forked the max # of simultaneous processes, wait till 1 finishes + while ($children > $pasumaxp) { processoutput($inputs); } + + # fork anothe process + my $child; + $children++; + # precedence on the username and password is: cli option, ipmi table, passwd table + my ($user, $pw); + if (defined($username)) { $user = $username; } # cli option + elsif (defined($ipmiattrs->{username})) { $user = $ipmiattrs->{username}; } + else { $user = $defaultuser; } + if (defined($passwd)) { $pw = $passwd; } # cli option + elsif (defined($ipmiattrs->{password})) { $pw = $ipmiattrs->{password}; } + else { $pw = $defaultpw; } + if ($::VERBOSE) { print "For node $node using bmc=$bmc, user=$user, pw=$pw\n"; } + #asunode(\$child,$node,$username,$passwd,@ARGV[1 .. $#ARGV]); + asunode(\$child,$node,$bmc,$user,$pw,$batchfile,@ARGV); # child is the fd of the child process + $inputs->add($child); + $nodehdl{$child} = $node; + } + + # quiesce everything + while ($inputs->count) { + processoutput($inputs); + } + while (processoutput($inputs)) {}; + while (wait != -1) { + yield; + } } my $exitcode=0; @@ -181,6 +214,7 @@ sub processoutput { #This way, one arbiter handles output, no interrupting sub asunode { my $out = shift; # this is a reference to the child file descriptor my $node = shift; + my $bmc = shift; my $username = shift; my $passwd = shift; my $batchfile = shift; @@ -190,7 +224,7 @@ sub asunode { } else { foreach my $a (@_) { $args .= ' ' . xCAT::Utils->quote($a); } } - my $cmd = "$::asucmd $args --host $node --user $username --password $passwd 2>&1 |"; + my $cmd = "$::asucmd $args --host $bmc --user $username --password $passwd 2>&1 |"; if ($::VERBOSE) { print "forking $cmd\n"; } my $pid = open($$out, $cmd); $pids{$pid} = $node; @@ -198,6 +232,7 @@ sub asunode { # Contact xcatd to expand the noderange into a list of nodes sub expandnoderange { + my $noderange = shift @_; my @nodes; my @user = getpwuid($>); my $homedir=$user[7]; @@ -244,8 +279,58 @@ sub expandnoderange { return @nodes; } +# Contact xcatd to get from the ipmi table for this list of nodes: bmc, username, password +sub getipmiattrs { + my $noderange = shift @_; + my $nodeattrs; # this will be a reference to a hash + my @user = getpwuid($>); + my $homedir=$user[7]; + my $client = IO::Socket::SSL->new( + PeerAddr=>$xcathost, + SSL_key_file=>$homedir."/.xcat/client-cred.pem", + SSL_cert_file=>$homedir."/.xcat/client-cred.pem", + SSL_ca_file => $homedir."/.xcat/ca.pem", + SSL_use_cert => 1, + #SSL_verify_mode => 1, + ); + die "Connection failure: $!\n" unless ($client); + my %cmdref = (command => 'getNodesAttribs', noderange => $noderange, table => 'ipmi'); + push (@{$cmdref{attr}}, qw(bmc username password)); + $SIG{ALRM} = sub { die "No response getting ipmi attributes" }; + alarm(15); + my $msg = XMLout(\%cmdref,RootName=>'xcatrequest', NoAttr=>1, KeyAttr => []); + if ($ENV{XCATXMLTRACE}) { print $msg; } + print $client $msg; + alarm(15); + my $response=""; + while (<$client>) { + alarm(0); + $response .= $_; + if ($response =~ m/<\/xcatresponse>/) { + if ($ENV{XCATXMLTRACE}) { print $response; } + my $rsp=XMLin($response, ForceArray => ['node']); + $response=''; + if ($rsp->{warning}) { + printf "Warning: ".$rsp->{warning}."\n"; + } + if ($rsp->{error}) { + die ("ERROR: ".$rsp->{error}."\n"); + } elsif ($rsp->{node}) { + #print Dumper($rsp->{node}); + $nodeattrs=$rsp->{node}; # this is reference to a hash, each key is the nodename and the value is a reference to a hash of attr values + } + if ($rsp->{serverdone}) { + last; + } + } + } + close($client); + #if ($::VERBOSE) { print 'Nodes:', join(',',$nodeattrs), "\n"; } + return $nodeattrs; +} + # Contact xcatd to get the default user/pw for ipmi in the xcat passwd table -sub getcredentials { +sub getdefaultcredentials { my @data; my @user = getpwuid($>); my $homedir=$user[7]; diff --git a/xCAT-client/pods/man1/pasu.1.pod b/xCAT-client/pods/man1/pasu.1.pod index d4addc50b..022d81cb5 100644 --- a/xCAT-client/pods/man1/pasu.1.pod +++ b/xCAT-client/pods/man1/pasu.1.pod @@ -4,9 +4,9 @@ B - run the ASU to many nodes in parallel =head1 SYNOPSIS -B [B<-V>] [B<-d>] [B<-n>] [B<-i> I] [B<-l> I] [B<-p> I] [B<-f> I] I I +B [B<-V>] [B<-d>] [B<-n>] [B<-l> I] [B<-p> I] [B<-f> I] I I -B [B<-V>] [B<-d>] [B<-n>] [B<-i> I] [B<-l> I] [B<-p> I] [B<-f> I] B<-b> I I +B [B<-V>] [B<-d>] [B<-n>] [B<-l> I] [B<-p> I] [B<-f> I] B<-b> I I B [B<-h> | B<--help>] @@ -17,11 +17,6 @@ that ASU connects from the xCAT management node to the IMM (BMC) of each node to see all of the ASU settings available on the node, use the "show all" command. To query or set multiple values, use the B<-b> (batch) option. To group similar output from multiple nodes, use L. -Current Limitation: The pasu command currently only queries the node names from the xCAT DB, but ASU really -needs to connect to the IMM of the node. You can make this work by defining hostnames for your IMMs that are of -the form: -imm . Then use the B<-i imm> flag and pasu will add "-imm" to each nodename before contacting -it. Or you can use the B<-n> option and give the list of IMM hostnames or IP addresses explicitly. - Before running B, you must install the ASU RPM from IBM. You can download it from the IBM Fix Central site. You also must configure the IMMs properly according to xCAT documentation. Run "B I B" to confirm that the IMMs are configured properly. @@ -30,25 +25,20 @@ to confirm that the IMMs are configured properly. =over 10 -=item B<-i|--interface> I - -A suffix to add to each nodename before connecting to it. Currently use this to change the nodename into the -IMM name. - =item B<-n|--nonodecheck> Do not send the noderange to xcatd to expand it into a list of nodes. Use the noderange exactly as it is specified -to pasu. In this case, the noderange must be a simple list of comma-separated node names. +to pasu. In this case, the noderange must be a simple list of comma-separated hostnames of the IMMs. =item B<-l|--loginname> I The username to use to connect to the IMMs. If not specified, the row in the xCAT B table with key "ipmi" -will be used to get the username. Currently B does not use the table value ipmi.username. +will be used to get the username. =item B<-p|--passwd> I The password to use to connect to the IMMs. If not specified, the row in the xCAT passwd table with key "ipmi" -will be used to get the password. Currently B does not use the table value ipmi.password. +will be used to get the password. =item B<-f|--fanout> @@ -94,7 +84,7 @@ Display usage message. To display the Com1ActiveAfterBoot setting on 2 nodes: - pasu -n node1,node2 show DevicesandIOPorts.Com1ActiveAfterBoot + pasu node1,node2 show DevicesandIOPorts.Com1ActiveAfterBoot Output is similar to: @@ -103,9 +93,9 @@ Output is similar to: =item 2. -To display the Com1ActiveAfterBoot setting on all compute nodes (and the IMMs have hostnames like -imm): +To display the Com1ActiveAfterBoot setting on all compute nodes: - pasu -i imm compute show DevicesandIOPorts.Com1ActiveAfterBoot | xcoll + pasu compute show DevicesandIOPorts.Com1ActiveAfterBoot | xcoll Output is similar to: @@ -116,7 +106,7 @@ Output is similar to: =item 3. -To set several settings on all compute nodes (and the IMMs have hostnames like -imm), create a batch file +To set several settings on all compute nodes, create a batch file called (for example) asu-settings with contents: set DevicesandIOPorts.Com1ActiveAfterBoot Enable @@ -126,7 +116,7 @@ called (for example) asu-settings with contents: Then run: - pasu -i imm -b asu-settings compute | xcoll + pasu -b asu-settings compute | xcoll Output is similar to: @@ -164,7 +154,7 @@ called (for example) asu-show with contents: Then run: - pasu -i imm -b asu-show compute | xcoll + pasu -b asu-show compute | xcoll Output is similar to: