git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@11024 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
		
			
				
	
	
		
			892 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			892 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env perl
 | |
| # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | |
| #
 | |
| 
 | |
| package xCAT::RemoteShellExp;
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| =head1   RemoteShellExp 
 | |
|  Uses perl  Expect to set up ssh passwordless login on the input node list
 | |
|  Called from  xdsh  <nodelist> -K command
 | |
|  It works for node and devices ( such as QLogic Switch).
 | |
|  See man xdsh.
 | |
|  It works for root and non-root userids.
 | |
| 
 | |
|  Environment Variables input to drive the setup:
 | |
| 
 | |
|    DSH_REMOTE_CMD  set to path to remote shell (ssh)
 | |
|      root password must agree on all the nodes
 | |
| 
 | |
|    XCAT_ROOT set to root of xCAT install
 | |
| 
 | |
|    DSH_REMOTE_PASSWORD  - to_user password for -s option  required to sendkeys)
 | |
| 			  Note this is obtained in the xdsh client frontend.
 | |
| 
 | |
|    SSH_SETUP_COMMAND - Command to be sent to the IB switch to setup SSH.
 | |
| 
 | |
|    DSH_FROM_USERID_HOME - The home directory of the userid from
 | |
|                   where the ssh keys will be obtained
 | |
|                   to send
 | |
| 
 | |
|    DSH_FROM_USERID - The userid from where the ssh keys will be obtained
 | |
|                   to send
 | |
|                   to the node,  or generated and then obtained to send to the
 | |
|                   node.
 | |
|    DSH_TO_USERID - The userid on the node where the ssh keys will be updated.
 | |
|    DSH_ENABLE_SSH - Node to node root passwordless ssh will be setup.
 | |
|  
 | |
| 
 | |
|  Usage: remoteshellexp
 | |
|    [-t node list]  test ssh connection to the node 
 | |
|    [-k] Generates the ssh keys needed , for the user on the MN. 
 | |
|    [-s node list]  copies the ssh keys to the nodes 
 | |
| 
 | |
|     exit 0 - good
 | |
|     exit 1 - abort
 | |
|     exit 2 - usage error
 | |
| 
 | |
| Examples:
 | |
| $rc=xCAT::RemoteShellExp->remoteshellexp("k",$callback,$remoteshellcmd); 
 | |
| $rc=xCAT::RemoteShellExp->remoteshellexp("s",$callback,$remoteshellcmd,$nodes); 
 | |
| $rc=xCAT::RemoteShellExp->remoteshellexp("t",$callback,$remoteshellcmd,$nodes); 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| BEGIN
 | |
| {
 | |
|     $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
 | |
|     $::XCATDIR  = $ENV{'XCATDIR'}  ? $ENV{'XCATDIR'}  : '/etc/xcat';
 | |
| }
 | |
| 
 | |
| 
 | |
| use lib "$::XCATROOT/lib/perl";
 | |
| use xCAT::Utils;
 | |
| use Getopt::Long;
 | |
| use xCAT::MsgUtils;
 | |
| use Expect;
 | |
| use strict;
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| sub remoteshellexp 
 | |
