added support for xdsh to ethernet switches

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@14318 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
linggao 2012-11-13 22:03:57 +00:00
parent 5855408946
commit 92414fbcd1
6 changed files with 297 additions and 37 deletions

View File

@ -2,6 +2,11 @@
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT::DSHCLI;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use File::Basename;
@ -662,7 +667,7 @@ sub _execute_dsh
if !$signal_interrupt_flag;
}
elsif (!defined($target_rc) && !$dsh_cmd_background && ($::DSH_MELLANOX_SWITCH==0))
elsif (!defined($target_rc) && !$dsh_cmd_background && ($::DSH_MELLANOX_SWITCH==0) && ($$options{'devicetype'}!~ /EthSwitch/))
{
# report error status --nodestatus
# Note the message below for node status must
@ -976,6 +981,32 @@ sub fork_fanout_dsh
)
= @_;
#get username and passeword for ether net switches (EthSwitch type)
if ($$options{'devicetype'} =~ /EthSwitch/) {
if (@$targets_waiting > 0) {
if ($ENV{'DSH_REMOTE_PASSWORD'}) {
foreach my $t (keys(%$resolved_targets)) {
$resolved_targets->{$t}->{'password'}=$ENV{'DSH_REMOTE_PASSWORD'};
$resolved_targets->{$t}->{'user'}=$$options{'user'};
}
} else {
#get user name and password from the switches table
my $switchestab=xCAT::Table->new('switches',-create=>0);
my $switchents = $switchestab->getNodesAttribs($targets_waiting,[qw/switch sshusername sshpassword/]);
foreach my $entry (values %$switchents) {
my $switch=$entry->[0]->{switch};
if (defined($entry->[0]->{sshusername})) {
$resolved_targets->{$switch}->{'user'}=$entry->[0]->{sshusername};
}
if (defined($entry->[0]->{sshpassword})) {
$resolved_targets->{$switch}->{'password'}=$entry->[0]->{sshpassword};
}
}
}
}
}
while (@$targets_waiting
&& (keys(%$targets_active) < $$options{'fanout'}))
{
@ -1041,6 +1072,12 @@ sub fork_fanout_dsh
|| $$options{'node-rsh-defaults'}{$context};
($remote_shell =~ /\/ssh$/) && ($rsh_extension = 'SSH');
if ($$options{'devicetype'} =~ /EthSwitch/) {
$remote_shell = "$::XCATROOT/sbin/rshell_api";
$rsh_extension='RShellAPI';
$rsh_config{'password'}=$$target_properties{'password'};
}
# will not set -n for any command, causing problems
# with running xdsh to install rpms and start xcatd on AIX
# if IB switch device, do not set -n, causes no returncode

View File

@ -0,0 +1,181 @@
#!/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;

View File

@ -39,47 +39,48 @@ sub _startssh {
}
sub new {
my $class = shift;
my %args = @_;
my $pty = IO::Pty->new or die "Unable to perform ssh: $!";
$args{"-fhopen"} = $pty;
$args{"-telnetmode"} = 0;
$args{"-telnetmode"} = 0;
$args{"-cmd_remove_mode"} = 1;
my $username = $args{"-username"};
my $host = $args{"-host"};
my $password = $args{"-password"};
delete $args{"-host"};
delete $args{"-username"};
delete $args{"-password"};
my $nokeycheck = $args{"-nokeycheck"};
delete $args{"-nokeycheck"};
my $self = $class->Net::Telnet::new(%args);
_startssh($self,$pty,$username,$host,"-nokeycheck"=>$nokeycheck);
my $promptex = $args{Prompt};
$promptex =~ s!^/!!;
$promptex =~ s!/\z!!;
my $class = shift;
my %args = @_;
my $pty = IO::Pty->new or die "Unable to perform ssh: $!";
$args{"-fhopen"} = $pty;
$args{"-telnetmode"} = 0;
$args{"-telnetmode"} = 0;
$args{"-cmd_remove_mode"} = 1;
my $username = $args{"-username"};
my $host = $args{"-host"};
my $password = $args{"-password"};
delete $args{"-host"};
delete $args{"-username"};
delete $args{"-password"};
my $nokeycheck = $args{"-nokeycheck"};
delete $args{"-nokeycheck"};
my $self = $class->Net::Telnet::new(%args);
_startssh($self,$pty,$username,$host,"-nokeycheck"=>$nokeycheck);
my $promptex = $args{Prompt};
$promptex =~ s!^/!!;
$promptex =~ s!/\z!!;
my ($prematch,$match) = $self->waitfor(Match => $args{Prompt},Match=>'/password:/i',Match=>'/REMOTE HOST IDENTIFICATION HAS CHANGED/') or die "Login Failed:", $self->lastline;
#print "prematch=$prematch, match=$match\n";
if ($match =~ /password:/i) {
#$self->waitfor("-match" => '/password:/i', -errmode => "return") or die "Unable to reach host ",$self->lastline;
$self->print($password);
my $nextline = $self->getline();
chomp($nextline);
while ($nextline =~ /^\s*$/) {
$nextline = $self->get();
chomp($nextline);
}
if ($nextline =~ /^password:/ or $nextline =~ /Permission denied, please try again/) {
die "Incorrect Password";
} elsif ($nextline =~ /$promptex/) {
*$self->{_xcatsshinteract}->{_atprompt}=1;
}
#$self->waitfor("-match" => '/password:/i', -errmode => "return") or die "Unable to reach host ",$self->lastline;
$self->print($password);
my $nextline = $self->getline();
chomp($nextline);
while ($nextline =~ /^\s*$/) {
$nextline = $self->get();
chomp($nextline);
}
if ($nextline =~ /password:/i or $nextline =~ /Permission denied, please try again/ or $nextline =~ /disconnect from/) {
die "Incorrect Password";
} elsif ($nextline =~ /$promptex/) {
*$self->{_xcatsshinteract}->{_atprompt}=1;
}
} elsif ($match =~ /$promptex/) {
*$self->{_xcatsshinteract}->{_atprompt}=1;
} elsif ($match =~ /REMOTE HOST IDENTIFICATION HAS CHANGED/){
die "Known_hosts issue";
}
return bless($self,$class);
die "Known_hosts issue";
}
return bless($self,$class);
}
sub atprompt {
my $self=shift;

33
xCAT-server/sbin/rshell_api Executable file
View File

@ -0,0 +1,33 @@
#!/usr/bin/env perl
# IBM(c) 2012 EPL license http://www.eclipse.org/legal/epl-v10.html
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use Getopt::Long;
use xCAT::RShellAPI;
Getopt::Long::Configure("require_order");
Getopt::Long::Configure("no_pass_through");
my $username;
my $passwd;
my $help;
if (!GetOptions(
'l|loginname=s' => \$username,
'p|password=s' => \$passwd,
'h|help' => \$help,
) || $help || scalar(@ARGV)<2 ) {
print "Usage: rshell_api [-l <user>] [-p <passwrd>] <node> <command>\n";
exit;
}
my $node = $ARGV[0];
xCAT::RShellAPI::run_remote_shell_api($node, $username, $passwd, @ARGV[1 .. $#ARGV]);
exit 0;

View File

@ -0,0 +1,5 @@
[main]
ssh-setup-command=
[xdsh]
pre-command=NULL
post-command=NULL

View File

@ -80,6 +80,7 @@ mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/xcat/ib/netboot/sles
mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/xcat/ib/netboot/rh
mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/xcat/ib/scripts/Mellanox
mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/xcat/ib/scripts/QLogic
mkdir -p $RPM_BUILD_ROOT/%{prefix}/share/xcat/EthSwitch
mkdir -p $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_plugin
mkdir -p $RPM_BUILD_ROOT/%{prefix}/xdsh/Context
mkdir -p $RPM_BUILD_ROOT/%{prefix}/lib/perl/xCAT_monitoring/samples
@ -122,6 +123,8 @@ cp share/xcat/cons/* $RPM_BUILD_ROOT/%{prefix}/share/xcat/cons
cp -r share/xcat/ib/scripts/* $RPM_BUILD_ROOT/%{prefix}/share/xcat/ib/scripts
cp share/xcat/ib/netboot/sles/* $RPM_BUILD_ROOT/%{prefix}/share/xcat/ib/netboot/sles
cp share/xcat/ib/netboot/rh/* $RPM_BUILD_ROOT/%{prefix}/share/xcat/ib/netboot/rh
cp share/xcat/EthSwitch/* $RPM_BUILD_ROOT/%{prefix}/share/xcat/EthSwitch
chmod 755 $RPM_BUILD_ROOT/%{prefix}/share/xcat/cons/*
chmod 755 $RPM_BUILD_ROOT/%{prefix}/share/xcat/ib/scripts/*
chmod 755 $RPM_BUILD_ROOT/%{prefix}/share/xcat/ib/netboot/sles/*