mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 11:22:27 +00:00 
			
		
		
		
	New perl expect code to replace remoteshell.expect, still to integrate in xdsh
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@10782 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
		
							
								
								
									
										887
									
								
								perl-xCAT/xCAT/RemoteShellExp.pm
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										887
									
								
								perl-xCAT/xCAT/RemoteShellExp.pm
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,887 @@ | ||||
| #!/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: remoteshell.expect | ||||
|    [-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,$ssh_setup_cmd,$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."; | ||||
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1); | ||||
|         next; # go to next node | ||||
|  | ||||
|       } | ||||
|  | ||||
|       # | ||||
|       #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->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();  | ||||
|  | ||||
|       # | ||||
|       #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."; | ||||
|         xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1); | ||||
|         next; # go to next node | ||||
|  | ||||
|       } | ||||
|  | ||||
|       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(); | ||||
|  | ||||
|       # | ||||
|       # 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->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; | ||||
| } | ||||
| #------------------------------------------------------------------------------- | ||||
|  | ||||
| =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; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user