| {
 | |
|   my ($class, $flag, $callback, $remoteshell, $nodes) = @_;
 | |
|   my $rc=0;
 | |
|   $::CALLBACK = $callback;
 | |
|   if (!($flag))
 | |
|   {
 | |
|        my $rsp = {};
 | |
|        $rsp->{data}->[0] = 
 | |
|        "No flag provide to remoteshellexp.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 2);
 | |
|         return 2;
 | |
|   }
 | |
| 
 | |
|   if (($flag ne "k") && ($flag ne "t") && ($flag ne "s")) {
 | |
|        my $rsp = {};
 | |
|        $rsp->{data}->[0] = 
 | |
|         "Invalid  flag  $flag provided.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|        return 2;
 | |
|        
 | |
|   }
 | |
| 
 | |
|   # for -s flag must have nodes and a $to_userid password
 | |
|   my $to_user_password;
 | |
|   if ($ENV{'DSH_REMOTE_PASSWORD'}) {
 | |
|      $to_user_password=$ENV{'DSH_REMOTE_PASSWORD'};
 | |
|   } 
 | |
|   if ($flag eq "s"){
 | |
| 	if (!$to_user_password) {
 | |
|        my $rsp = {};
 | |
|        $rsp->{data}->[0] = 
 | |
|         "The DSH_REMOTE_PASSWORD environment variable has not been set to the user id password on the node which will have their ssh keys updated (ususally root).";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|        return 2;
 | |
| 	}
 | |
| 	if (!$nodes) {
 | |
|        my $rsp = {};
 | |
|        $rsp->{data}->[0] = 
 | |
|         "No nodes were input to update the user's ssh keys.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|        return 2;
 | |
| 	}
 | |
|   }
 | |
|   my $ssh_setup_cmd;
 | |
|   my $from_userid;
 | |
|   my $to_userid;
 | |
|   my $home;
 | |
|   my $remotecopy;
 | |
|   # if caller input a path to ssh remote command, use it
 | |
|   if ($ENV{'DSH_REMOTE_CMD'}) {
 | |
|      $remoteshell=$ENV{'DSH_REMOTE_CMD'};
 | |
|   } else {
 | |
|     if (!$remoteshell) {
 | |
|      $remoteshell="/usr/bin/ssh";
 | |
|     }
 | |
|   }
 | |
|   # figure out path to scp
 | |
|   my ($path,$ssh) = split(/ssh/,$remoteshell);
 | |
|   $remotecopy=$path . "scp";
 | |
|   # if caller input the ssh setup command (such as for IB Switch)
 | |
|   if ($ENV{'SSH_SETUP_COMMAND'}) {
 | |
|      $ssh_setup_cmd=$ENV{'SSH_SETUP_COMMAND'};
 | |
|   }
 | |
|   # set User on the Management node that has the ssh keys 
 | |
|   # this id can be a local (non-root) id as well as root 
 | |
|   if ($ENV{'DSH_FROM_USERID'}) {
 | |
|      $from_userid=$ENV{'DSH_FROM_USERID'};
 | |
|   } else {
 | |
|      $from_userid="root";
 | |
|   }
 | |
|   # set User on the node where we will send the keys 
 | |
|   # this id can be a local id as well as root 
 | |
|   if ($ENV{'DSH_TO_USERID'}) {
 | |
|      $to_userid=$ENV{'DSH_TO_USERID'};
 | |
|   } else {
 | |
|      $to_userid="root";
 | |
|   }
 | |
|   # set User home directory to find the ssh public key to send 
 | |
|   # For non-root ids information may not be in /etc/passwd
 | |
|   #  but elsewhere like LDAP 
 | |
|   if ($ENV{'DSH_FROM_USERID_HOME'}) {
 | |
|      $home=$ENV{'DSH_FROM_USERID_HOME'};
 | |
|   } else {
 | |
|      $home=xCAT::Utils->getHomeDir($from_userid);
 | |
|   }
 | |
|   
 | |
|   # This indicates we will generate new ssh keys for the user,
 | |
|   # if they are not already there
 | |
|   my $key="$home/.ssh/id_rsa";
 | |
|   my $key2="$home/.ssh/id_rsa.pub";
 | |
|   # Check to see if empty
 | |
|   if (-z $key) {
 | |
|          my $rsp = {};
 | |
|          $rsp->{data}->[0] = 
 | |
|          "The $key file is empty. Remove it and rerun the command.";
 | |
|          xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|          return 1;
 | |
| 
 | |
|   } 
 | |
|   if (-z $key2) {
 | |
|          my $rsp = {};
 | |
|          $rsp->{data}->[0] = 
 | |
|          "The $key2 file is empty. Remove it and rerun the command.";
 | |
|          xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|          return 1;
 | |
| 
 | |
|   } 
 | |
|   if (($flag eq "k") && (!(-e $key))) 
 | |
|   {
 | |
|      # if the file size of the id_rsa key is 0, tell them to remove it
 | |
|      # and run the command again
 | |
|      $rc=xCAT::RemoteShellExp->gensshkeys;
 | |
|   }
 | |
|   # send ssh keys to the nodes/devices, to setup passwordless ssh 
 | |
|   if ($flag eq "s")
 | |
|   {
 | |
|     if (!($nodes)) {
 | |
|          my $rsp = {};
 | |
|          $rsp->{data}->[0] = 
 | |
|          "There are no nodes defined to update the ssh keys.";
 | |
|          xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|          return 1;
 | |
|     }
 | |
|     if ($ssh_setup_cmd) { # setup ssh on devices
 | |
|      $rc=xCAT::RemoteShellExp->senddeviceskeys($remoteshell,$remotecopy,$to_userid,$to_user_password,$home,$ssh_setup_cmd,$nodes);
 | |
|     } else {  #setup ssh on nodes
 | |
|      $rc=xCAT::RemoteShellExp->sendnodeskeys($remoteshell,$remotecopy,$to_userid,$to_user_password,$home,$nodes);
 | |
|     } 
 | |
|   }
 | |
|   # test ssh setup on the node
 | |
|   if ($flag eq "t")
 | |
|   {
 | |
|      $rc=xCAT::RemoteShellExp->testkeys($remoteshell,$to_userid,$nodes);
 | |
|   }
 | |
|   return $rc;
 | |
| }
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| =head3    gensshkeys 
 | |
