xcat-core/xCAT-server/lib/perl/xCAT/RShellAPI.pm

182 lines
4.7 KiB
Perl
Raw Normal View History

#!/usr/bin/perl
# IBM(c) 2012 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT::RShellAPI;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use xCAT::MsgUtils;
#######################################################
=head3
remote_shell_command
This routine constructs an remote shell command using the
given arguments
Arguments:
$class - Calling module name (discarded)
$config - Reference to remote shell command configuration hash table
$exec_path - Path to ssh executable
Returns:
A command array for the ssh command with the appropriate
arguments as defined in the $config hash table
=cut
#####################################################
sub remote_shell_command {
my ( $class, $config, $exec_path ) = @_;
my @command = ();
push @command, $exec_path;
if ( $$config{'options'} ) {
my @options = split ' ', $$config{'options'};
push @command, @options;
}
my @tmp;
if ($$config{'user'} && ($$config{'user'} !~ /^none$/i)) {
@tmp=split(' ', "-l $$config{'user'}");
push @command, @tmp;
}
if ($$config{'password'} && ($$config{'password'} !~ /^none$/i)) {
@tmp=split(' ', "-p $$config{'password'}");
push @command, @tmp;
}
push @command, "$$config{'hostname'}";
push @command, $$config{'command'};
return @command;
}
sub run_remote_shell_api {
require xCAT::SSHInteract;
my $node=shift;
my $user=shift;
my $passwd=shift;
my $args = join(" ", @_);
my $t;
if(0) {
print "start SSH session...\n";
$t = new xCAT::SSHInteract(
-username=>$user,
-password=>$passwd,
-host=>$node,
-nokeycheck=>1,
-output_record_separator=>"\r",
Timeout=>5,
Errmode=>'return',
Prompt=>'/.*[\>\#]$/',
);
};
my $errmsg=$@;
$errmsg =~ s/ at (.*) line (\d)+//g;
print "$errmsg\n";
my $rc=1;
if (not $t) {#ssh failed.. fallback to a telnet attempt
print "start Telnet session...\n";
require Net::Telnet;
$t = new Net::Telnet(
Timeout=>5,
Errmode=>'return',
Prompt=>'/.*[\>\#]$/',
);
$rc = $t->open($node);
if ($rc) {
my $pw_tried=0;
my ($prematch, $match)= $t->waitfor(Match => '/login[: ]*$/i',
Match => '/username[: ]*$/i',
Match => '/password[: ]*$/i',
Errmode => "return");
if (($match =~ /username[: ]*$/i) || ($match =~ /login[: ]*$/i )) {
# user name
if ($user) {
if (! $t->put(String => "$user\n",
Errmode => "return")) {
print "login disconnected\n";
return [1, "login disconnected"];
}
} else {
print "Username is required.\n";
return [1, "Username is required."];
}
} elsif ($match =~ /password[: ]*$/i) {
if ($passwd) {
$pw_tried=1;
if (! $t->put(String => "$passwd\n",
Errmode => "return")) {
print "login disconnected\n";
return [1, "login disconnected"];
}
} else {
print "password is required.\n";
return [1, "Passwordis required."];
}
}
($prematch, $match)= $t->waitfor(Match => '/login[: ]*$/i',
Match => '/username[: ]*$/i',
Match => '/password[: ]*$/i',
Errmode => "return");
if (($match =~ /username[: ]*$/i) || ($match =~ /login[: ]*$/i )) {
print "Incorrect username.\n";
return [1, "Incorrect username."];
} elsif ($match =~ /password[: ]*$/i) {
if ($pw_tried) {
print "Incorrect password.\n";
return [1, "Incorrect password."];
}
if ($passwd) {
if (! $t->put(String => "$passwd\n",
Errmode => "return")) {
print "login disconnected\n";
return [1, "login disconnected"];
}
} else {
print "password is required.\n";
return [1, "Passwordis required."];
}
}
#Wait for command prompt
($prematch, $match) = $t->waitfor(Match => '/login[: ]*$/i',
Match => '/username[: ]*$/i',
Match => '/password[: ]*$/i',
Match => '/\>/',
Errmode => "return");
#print "prematch=$prematch, match=$match\n";
if ($match =~ /login[: ]*$/i or $match =~ /username[: ]*$/i or $match =~ /password[: ]*$/i) {
print "login failed: bad login name or password\n";
return [1, "login failed: bad login name or password"];
}
}
}
if (!$rc) {
print "Error: " . $t->errmsg . "\n";
return([1, $t->errmsg]);
}
$rc = 0;
my $output;
my @cmd_array=split(';', $args);
foreach my $cmd (@cmd_array) {
#my @data = $t->cmd($cmd);
my @data= $t->cmd(String =>$cmd);
$output .= "command:$cmd\n@data\n";
print "command:$cmd\n@data\n";
}
$t->close();
return [0, $output];
}
1;