mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-03 21:02:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			625 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			625 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head1
 | 
						|
  xCAT plugin package to handle pdu 
 | 
						|
 | 
						|
   Supported command:
 | 
						|
        rpower 
 | 
						|
        rinv
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
package xCAT_plugin::pdu;
 | 
						|
 | 
						|
BEGIN {
 | 
						|
    $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr';
 | 
						|
}
 | 
						|
use lib "$::XCATROOT/lib/perl";
 | 
						|
 | 
						|
use xCAT::Table;
 | 
						|
use xCAT::Utils;
 | 
						|
use xCAT::FifoPipe;
 | 
						|
use xCAT::MsgUtils;
 | 
						|
use xCAT::State;
 | 
						|
use xCAT::SvrUtils;
 | 
						|
use xCAT::Usage;
 | 
						|
use xCAT::NodeRange;
 | 
						|
use Data::Dumper;
 | 
						|
use Getopt::Long;
 | 
						|
use File::Path;
 | 
						|
use Term::ANSIColor;
 | 
						|
use Time::Local;
 | 
						|
use strict;
 | 
						|
use Class::Struct;
 | 
						|
use XML::Simple;
 | 
						|
use Storable qw(dclone);
 | 
						|
use SNMP;
 | 
						|
use Expect;
 | 
						|
use Net::Ping;
 | 
						|
 | 
						|
my $VERBOSE = 0;
 | 
						|
my %allerrornodes = ();
 | 
						|
my $callback;
 | 
						|
my $pdutab;
 | 
						|
my @pduents;
 | 
						|
my $pdunodes;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head3  handled_commands
 | 
						|
 | 
						|
Return list of commands handled by this plugin
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
sub handled_commands
 | 
						|
{
 | 
						|
    return {
 | 
						|
       rpower => ["nodehm:mgt","pduoutlet:pdu=\.\*"],
 | 
						|
       rinv   => ["nodehm:mgt"],
 | 
						|
       nodeset => ["nodehm:mgt"],
 | 
						|
       rspconfig => ["nodehm:mgt"],
 | 
						|
       pdudiscover => "pdu",
 | 
						|
    };
 | 
						|
}
 | 
						|
 | 
						|
#--------------------------------------------------------------------------------
 | 
						|
=head3   preprocess_request
 | 
						|
 | 
						|
Parse the arguments and display the usage or the version string.
 | 
						|
 | 
						|
=cut
 | 
						|
#--------------------------------------------------------------------------------
 | 
						|