| 	
 | |
|       Generates new ssh keys for the input userid on the MN, if they do not
 | |
|       already exist.  Test for id_rsa key existence. 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub gensshkeys 
 | |
| 
 | |
| {
 | |
|     my ($class) = @_;
 | |
|     my $keygen;
 | |
|     my $timeout  = 10;    # sets Expect default timeout, 0 accepts immediately
 | |
|     my $keygen_sent = 0;
 | |
|     my $prompt1   = 'Generating public/private rsa';
 | |
|     my $prompt2   = 'Enter file.*:';
 | |
|     my $prompt3   = 'Enter passphrase.*:';
 | |
|     my $prompt4   = 'Enter same passphrase.*:';
 | |
|     my $expect_log   = undef;
 | |
|     my $debug        = 0;
 | |
|     if ($::VERBOSE)
 | |
|     {
 | |
|         $debug = 1;
 | |
|     }
 | |
|     $keygen = new Expect;
 | |
|     
 | |
|     #  run /usr/bin/ssh-keygen -t rsa
 | |
|     # prompt1   = 'Generating public/private rsa';
 | |
|     # prompt2   = 'Enter file.*:';
 | |
|     # -re "\r"
 | |
|     # prompt3   = 'Enter passphrase.*:';
 | |
|     # -re "\r"
 | |
|     # prompt4   = 'Enter same passphrase.*:';
 | |
|     # -re "\r"
 | |
| 
 | |
| 
 | |
|     # disable command echoing
 | |
|     #$keygen->slave->stty(qw(sane -echo));
 | |
| 
 | |
|     #
 | |
|     # exp_internal(1) sets exp_internal debugging
 | |
|     # to STDERR.
 | |
|     #
 | |
|     #$keygen->exp_internal(1);
 | |
|     $keygen->exp_internal($debug);
 | |
| 
 | |
|     #
 | |
|     # log_stdout(0) prevent the program's output from being shown.
 | |
|     #  turn on if debugging error
 | |
|     #$keygen->log_stdout(1);
 | |
|     $keygen->log_stdout($debug);
 | |
| 
 | |
|     # Run the ssh key gen command
 | |
|     my $spawncmd = "/usr/bin/ssh-keygen -t rsa";
 | |
|     unless ($keygen->spawn($spawncmd))
 | |
|     {
 | |
|        my $rsp = {};
 | |
|        $rsp->{data}->[0] = 
 | |
|         "Unable to run $spawncmd.";
 | |
|        xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|        return 1;
 | |
| 
 | |
|     }
 | |
| 
 | |
|     #
 | |
|     #ssh-keygen prompts starts here 
 | |
|     #
 | |
| 
 | |
|     my @result = $keygen->expect(
 | |
|         $timeout,
 | |
|         [
 | |
|          $prompt1,   # Generating public/private rsa
 | |
|          sub {
 | |
|              $keygen->send("\r");
 | |
|              $keygen->clear_accum();
 | |
|              $keygen->exp_continue();
 | |
|            }
 | |
|         ],
 | |
|         [
 | |
|          $prompt2,  # Enter file.*:
 | |
|          sub {
 | |
|              $keygen->send("\r");
 | |
|              $keygen->clear_accum();
 | |
|              $keygen->exp_continue();
 | |
|            }
 | |
|         ],
 | |
|         [
 | |
|          $prompt3, # Enter passphrase.*
 | |
|          sub {
 | |
|              $keygen->send("\r");
 | |
|              $keygen->clear_accum();
 | |
|              $keygen->exp_continue();
 | |
|            }
 | |
|         ],
 | |
|         [
 | |
|          $prompt4, # Enter same passphrase.
 | |
|          sub {
 | |
|              $keygen->send("\r");
 | |
|              $keygen->clear_accum();
 | |
|              $keygen->exp_continue();
 | |
|            }
 | |
|         ]
 | |
|         );   # end prompts
 | |
|     ##########################################
 | |
|     # Expect error - report and quit
 | |
|     ##########################################
 | |
|     if (defined($result[1]))
 | |
|     {
 | |
|         my $msg = $result[1];
 | |
|         $keygen->soft_close();
 | |
|         if ($msg =~ /status 0/i) { # no error
 | |
|           return 0;
 | |
|         } else {
 | |
|           my $rsp = {};
 | |
|           $rsp->{data}->[0] =  $msg;
 | |
|           xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|           return 1;
 | |
|         }
 | |
| 
 | |
|     } else {
 | |
|       $keygen->soft_close();
 | |
|       return 0;
 | |
|    }
 | |
| }
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| =head3    testkeys 
 | |
| 	
 | |
|       Test to see if the remoteshell setup worked 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub testkeys 
 | |
| 
 | |
| {
 | |
|     my ($class,$remoteshell,$to_userid,$nodes) = @_;
 | |
|     my $testkeys;
 | |
|     my $timeout  = 10;    # sets Expect default timeout, 0 accepts immediately
 | |
|     my $testkeys_sent = 0;
 | |
|     my $prompt1   = 'Are you sure you want to continue connecting (yes/no)?';
 | |
|     my $prompt2   = 'ssword:';
 | |
|     my $prompt3   = 'Permission denied*';
 | |
|     my $prompt4   = 'test.success';
 | |
|     my $expect_log   = undef;
 | |
|     my $debug        = 0;
 | |
|     my $rc=1;   # default to error
 | |
|     if ($::VERBOSE)
 | |
|     {
 | |
|         $debug = 1;
 | |
|     }
 | |
|     $testkeys = new Expect;
 | |
|     
 | |
|     #  run ssh <node> -l to_userid  echo test.success 
 | |
|     # possible return
 | |
|     # bad
 | |
|     ##  Are you sure you want to continue connecting (yes/no)?
 | |
|     ##  *ssword*
 | |
|     ## Permission denied.
 | |
|     # Good
 | |
|     ## test.success
 | |
| 
 | |
|     # disable command echoing
 | |
|     #$testkeys->slave->stty(qw(sane -echo));
 | |
| 
 | |
|     #
 | |
|     # exp_internal(1) sets exp_internal debugging
 | |
|     # to STDERR.
 | |
|     #
 | |
|     #$testkeys->exp_internal(1);
 | |
|     $testkeys->exp_internal($debug);
 | |
| 
 | |
|     #
 | |
|     # log_stdout(0) prevent the program's output from being shown.
 | |
|     #  turn on if debugging error
 | |
|     #$testkeys->log_stdout(1);
 | |
|     $testkeys->log_stdout($debug);
 | |
| 
 | |
|     # Run the ssh key gen command
 | |
|     my $spawncmd = "$remoteshell $nodes -l $to_userid echo test.success";
 | |
|     unless ($testkeys->spawn($spawncmd))
 | |
|     {
 | |
|        my $rsp = {};
 | |
|        $rsp->{data}->[0] = 
 | |
|         "Unable to run $spawncmd.";
 | |
|        xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|        return 1;
 | |
| 
 | |
|     }
 | |
| 
 | |
|     #
 | |
|     #testkeys prompts starts here 
 | |
|     #
 | |
| 
 | |
|     my @result = $testkeys->expect(
 | |
|         $timeout,
 | |
|         [
 | |
|          $prompt1,  # Are you sure you want to ...
 | |
|          sub {
 | |
|              $rc= 1; 
 | |
|              $testkeys->hard_close();         
 | |
|            }
 | |
|         ],
 | |
|         [
 | |
|          $prompt2,  # *ssword*
 | |
|          sub {
 | |
|              $rc= 1; 
 | |
|              $testkeys->hard_close();         
 | |
|            }
 | |
|         ],
 | |
|         [
 | |
|          $prompt3,  # Permission denied
 | |
|          sub {
 | |
|              $rc= 1; 
 | |
|              $testkeys->hard_close();         
 | |
|            }
 | |
|         ],
 | |
|         [
 | |
|          $prompt4, # test.success
 | |
|          sub {
 | |
|              $rc= 0; 
 | |
|            }
 | |
|         ]
 | |
|         );   # end prompts
 | |
|     ##########################################
 | |
|     # Expect error - report and quit
 | |
|     ##########################################
 | |
|     if (defined($result[1]))
 | |
|     {
 | |
|         my $msg = $result[1];
 | |
|         $testkeys->soft_close();
 | |
|         if ($msg =~ /status 0/i) { # no error
 | |
|           return 0;
 | |
|         } else {
 | |
|           my $rsp = {};
 | |
|           $rsp->{data}->[0] =  $msg;
 | |
|           xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|           return 1;
 | |
|         }
 | |
| 
 | |
|     } else {
 | |
|       $testkeys->soft_close();
 | |
|       return $rc;
 | |
|    }
 | |
| }
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    sendnodeskeys 
 | |