sub preprocess_request {
 | 
						|
    my $req = shift;
 | 
						|
    if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; }
 | 
						|
    my $callback=shift;
 | 
						|
    my @requests;
 | 
						|
 | 
						|
    my $command = $req->{command}->[0];
 | 
						|
    my $noderange = $req->{node};           #Should be arrayref
 | 
						|
    my $extrargs = $req->{arg};
 | 
						|
    my @exargs=($req->{arg});
 | 
						|
    if (ref($extrargs)) {
 | 
						|
        @exargs=@$extrargs;
 | 
						|
    }
 | 
						|
 | 
						|
    my $usage_string=xCAT::Usage->parseCommand($command, @exargs);
 | 
						|
    if ($usage_string) {
 | 
						|
        $callback->({data=>[$usage_string]});
 | 
						|
        $req = {};
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((!$noderange) && ($command ne "pdudiscover") ){
 | 
						|
        $usage_string = xCAT::Usage->getUsage($command);
 | 
						|
        $callback->({ data => $usage_string });
 | 
						|
        $req = {};
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    my @result = ();
 | 
						|
    my $mncopy = {%$req};
 | 
						|
    push @result, $mncopy;
 | 
						|
    return \@result;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head3  process_request
 | 
						|
 | 
						|
  Process the command.
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
sub process_request
 | 
						|
{
 | 
						|
    my $request  = shift;
 | 
						|
    my $callback = shift;
 | 
						|
    my $subreq   = shift;
 | 
						|
    my $command  = $request->{command}->[0];
 | 
						|
    my $noderange = $request->{node};           #Should be arrayref
 | 
						|
    my $extrargs  = $request->{arg};
 | 
						|
    my @exargs    = ($request->{arg});
 | 
						|
 | 
						|
    if (ref($extrargs)) {
 | 
						|
        @exargs = @$extrargs;
 | 
						|
    }
 | 
						|
 | 
						|
    #fill in the total outlet count for each pdu
 | 
						|
    $pdutab = xCAT::Table->new('pdu');
 | 
						|
    @pduents = $pdutab->getAllNodeAttribs(['node', 'outlet']);
 | 
						|
    fill_outletCount(\@pduents, $callback);
 | 
						|
 | 
						|
    if( $command eq "rinv") {
 | 
						|
        #for higher performance, handle node in batch
 | 
						|
        return powerstat($noderange, $callback);
 | 
						|
    }elsif ($command eq "rpower") {
 | 
						|
        my $subcmd = $exargs[0];
 | 
						|
        if (($subcmd eq 'pduoff') || ($subcmd eq 'pduon') || ($subcmd eq 'pdustat')|| ($subcmd eq 'pdureset') ){
 | 
						|
            #if one day, pdu node have pdu attribute, handle in this section too
 | 
						|
            return powerpduoutlet($noderange, $subcmd, $callback);
 | 
						|
        } else {
 | 
						|
            #-------------------------------------------
 | 
						|
            #there are 2 cases will enter this block
 | 
						|
            #one is if node's mgt is pdu
 | 
						|
            #another is if node has pdu attribute but mgt isn't pdu
 | 
						|
            #if the node has pdu attribute but mgt isn't pdu, 
 | 
						|
            #should do nothing for this node, let other plugin to hanle this node 
 | 
						|
            #-------------------------------------------
 | 
						|
            my @allpdunodes=();
 | 
						|
            my $nodehm = xCAT::Table->new('nodehm');
 | 
						|
            my $nodehmhash = $nodehm->getNodesAttribs($noderange, ['mgt']);
 | 
						|
            foreach my $node (@$noderange) { 
 | 
						|
                if($nodehmhash->{$node}->[0]->{mgt} eq 'pdu'){
 | 
						|
                    push @allpdunodes, $node;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            if(@allpdunodes) {
 | 
						|
                if(($subcmd eq 'on') || ($subcmd eq 'off') || ($subcmd eq 'stat') || ($subcmd eq 'state') || ($subcmd eq 'reset') ){
 | 
						|
                    return powerpdu(\@allpdunodes, $subcmd, $callback);
 | 
						|
                } else {
 | 
						|
                    my $pdunode = join (",", @allpdunodes);
 | 
						|
                    $callback->({ errorcode => [1],error => "The option $subcmd is not support for pdu node(s) $pdunode."});
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }elsif($command eq "rspconfig") {
 | 
						|
        my $subcmd = $exargs[0];
 | 
						|
        if ($subcmd eq 'sshcfg') {
 | 
						|
            process_sshcfg($noderange, $subcmd, $callback);
 | 
						|
        } else {
 | 
						|
            $callback->({ errorcode => [1],error => "The input $command $subcmd is not support for pdu"});
 | 
						|
        }
 | 
						|
    }elsif($command eq "pdudiscover") {
 | 
						|
        process_pdudiscover($request, $subreq, $callback);
 | 
						|
    }elsif($command eq "nodeset") {
 | 
						|
        $callback->({ errorcode => [1],error => "The input $command is not support for pdu"});
 | 
						|
    }else{
 | 
						|
        #reserve for other new command in future
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
sub fill_outletCount {
 | 
						|
    my $pduentries = shift;
 | 
						|
    my $callback = shift;
 | 
						|
    my $outletoid = ".1.3.6.1.4.1.2.6.223.8.2.1.0";
 | 
						|
    my $pdutab = xCAT::Table->new('pdu');
 | 
						|
 | 
						|
    foreach my $pdu (@$pduentries) {
 | 
						|
        my $cur_pdu = $pdu->{node};
 | 
						|
        my $count = $pdu->{outlet};
 | 
						|
        #get total outlet number for the pdu
 | 
						|
        if (!$count) {
 | 
						|
            my $session = connectTopdu($cur_pdu,$callback);
 | 
						|
            #will not log this error to output
 | 
						|
            if (!$session) {
 | 
						|
                next;
 | 
						|
            }
 | 
						|
            $count = $session->get("$outletoid");
 | 
						|
            if ($count) {
 | 
						|
                $pdutab->setNodeAttribs($cur_pdu, {outlet => $count});
 | 
						|
            }
 | 
						|
        }
 | 
						|
        $pdunodes->{$cur_pdu}->{outlet}=$count;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head3  powerpdu 
 | 
						|
 | 
						|
    Process power command (stat/off/on) for pdu/pdus
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
sub powerpdu {
 | 
						|
    my $noderange = shift;
 | 
						|
    my $subcmd = shift;
 | 
						|
    my $callback = shift;
 | 
						|
 | 
						|
    if (($subcmd eq "stat") || ($subcmd eq "state")){
 | 
						|
        return powerstat($noderange, $callback);
 | 
						|
    }
 | 
						|
 | 
						|
    foreach my $node (@$noderange) {
 | 
						|
        my $session = connectTopdu($node,$callback);
 | 
						|
        if (!$session) {
 | 
						|
            $callback->({ errorcode => [1],error => "Couldn't connect to $node"});
 | 
						|
            next;
 | 
						|
        }
 | 
						|
        my $count = $pdunodes->{$node}->{outlet};
 | 
						|
        my $value;
 | 
						|
        my $statstr;
 | 
						|
        if ($subcmd eq "off") {
 | 
						|
            $value = 0;
 | 
						|
            $statstr = "off";
 | 
						|
        } elsif ( $subcmd eq "on") {
 | 
						|
            $value = 1;
 | 
						|
            $statstr = "on";
 | 
						|
        } else  {
 | 
						|
            $value = 2;
 | 
						|
            $statstr = "reset";
 | 
						|
        }
 | 
						|
 | 
						|
        for (my $outlet =1; $outlet <= $count; $outlet++)
 | 
						|
        {
 | 
						|
            outletpower($session, $outlet, $value);
 | 
						|
            if ($session->{ErrorStr}) { 
 | 
						|
                $callback->({ errorcode => [1],error => "Failed to get outlet status for $node"});
 | 
						|
            } else {
 | 
						|
                my $output = " outlet $outlet is $statstr"; 
 | 
						|
                xCAT::SvrUtils::sendmsg($output, $callback, $node, %allerrornodes);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head3  powerpduoutlet 
 | 
						|
 | 
						|
    Process power command (pdustat/pduoff/pduon) for compute nodes,
 | 
						|
    the pdu attribute needs to be set 
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
sub powerpduoutlet {
 | 
						|
    my $noderange = shift;
 | 
						|
    my $subcmd = shift;
 | 
						|
    my $callback = shift;
 | 
						|
    my $output;
 | 
						|
    my $value;
 | 
						|
    my $statstr;
 | 
						|
 | 
						|
    my $tmpnodestr = join(",", @$noderange);
 | 
						|
 | 
						|
    my $nodetab = xCAT::Table->new('pduoutlet');
 | 
						|
    my $nodepdu = $nodetab->getNodesAttribs($noderange,['pdu']);
 | 
						|
    foreach my $node (@$noderange) {
 | 
						|
        # the pdu attribute needs to be set
 | 
						|
        if(! $nodepdu->{$node}->[0]->{pdu}){
 | 
						|
            $callback->({ error => "$node: without pdu attribute"});
 | 
						|
            next;
 | 
						|
        }
 | 
						|
 | 
						|
        my @pdus = split /,/, $nodepdu->{$node}->[0]->{pdu};
 | 
						|
        foreach my $pdu_outlet (@pdus) {
 | 
						|
            my ($pdu, $outlet) = split /:/, $pdu_outlet;
 | 
						|
            my $session = connectTopdu($pdu,$callback);
 | 
						|
            if (!$session) {
 | 
						|
                $callback->({ errorcode => [1],error => "$node: Couldn't connect to $pdu"});
 | 
						|
                next;
 | 
						|
            }
 | 
						|
            if ($outlet > $pdunodes->{$pdu}->{outlet} ) {
 | 
						|
                $callback->({ error => "$node: $pdu outlet number $outlet is invalid"});
 | 
						|
                next;
 | 
						|
            }
 | 
						|
            my $cmd;
 | 
						|
            if ($subcmd eq "pdustat") {
 | 
						|
                $statstr=outletstat($session, $outlet);
 | 
						|
            } elsif ($subcmd eq "pduoff") {
 | 
						|
                $value = 0;
 | 
						|
                $statstr = "off";
 | 
						|
                outletpower($session, $outlet, $value);
 | 
						|
            } elsif ($subcmd eq "pduon") {
 | 
						|
                $value = 1;
 | 
						|
                $statstr = "on";
 | 
						|
                outletpower($session, $outlet, $value);
 | 
						|
            } elsif ($subcmd eq "pdureset") {
 | 
						|
                $value = 2;
 | 
						|
                $statstr = "reset";
 | 
						|
                outletpower($session, $outlet, $value);
 | 
						|
            } else {
 | 
						|
                $callback->({ error => "$subcmd is not support"});
 | 
						|
            } 
 | 
						|
    
 | 
						|
            if ($session->{ErrorStr}) { 
 | 
						|
                $callback->({ errorcode => [1],error => "$node: $pdu outlet $outlet has error = $session->{ErrorStr}"});
 | 
						|
            } else {
 | 
						|
                $output = "$pdu outlet $outlet is $statstr"; 
 | 
						|
                xCAT::SvrUtils::sendmsg($output, $callback, $node, %allerrornodes);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head3  outletpower 
 | 
						|
 | 
						|
    Process power command for one pdu outlet,
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
sub outletpower {
 | 
						|
    my $session = shift;
 | 
						|
    my $outlet = shift;
 | 
						|
    my $value = shift;
 | 
						|
 | 
						|
    my $oid = ".1.3.6.1.4.1.2.6.223.8.2.2.1.11";
 | 
						|
    my $type = "INTEGER";
 | 
						|
    if ($session->{newmib}) {
 | 
						|
        $oid = ".1.3.6.1.4.1.2.6.223.8.2.2.1.13";
 | 
						|
    }    
 | 
						|
 | 
						|
 | 
						|
    my $varbind = new SNMP::Varbind([ $oid, $outlet, $value, $type ]);
 | 
						|
    return $session->set($varbind);
 | 
						|
}
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head3  powerstat 
 | 
						|
 | 
						|
    Process command to query status of pdu
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
sub powerstat {
 | 
						|
    my $noderange = shift;
 | 
						|
    my $callback = shift;
 | 
						|
    my $output;
 | 
						|
 | 
						|
    foreach my $pdu (@$noderange) {
 | 
						|
        my $session = connectTopdu($pdu,$callback);
 | 
						|
        if (!$session) {
 | 
						|
            $callback->({ errorcode => [1],error => "Couldn't connect to $pdu"});
 | 
						|
            next;
 | 
						|
        }
 | 
						|
        my $count = $pdunodes->{$pdu}->{outlet};
 | 
						|
        for (my $outlet =1; $outlet <= $count; $outlet++)
 | 
						|
        {
 | 
						|
            my $statstr = outletstat($session, $outlet);
 | 
						|
            my $msg = " outlet $outlet is $statstr";
 | 
						|
            xCAT::SvrUtils::sendmsg($msg, $callback, $pdu, %allerrornodes);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head3  outletstat 
 | 
						|
 | 
						|
    Process command to query status of one pdu outlet
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
sub outletstat {
 | 
						|
    my $session = shift;
 | 
						|
    my $outlet = shift;
 | 
						|
 
 | 
						|
    my $oid = ".1.3.6.1.4.1.2.6.223.8.2.2.1.11";
 | 
						|
    my $output;
 | 
						|
    my $statstr;
 | 
						|
    if ($session->{newmib}) {
 | 
						|
        $oid = ".1.3.6.1.4.1.2.6.223.8.2.2.1.13";
 | 
						|
    }
 | 
						|
 | 
						|
    $output = $session->get("$oid.$outlet");
 | 
						|
    if ($output eq 1) {
 | 
						|
        $statstr = "on";
 | 
						|
    } elsif ($output eq 0) {
 | 
						|
        $statstr = "off";
 | 
						|
    } else {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    return $statstr;
 | 
						|
}
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
 | 
						|
=head3  connectTopdu 
 | 
						|
 | 
						|
   connect pdu via snmp session 
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#-------------------------------------------------------
 | 
						|
sub connectTopdu {
 | 
						|
    my $pdu = shift;
 | 
						|
    my $callback = shift;
 | 
						|
 | 
						|
    my $snmpver = "1";
 | 
						|
    my $community = "public";
 | 
						|
    my $session;
 | 
						|
    my $msg = "connectTopdu";
 | 
						|
    my $versionoid = ".1.3.6.1.4.1.2.6.223.7.3.0";
 | 
						|
 | 
						|
    $session = new SNMP::Session(
 | 
						|
        DestHost       => $pdu,
 | 
						|
        Version        => $snmpver,
 | 
						|
        Community      => $community,
 | 
						|
        UseSprintValue => 1,
 | 
						|
    );
 | 
						|
    unless ($session) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    my $varbind = new SNMP::Varbind([ $versionoid, '' ]);
 | 
						|
    my $pduversion = $session->get($varbind);
 | 
						|
    if ($session->{ErrorStr}) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    $session->{newmib} = 0;
 | 
						|
    if ($pduversion =~ /sLEN/) {
 | 
						|
        $session->{newmib} = 1;
 | 
						|
    }
 | 
						|
 | 
						|
    return $session;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
sub process_sshcfg { 
 | 
						|
    my $noderange = shift;
 | 
						|
    my $subcmd = shift;
 | 
						|
    my $callback = shift;
 | 
						|
 | 
						|
    my $password = "password8";
 | 
						|
    my $userid = "root";
 | 
						|
    my $timeout = 10;
 | 
						|
    my $keyfile = "/root/.ssh/id_rsa.pub";
 | 
						|
    my $rootkey = `cat /root/.ssh/id_rsa.pub`;
 | 
						|
    my $cmd;
 | 
						|
 | 
						|
    my $nodetab = xCAT::Table->new('hosts');
 | 
						|
    my $nodehash = $nodetab->getNodesAttribs($noderange,['ip','otherinterfaces']);
 | 
						|
    
 | 
						|
    foreach my $pdu (@$noderange) {
 | 
						|
        my $msg = " process_sshcfg";
 | 
						|
        xCAT::SvrUtils::sendmsg($msg, $callback, $pdu, %allerrornodes);
 | 
						|
 | 
						|
        #remove old host key from /root/.ssh/known_hosts
 | 
						|
        $cmd = "ssh-keygen -R $pdu";
 | 
						|
        xCAT::Utils->runcmd($cmd, 0);
 | 
						|
 | 
						|
        my $static_ip = $nodehash->{$pdu}->[0]->{ip};
 | 
						|
        my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces};
 | 
						|
        my $ssh_ip;
 | 
						|
 | 
						|
        my $p = Net::Ping->new();
 | 
						|
        if ($p->ping($static_ip)) {
 | 
						|
            $ssh_ip = $static_ip;
 | 
						|
        } elsif ($p->ping($discover_ip)) {
 | 
						|
            $ssh_ip = $discover_ip;
 | 
						|
        } else {
 | 
						|
            $msg = " is not reachable";
 | 
						|
            xCAT::SvrUtils::sendmsg($msg, $callback, $pdu, %allerrornodes);
 | 
						|
            next;
 | 
						|
        }
 | 
						|
 | 
						|
        my ($exp, $errstr) = session_connect($ssh_ip, $userid, $password, $timeout);
 | 
						|
        if (!defined $exp) {
 | 
						|
            $msg = " Failed to connect $errstr";
 | 
						|
            xCAT::SvrUtils::sendmsg($msg, $callback, $pdu, %allerrornodes);
 | 
						|
            next;
 | 
						|
        }
 | 
						|
 | 
						|
        my $ret;
 | 
						|
        my $err;
 | 
						|
 | 
						|
        ($ret, $err) = session_exec($exp, "mkdir -p /home/root/.ssh");
 | 
						|
        ($ret, $err) = session_exec($exp, "chmod 700 /home/root/.ssh");
 | 
						|
        ($ret, $err) = session_exec($exp, "echo \"$rootkey\" >/home/root/.ssh/authorized_keys");
 | 
						|
        ($ret, $err) = session_exec($exp, "chmod 644 /home/root/.ssh/authorized_keys");
 | 
						|
        #config dhcp ip address to static
 | 
						|
        if ($ssh_ip eq $discover_ip) {
 | 
						|
            # ($ret, $err) = session_exec($exp, "ifconfig eth0 $static_ip");
 | 
						|
        }
 | 
						|
 | 
						|
        $exp->hard_close();
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
sub session_connect {
 | 
						|
     my $server   = shift;
 | 
						|
     my $userid   = shift;
 | 
						|
     my $password = shift;
 | 
						|
     my $timeout  = shift;
 | 
						|
 | 
						|
     my $ssh      = Expect->new;
 | 
						|
     my $command     = 'ssh';
 | 
						|
     my @parameters  = ($userid . "@" . $server);
 | 
						|
 | 
						|
     $ssh->debug(0);
 | 
						|
     $ssh->log_stdout(0);    # suppress stdout output..
 | 
						|
     $ssh->slave->stty(qw(sane -echo));
 | 
						|
 | 
						|
     unless ($ssh->spawn($command, @parameters))
 | 
						|
     {
 | 
						|
         my $err = $!;
 | 
						|
         $ssh->soft_close();
 | 
						|
         my $rsp;
 | 
						|
         return(undef, "unable to run command $command $err\n");
 | 
						|
     }
 | 
						|
 | 
						|
     $ssh->expect($timeout,
 | 
						|
                   [ "-re", qr/WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED/, sub {die "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!\n"; } ],
 | 
						|
                   [ "-re", qr/\(yes\/no\)\?\s*$/, sub { $ssh->send("yes\n");  exp_continue; } ],
 | 
						|
                   [ "-re", qr/ password:/,        sub {$ssh->send("$password\n"); exp_continue; } ],
 | 
						|
                   [ "-re", qr/:~\$/,              sub { $ssh->send("sudo su\n"); exp_continue; } ],
 | 
						|
                   [ "-re", qr/.*#/,               sub { $ssh->clear_accum(); } ],
 | 
						|
                   [ timeout => sub { die "No login.\n"; } ]
 | 
						|
                  );
 | 
						|
     $ssh->clear_accum();
 | 
						|
     return ($ssh);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
sub session_exec {
 | 
						|
     my $exp = shift;
 | 
						|
     my $cmd = shift;
 | 
						|
     my $timeout    = shift;
 | 
						|
     my $prompt =  shift;
 | 
						|
 | 
						|
     $timeout = 10 unless defined $timeout;
 | 
						|
     $prompt = qr/.*#/ unless defined $prompt;
 | 
						|
 | 
						|
 | 
						|
     $exp->clear_accum();
 | 
						|
     $exp->send("$cmd\n");
 | 
						|
     my ($mpos, $merr, $mstr, $mbmatch, $mamatch) = $exp->expect(6,  "-re", $prompt);
 | 
						|
 | 
						|
     if (defined $merr) {
 | 
						|
         return(undef,$merr);
 | 
						|
     }
 | 
						|
     return($mbmatch);
 | 
						|
}
 | 
						|
 | 
						|
sub process_pdudiscover {
 | 
						|
    my $request  = shift;
 | 
						|
    my $sub_req  = shift;
 | 
						|
    my $callback = shift;
 | 
						|
    my $extrargs = $request->{arg};
 | 
						|
    my @exargs   = ($request->{arg});
 | 
						|
    if (ref($extrargs)) {
 | 
						|
        @exargs=@$extrargs;
 | 
						|
    }
 | 
						|
 | 
						|
    #check case in GetOptions
 | 
						|
    $Getopt::Long::ignorecase = 0;
 | 
						|
    Getopt::Long::Configure( "bundling" );
 | 
						|
    Getopt::Long::Configure("no_pass_through");
 | 
						|
    my %opt;
 | 
						|
    if (!GetOptions( \%opt,
 | 
						|
                    qw(h|help V|verbose x z w r range=s setup))) {
 | 
						|
        my $usage_string = xCAT::Usage->getUsage($request->{command}->[0]);
 | 
						|
        $callback->({ data => $usage_string });
 | 
						|
        return;
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    push @exargs, "-s snmp --pdu";
 | 
						|
    my $cmd = "switchdiscover @exargs";
 | 
						|
    my $result = xCAT::Utils->runcmd($cmd, 0);
 | 
						|
 | 
						|
    my $rsp = {};
 | 
						|
    push @{ $rsp->{data} }, "$result";
 | 
						|
    xCAT::MsgUtils->message("I", $rsp, $callback);
 | 
						|
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
1;
 |