| 	
 | |
|       Setup the ssh keys on the nodes 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub sendnodeskeys 
 | |
| 
 | |
| {
 | |
|    my ($class,$remoteshell,$remotecopy,$to_userid,$to_userpassword,$home,$nodes) = @_;
 | |
|     my $sendkeys;
 | |
|     my $timeout  = 10;    # sets Expect default timeout, 0 accepts immediately
 | |
|     my $sendkeys_sent = 0;
 | |
|     my $prompt1   = 'Are you sure you want to continue connecting (yes/no)?';
 | |
|     my $prompt2   = 'ssword:';
 | |
|     my $prompt3   = 'Permission denied*';
 | |
|     my $expect_log   = undef;
 | |
|     my $debug        = 0;
 | |
|     my $rc=0;  
 | |
|     if ($::VERBOSE)
 | |
|     {
 | |
|         $debug = 1;
 | |
|     }
 | |
|     # For each node
 | |
|     #  make a temporary directory on the node
 | |
|     #  run scp <nodename> -l <to user> /bin/mkdir -p /tmp/$to_userid/.ssh 
 | |
|     #  xdsh has built an authorized_keys file for the node 
 | |
|     #  in $HOME/.ssh/tmp/authorized_keys 
 | |
|     #  copy to the node to the temp directory 
 | |
|     #  scp $HOME/.ssh/tmp/authorized_keys to_userid@<node>:/tmp/$to_userid/.ssh
 | |
|     #  If you are going to enable ssh to ssh between nodes, then
 | |
|     #  scp $HOME/.ssh/id_rsa to that temp directory on the node
 | |
|     #  copy the script $HOME/.ssh/copy.sh to the node, it will do the 
 | |
|     #  the work of setting up the user's ssh keys  and clean up
 | |
|     #  ssh (run)  copy.sh on the node
 | |
|     my @nodelist=split(/,/,$nodes);
 | |
|     foreach my $node (@nodelist) {
 | |
|       $sendkeys = new Expect;
 | |
| 
 | |
|       # disable command echoing
 | |
|       #$sendkeys->slave->stty(qw(sane -echo));
 | |
|       #
 | |
|       # exp_internal(1) sets exp_internal debugging
 | |
|       # to STDERR.
 | |
|       #
 | |
|       #$sendkeys->exp_internal(1);
 | |
|       $sendkeys->exp_internal($debug);
 | |
|       #
 | |
|       # log_stdout(0) prevent the program's output from being shown.
 | |
|       #  turn on if debugging error
 | |
|       #$sendkeys->log_stdout(1);
 | |
|       $sendkeys->log_stdout($debug);
 | |
|    
 | |
|       # command to make the temp directory on the node 
 | |
|       my $spawnmkdir=
 | |
|       "$remoteshell $node -l $to_userid /bin/mkdir -p /tmp/$to_userid/.ssh";  
 | |
|       # command to copy the needed files to the node
 | |
|     
 | |
|       # send mkdir command 
 | |
|       unless ($sendkeys->spawn($spawnmkdir))
 | |
|       {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = 
 | |
|          "Unable to run $spawnmkdir on $node";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|         next;
 | |
|       }
 | |
| 
 | |
|       #
 | |
|       #mkdir prompts starts here 
 | |
|       #
 | |
| 
 | |
|       my @result = $sendkeys->expect(
 | |
|         $timeout,
 | |
|         [
 | |
|          $prompt1,  # Are you sure you want to ...
 | |
|          sub {
 | |
|              $sendkeys->send("yes\r");
 | |
|              $sendkeys->clear_accum();
 | |
|              $sendkeys->exp_continue();
 | |
|            }
 | |
|         ],
 | |
|         [
 | |
|          $prompt2,  # *ssword*
 | |
|          sub {
 | |
|              $sendkeys->send("$to_userpassword\r");
 | |
|              $sendkeys->clear_accum();
 | |
|              $sendkeys->exp_continue();
 | |
|            }
 | |
|         ],
 | |
|         [
 | |
|          $prompt3,  # Permission denied
 | |
|          sub {
 | |
|              $rc= 1; 
 | |
|              $sendkeys->hard_close(); 
 | |
|            }
 | |
|         ],
 | |
|         );   # end prompts
 | |
|         ##########################################
 | |
|         # Expect error - report 
 | |
|         ##########################################
 | |
|         if (defined($result[1]))
 | |
|         {
 | |
|             my $msg = $result[1];
 | |
|            if ($msg =~ /status 0/i) { # no error
 | |
|               $rc=0;
 | |
|             } else {
 | |
|                if ($msg =~ /2:EOF/i) { # no error
 | |
|                   $rc=0;
 | |
|                } else {
 | |
|                  my $rsp = {};
 | |
|                  $rsp->{data}->[0] =  "mkdir:$node has error,$msg";
 | |
|                  xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|                  $rc=1;
 | |
|                }
 | |
|             }
 | |
|         }
 | |
|       $sendkeys->soft_close(); 
 | |
| 
 | |
|       #
 | |
|       #copy files prompts starts here 
 | |
|       #
 | |
| 
 | |
|       $sendkeys = new Expect;
 | |
| 
 | |
|       # disable command echoing
 | |
|       #$sendkeys->slave->stty(qw(sane -echo));
 | |
|       #
 | |
|       # exp_internal(1) sets exp_internal debugging
 | |
|       # to STDERR.
 | |
|       #
 | |
|       #$sendkeys->exp_internal(1);
 | |
|       $sendkeys->exp_internal($debug);
 | |
|       #
 | |
|       # log_stdout(0) prevent the program's output from being shown.
 | |
|       #  turn on if debugging error
 | |
|       #$sendkeys->log_stdout(1);
 | |
|       $sendkeys->log_stdout($debug);
 | |
| 
 | |
|       my $spawncopyfiles;
 | |
|       if ($ENV{'DSH_ENABLE_SSH'}) { # we will enable node to node ssh 
 | |
|          $spawncopyfiles=
 | |
|         "$remotecopy $home/.ssh/id_rsa $home/.ssh/copy.sh $home/.ssh/tmp/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh "; 
 | |
|           
 | |
|       } else {    # no node to node ssh ( don't send private key)
 | |
|          $spawncopyfiles=
 | |
|         "$remotecopy $home/.ssh/copy.sh $home/.ssh/tmp/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh "; 
 | |
|       }
 | |
|       # send copy command 
 | |
|       unless ($sendkeys->spawn($spawncopyfiles))
 | |
|       {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = 
 | |
|          "Unable to run $spawncopyfiles on $node.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|         next; 
 | |
|       }
 | |
| 
 | |
|       my @result = $sendkeys->expect(
 | |
|         $timeout,
 | |
|         [
 | |
|          $prompt1,  # Are you sure you want to ...
 | |
|          sub {
 | |
|              $sendkeys->send("yes\r");
 | |
|              $sendkeys->clear_accum();
 | |
|              $sendkeys->exp_continue();
 | |
|            }
 | |
|         ],
 | |
|         [
 | |
|          $prompt2,  # *ssword*
 | |
|          sub {
 | |
|              $sendkeys->send("$to_userpassword\r");
 | |
|              $sendkeys->clear_accum();
 | |
|              $sendkeys->exp_continue();
 | |
|            }
 | |
|         ],
 | |
|         [
 | |
|          $prompt3,  # Permission denied
 | |
|          sub {
 | |
|              $rc= 1; 
 | |
|              $sendkeys->hard_close(); 
 | |
|              
 | |
|            }
 | |
|         ],
 | |
|         );   # end prompts
 | |
|         ##########################################
 | |
|         # Expect error - report 
 | |
|         ##########################################
 | |
|         if (defined($result[1]))
 | |
|         {
 | |
|             my $msg = $result[1];
 | |
|             if ($msg =~ /status 0/i) { # no error
 | |
|               $rc=0;
 | |
|             } else {
 | |
|                if ($msg =~ /2:EOF/i) { # no error
 | |
|                   $rc=0;
 | |
|                } else {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{data}->[0] =  "copykeys:$node has error,$msg";
 | |
|                 xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|                 $rc=1;
 | |
|               }
 | |
|             }
 | |
|         }
 | |
|         $sendkeys->soft_close();
 | |
| 
 | |
|       #
 | |
|       # ssh to the node to run  the copy.sh to setup the keys starts here
 | |
|       #
 | |
|       $sendkeys = new Expect;
 | |
| 
 | |
|       # disable command echoing
 | |
|       #$sendkeys->slave->stty(qw(sane -echo));
 | |
|       #
 | |
|       # exp_internal(1) sets exp_internal debugging
 | |
|       # to STDERR.
 | |
|       #
 | |
|       #$sendkeys->exp_internal(1);
 | |
|       $sendkeys->exp_internal($debug);
 | |
|       #
 | |
|       # log_stdout(0) prevent the program's output from being shown.
 | |
|       #  turn on if debugging error
 | |
|       #$sendkeys->log_stdout(1);
 | |
|       $sendkeys->log_stdout($debug);
 | |
|    
 | |
|       # command to run copy.sh 
 | |
|       my $spawnruncopy=
 | |
|       "$remoteshell $node -l $to_userid /tmp/$to_userid/.ssh/copy.sh";  
 | |
|     
 | |
|       # send mkdir command 
 | |
|       unless ($sendkeys->spawn($spawnruncopy))
 | |
|       {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = 
 | |
|          "Unable to run $spawnruncopy.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|         next; # go to next node
 | |
| 
 | |
|       }
 | |
| 
 | |
|       #
 | |
|       #run copy.sh prompts starts here 
 | |
|       #
 | |
| 
 | |
|       my @result = $sendkeys->expect(
 | |
|         $timeout,
 | |
|         [
 | |
|          $prompt1,  # Are you sure you want to ...
 | |
|          sub {
 | |
|              $sendkeys->send("yes\r");
 | |
|              $sendkeys->clear_accum();
 | |
|              $sendkeys->exp_continue();
 | |
|            }
 | |
|         ],
 | |
|         [
 | |
|          $prompt2,  # *ssword*
 | |
|          sub {
 | |
|              $sendkeys->send("$to_userpassword\r");
 | |
|              $sendkeys->clear_accum();
 | |
|              $sendkeys->exp_continue();
 | |
|            }
 | |
|         ],
 | |
|         [
 | |
|          $prompt3,  # Permission denied
 | |
|          sub {
 | |
|              $rc= 1; 
 | |
|              $sendkeys->hard_close(); 
 | |
|            }
 | |
|         ],
 | |
|         );   # end prompts
 | |
|         ##########################################
 | |
|         # Expect error - report 
 | |
|         ##########################################
 | |
|         if (defined($result[1]))
 | |
|         {
 | |
|             my $msg = $result[1];
 | |
|             if ($msg =~ /status 0/i) { # no error
 | |
|               $rc=0;
 | |
|             } else {
 | |
|                if ($msg =~ /2:EOF/i) { # no error
 | |
|                   $rc=0;
 | |
|                } else {
 | |
|                  my $rsp = {};
 | |
|                  $rsp->{data}->[0] =  "copy.sh:$node has error,$msg";
 | |
|                  xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|                  $rc=1;
 | |
|               }
 | |
|             }
 | |
|         }
 | |
|       $sendkeys->soft_close(); 
 | |
| 
 | |
| 
 | |
|   }  # end foreach node
 | |
|   return $rc;
 | |
| }
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    senddeviceskeys 
 | |
| 	
 | |
|       Setup the ssh keys on the nodes 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-----------------------------------------------------------------------------
 | |
| 
 | |
| sub senddeviceskeys 
 | |
| 
 | |
| {
 | |
|    my ($class,$remoteshell,$remotecopy,$to_userid,$to_userpassword,$home,$ssh_setup_cmd,$nodes) = @_;
 | |
|     my $sendkeys;
 | |
|     my $timeout  = 10;    # sets Expect default timeout, 0 accepts immediately
 | |
|     my $sendkeys_sent = 0;
 | |
|     my $prompt1   = 'Are you sure you want to continue connecting (yes/no)?';
 | |
|     my $prompt2   = 'ssword:';
 | |
|     my $prompt3   = 'Permission denied*';
 | |
|     my $expect_log   = undef;
 | |
|     my $debug        = 0;
 | |
|     my $rc=0;  
 | |
|     if ($::VERBOSE)
 | |
|     {
 | |
|         $debug = 1;
 | |
|     }
 | |
|     
 | |
|     # quote the setup command and key "sshKey add \"<key\""
 | |
|     my $setupcmd="\"";
 | |
|     $setupcmd .= $ssh_setup_cmd;
 | |
|     $setupcmd .=" ";
 | |
|     
 | |
|     # get the public key
 | |
|     my $key="\\";
 | |
|     $key .="\"";
 | |
|     $key .=`cat $home/.ssh/tmp/authorized_keys  `;
 | |
|     chop ($key);
 | |
|     $key .="\\";
 | |
|     $key .="\"";
 | |
|     # add to the command
 | |
|     $setupcmd .=$key; 
 | |
|     $setupcmd .="\"";
 | |
|     # For each input device
 | |
|     my @nodelist=split(/,/,$nodes);
 | |
|     foreach my $node (@nodelist) {
 | |
|       #
 | |
|       # ssh to the node to run  the copy.sh to setup the keys starts here
 | |
|       #
 | |
|       $sendkeys = new Expect;
 | |
| 
 | |
|       # disable command echoing
 | |
|       #$sendkeys->slave->stty(qw(sane -echo));
 | |
|       #
 | |
|       # exp_internal(1) sets exp_internal debugging
 | |
|       # to STDERR.
 | |
|       #
 | |
|       #$sendkeys->exp_internal(1);
 | |
|       $sendkeys->exp_internal($debug);
 | |
|       #
 | |
|       # log_stdout(0) prevent the program's output from being shown.
 | |
|       #  turn on if debugging error
 | |
|       #$sendkeys->log_stdout(1);
 | |
|       $sendkeys->log_stdout($debug);
 | |
|    
 | |
|       # command to send key to the device
 | |
|       # sshKey add "key" 
 | |
|       my $spawnaddkey=
 | |
|       "$remoteshell $node -l $to_userid $setupcmd ";  
 | |
|     
 | |
|       # send mkdir command 
 | |
|       unless ($sendkeys->spawn($spawnaddkey))
 | |
|       {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = 
 | |
|          "Unable to run $spawnaddkey.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1);
 | |
|         next; # go to next node
 | |
| 
 | |
|       }
 | |
| 
 | |
|       #
 | |
|       #run copy.sh prompts starts here 
 | |
|       #
 | |
| 
 | |
|       my @result = $sendkeys->expect(
 | |
|         $timeout,
 | |
|         [
 | |
|          $prompt1,  # Are you sure you want to ...
 | |
|          sub {
 | |
|              $sendkeys->send("yes\r");
 | |
|              $sendkeys->clear_accum();
 | |
|              $sendkeys->exp_continue();
 | |
|            }
 | |
|         ],
 | |
|         [
 | |
|          $prompt2,  # *ssword*
 | |
|          sub {
 | |
|              $sendkeys->send("$to_userpassword\r");
 | |
|              $sendkeys->clear_accum();
 | |
|              $sendkeys->exp_continue();
 | |
|            }
 | |
|         ],
 | |
|         [
 | |
|          $prompt3,  # Permission denied
 | |
|          sub {
 | |
|              $rc= 1; 
 | |
|              $sendkeys->soft_close(); 
 | |
|              next; # go to next node
 | |
|            }
 | |
|         ],
 | |
|         );   # end prompts
 | |
|         ##########################################
 | |
|         # Expect error - report 
 | |
|         ##########################################
 | |
|         if (defined($result[1]))
 | |
|         {
 | |
|             my $msg = $result[1];
 | |
|             if ($msg =~ /status 0/i) { # no error
 | |
|               $rc=0;
 | |
|             } else {
 | |
|               my $rsp = {};
 | |
|               $rsp->{data}->[0] =  "$node has error,$msg";
 | |
|               xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
 | |
|               $rc=1;
 | |
|               next; # go to next node
 | |
|             }
 | |
|         }
 | |
|       $sendkeys->soft_close(); 
 | |
|     } # end foreach node
 | |
|     return $rc;
 | |
| }
 | |
| 1;
 | |
| 
 |