mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-11-03 21:02:34 +00:00 
			
		
		
		
	git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@2721 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
		
			
				
	
	
		
			438 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			438 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
#!/usr/bin/expect --
 | 
						|
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | 
						|
#
 | 
						|
#
 | 
						|
# sets up ssh on the input node list
 | 
						|
# called from by xdsh  <nodelist> -K command 
 | 
						|
# Environment Variables:
 | 
						|
#
 | 
						|
#   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  - user password for -s option 
 | 
						|
#
 | 
						|
#   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. 
 | 
						|
#
 | 
						|
# Usage: remoteshell.expect 
 | 
						|
#   [-t remote_shell hostname]  test the remoteshell on the host
 | 
						|
#   [-k] Generates the ssh keys needed 
 | 
						|
#   [-s node_list]  copies the ssh keys to the nodes
 | 
						|
#   [-h ] usage
 | 
						|
#
 | 
						|
#    exit 0 - good
 | 
						|
#    exit 1 - abort
 | 
						|
#    exit 2 - usage error
 | 
						|
#
 | 
						|
#
 | 
						|
################################################################################
 | 
						|
 | 
						|
#
 | 
						|
################################################################################
 | 
						|
 | 
						|
set timeout 80
 | 
						|
log_user 0
 | 
						|
 | 
						|
#Clear xdsh environment variables
 | 
						|
 | 
						|
set empty ""
 | 
						|
 | 
						|
# path to remote command
 | 
						|
if { [info exists env(DSH_REMOTE_CMD)] } {
 | 
						|
   set remoteshell $env(DSH_REMOTE_CMD)
 | 
						|
} else {
 | 
						|
   set remoteshell "/usr/bin/ssh"
 | 
						|
}
 | 
						|
if { [info exists env(XCATROOT)] } {
 | 
						|
	set xcatroot $env(XCATROOT)
 | 
						|
} else {
 | 
						|
	set xcatroot "/opt/xcat" 
 | 
						|
}
 | 
						|
 | 
						|
if { [info exists env(SSH_SETUP_COMMAND)] } {
 | 
						|
    set ssh_setup_cmd $env(SSH_SETUP_COMMAND)
 | 
						|
} else {
 | 
						|
    set ssh_setup_cmd ""
 | 
						|
}
 | 
						|
# User on the Management node that has the ssh keys
 | 
						|
if { [info exists env(DSH_FROM_USERID)] } {
 | 
						|
    set from_userid $env(DSH_FROM_USERID)
 | 
						|
} else {
 | 
						|
    set from_userid "root"
 | 
						|
}
 | 
						|
 | 
						|
# User on the node where we will send the ssh keys
 | 
						|
if { [info exists env(DSH_TO_USERID)] } {
 | 
						|
    set to_userid $env(DSH_TO_USERID)
 | 
						|
} else {
 | 
						|
    set to_userid "root"
 | 
						|
}
 | 
						|
 | 
						|
# get the from userid and its home directory to get the ssh keys
 | 
						|
 | 
						|
#set home [exec /usr/bin/perl -e {$user = $ENV{'DSH_FROM_USERID'} ? $ENV{'DSH_FROM_USERID'} : "root"; @info = getpwnam($user); print $info[7] . "\n";}]
 | 
						|
 | 
						|
#if { [string compare $home $empty] ==0 } {
 | 
						|
#set home $env(HOME)
 | 
						|
#}
 | 
						|
set home $env(DSH_FROM_USERID_HOME)
 | 
						|
 | 
						|
#
 | 
						|
# check input arguments
 | 
						|
#
 | 
						|
if { [llength $argv] != 0 } {
 | 
						|
   if { [string compare "-h" [lindex $argv 0]] ==0 } {  # usage
 | 
						|
 | 
						|
     puts "Usage: remoteshell.expect" 
 | 
						|
     puts "  -t remote_shell hostname - test the remoteshell on the host"
 | 
						|
     puts "  -k Generates the ssh keys needed" 
 | 
						|
     puts "  -s node_list  - copies keys to the nodes"
 | 
						|
     puts "  -h  usage"
 | 
						|
     exit 0
 | 
						|
    }
 | 
						|
	# -t means test to see if the shell is already setup
 | 
						|
	if { [string compare "-t" [lindex $argv 0]] ==0 } {
 | 
						|
		set env(LC_ALL) "C"
 | 
						|
 | 
						|
		set pid [ spawn [lindex $argv 1] [lindex $argv 2] -l $to_userid echo test.success ]
 | 
						|
		expect {
 | 
						|
			timeout { exit 1 }
 | 
						|
			"Are you sure you want to continue connecting (yes/no)?" {
 | 
						|
				exec /bin/kill $pid
 | 
						|
				exit 1
 | 
						|
			}
 | 
						|
			"*ssword*" {
 | 
						|
				exec /bin/kill $pid               		
 | 
						|
				exit 1
 | 
						|
			}
 | 
						|
			"Permission denied." {
 | 
						|
				exit 1
 | 
						|
			}
 | 
						|
			"test.success" { 
 | 
						|
				exit 0 
 | 
						|
			}
 | 
						|
		}
 | 
						|
		exit 1
 | 
						|
	} elseif { [string compare "-k" [lindex $argv 0]] ==0 } {
 | 
						|
		# -k  means generate the keys to the nodes
 | 
						|
		# check to see if ssh rsa1 keys exists, if not generate it
 | 
						|
		if {![file exists "$home/.ssh/identity"]} {   # key does not exist 
 | 
						|
			set env(LC_ALL) "C"
 | 
						|
			spawn /usr/bin/ssh-keygen -t rsa1
 | 
						|
			expect "Generating public/private rsa1"
 | 
						|
			expect -re "Enter file.*:"
 | 
						|
			send "\r"
 | 
						|
			expect -re "Enter passphrase.*:"
 | 
						|
			send "\r"
 | 
						|
			expect -re "Enter same passphrase.*:"
 | 
						|
			send "\r"
 | 
						|
			expect eof
 | 
						|
		} elseif {[file exists "$home/.ssh/identity"] &&([file size "$home/.ssh/identity"] == 0)} {  # key exists
 | 
						|
			set env(LC_ALL) "C"
 | 
						|
			spawn /usr/bin/ssh-keygen -t rsa1
 | 
						|
			expect "Generating public/private rsa1"
 | 
						|
			expect -re "Enter file.*:"
 | 
						|
			send "\r"
 | 
						|
			expect -re "Overwrite.*\(y/n\)\?"
 | 
						|
			send "y\r"
 | 
						|
			expect -re "Enter passphrase.*:"
 | 
						|
			send "\r"
 | 
						|
			expect -re "Enter same passphrase.*:"
 | 
						|
			send "\r"
 | 
						|
			expect eof
 | 
						|
		}
 | 
						|
 | 
						|
		# check to see if ssh rsa keys exists, if not generate it
 | 
						|
		if {![file exists "$home/.ssh/id_rsa"]} {
 | 
						|
			set env(LC_ALL) "C"
 | 
						|
			spawn /usr/bin/ssh-keygen -t rsa
 | 
						|
			expect "Generating public/private rsa"
 | 
						|
			expect -re "Enter file.*:"
 | 
						|
			send "\r"
 | 
						|
			expect -re "Enter passphrase.*:"
 | 
						|
			send "\r"
 | 
						|
			expect -re "Enter same passphrase.*:"
 | 
						|
			send "\r"
 | 
						|
			expect eof
 | 
						|
		} elseif {[file exists "$home/.ssh/id_rsa"] &&([file size "$home/.ssh/id_rsa"] == 0)} {
 | 
						|
			set env(LC_ALL) "C"
 | 
						|
			spawn /usr/bin/ssh-keygen -t rsa
 | 
						|
			expect "Generating public/private rsa"
 | 
						|
			expect -re "Enter file.*:"
 | 
						|
			send "\r"
 | 
						|
			expect -re "Overwrite.*\(y/n\)\?"
 | 
						|
			send "y\r"
 | 
						|
			expect -re "Enter passphrase.*:"
 | 
						|
			send "\r"
 | 
						|
			expect -re "Enter same passphrase.*:"
 | 
						|
			send "\r"
 | 
						|
			expect eof
 | 
						|
		}
 | 
						|
 | 
						|
		# check to see if ssh dsa keys exists, if not generate it
 | 
						|
		if {![file exists "$home/.ssh/id_dsa"]} {
 | 
						|
			set env(LC_ALL) "C"	
 | 
						|
			spawn /usr/bin/ssh-keygen -t dsa
 | 
						|
			expect "Generating public/private dsa"
 | 
						|
			expect -re "Enter file.*:"
 | 
						|
			send "\r"
 | 
						|
			expect -re "Enter passphrase.*:"
 | 
						|
			send "\r"
 | 
						|
			expect -re "Enter same passphrase.*:"
 | 
						|
			send "\r"
 | 
						|
			expect eof
 | 
						|
		} elseif {[file exists "$home/.ssh/id_dsa"] && ([file size "$home/.ssh/id_dsa"] == 0)} {
 | 
						|
			set env(LC_ALL) "C"	
 | 
						|
			spawn /usr/bin/ssh-keygen -t dsa
 | 
						|
			expect "Generating public/private dsa"
 | 
						|
			expect -re "Enter file.*:"
 | 
						|
			send "\r"
 | 
						|
			expect -re "Overwrite.*\(y/n\)\?"
 | 
						|
			send "y\r"
 | 
						|
			expect -re "Enter passphrase.*:"
 | 
						|
			send "\r"
 | 
						|
			expect -re "Enter same passphrase.*:"
 | 
						|
			send "\r"
 | 
						|
			expect eof
 | 
						|
		}
 | 
						|
	} elseif { [string compare "-s" [lindex $argv 0]] ==0 } {
 | 
						|
                # copy the keys to the nodes
 | 
						|
		set nodes [lindex $argv 1]
 | 
						|
		set empty ""
 | 
						|
		if { [string compare $nodes $empty] ==0 } {
 | 
						|
			#no target
 | 
						|
			exit 1
 | 
						|
		}
 | 
						|
		set nodelist [split $nodes ',']
 | 
						|
		set nodelist2 $nodelist
 | 
						|
		set printlist [ join $nodelist ", " ]
 | 
						|
		set scp "/usr/bin/scp"
 | 
						|
		set directory "$home/.ssh"
 | 
						|
		set fh_auth_keys2  [ open "$home/.ssh/authorized_keys2" "r"]
 | 
						|
		set auth_keys2 [read $fh_auth_keys2]
 | 
						|
		close $fh_auth_keys2
 | 
						|
	   if { [info exists env(DSH_REMOTE_PASSWORD)] } {
 | 
						|
		    set word $env(DSH_REMOTE_PASSWORD)
 | 
						|
		} else {
 | 
						|
		  exec /bin/stty -echo
 | 
						|
		  set timeout 360
 | 
						|
		  puts "Enter the password for the userid:$to_userid to access the following target nodes: $printlist"
 | 
						|
		  expect_user "*\n"
 | 
						|
		  set timeout 80
 | 
						|
		  exec /bin/stty echo
 | 
						|
		  set word $expect_out(buffer)
 | 
						|
		  set expect_out(buffer) ""
 | 
						|
		  send_user "\n"
 | 
						|
		}
 | 
						|
                
 | 
						|
		foreach node $nodelist {
 | 
						|
                       puts $node
 | 
						|
			if { [string compare $ssh_setup_cmd $empty] ==0 } {
 | 
						|
				set env(LC_ALL) "C"
 | 
						|
				set pid [ spawn $remoteshell $node -l $to_userid /bin/mkdir -p /tmp/$to_userid/.ssh ]
 | 
						|
				expect {
 | 
						|
					"Are you sure you want to continue connecting (yes/no)?" {
 | 
						|
						send "yes\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"*ssword*" {
 | 
						|
						send "$word\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"Permission denied*" {
 | 
						|
						exec /bin/kill $pid
 | 
						|
					}
 | 
						|
				}
 | 
						|
				set pid [ spawn $scp  $directory/authorized_keys2 $to_userid\@$node:/tmp/$to_userid/.ssh ] 
 | 
						|
				expect {
 | 
						|
					"Are you sure you want to continue connecting (yes/no)?" {
 | 
						|
						send "yes\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"*ssword*" {
 | 
						|
						send "$word\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"Permission denied*" {
 | 
						|
						exec /bin/kill $pid
 | 
						|
					}
 | 
						|
				}
 | 
						|
				set pid [ spawn $scp  $directory/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh ] 
 | 
						|
				expect {
 | 
						|
					"Are you sure you want to continue connecting (yes/no)?" {
 | 
						|
						send "yes\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"*ssword*" {
 | 
						|
						send "$word\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"Permission denied*" {
 | 
						|
						exec /bin/kill $pid
 | 
						|
					}
 | 
						|
				}
 | 
						|
				set pid [ spawn $scp  $directory/id_rsa $to_userid\@$node:/tmp/$to_userid/.ssh ] 
 | 
						|
				expect {
 | 
						|
					"Are you sure you want to continue connecting (yes/no)?" {
 | 
						|
						send "yes\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"*ssword*" {
 | 
						|
						send "$word\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"Permission denied*" {
 | 
						|
						exec /bin/kill $pid
 | 
						|
					}
 | 
						|
				}
 | 
						|
				set pid [ spawn $scp  $directory/id_dsa $to_userid\@$node:/tmp/$to_userid/.ssh ] 
 | 
						|
				expect {
 | 
						|
					"Are you sure you want to continue connecting (yes/no)?" {
 | 
						|
						send "yes\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"*ssword*" {
 | 
						|
						send "$word\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"Permission denied*" {
 | 
						|
						exec /bin/kill $pid
 | 
						|
					}
 | 
						|
				}
 | 
						|
				set pid [ spawn $scp  $directory/copy.sh $to_userid\@$node:/tmp/$to_userid/.ssh ] 
 | 
						|
				expect {
 | 
						|
					"Are you sure you want to continue connecting (yes/no)?" {
 | 
						|
						send "yes\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"*ssword*" {
 | 
						|
						send "$word\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"Permission denied*" {
 | 
						|
						exec /bin/kill $pid
 | 
						|
					}
 | 
						|
				}
 | 
						|
				set pid [ spawn $remoteshell $node -l $to_userid /tmp/$to_userid/.ssh/copy.sh ]
 | 
						|
				expect {
 | 
						|
					"Are you sure you want to continue connecting (yes/no)?" {
 | 
						|
						send "yes\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"*ssword*" {
 | 
						|
						send "$word\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"Permission denied*" {
 | 
						|
						exec /bin/kill $pid
 | 
						|
					}
 | 
						|
				}
 | 
						|
			} else {
 | 
						|
				# Loop all keys in $auth_keys2 and generate ssh setup command one by one
 | 
						|
				# Remove '\n'
 | 
						|
				set auth_keys2 [string range $auth_keys2 0 end-1]
 | 
						|
				set all_keys [split $auth_keys2 "\n"]
 | 
						|
				set ssh_setup_string ""
 | 
						|
				foreach each_key $all_keys {
 | 
						|
					# Skip blank line
 | 
						|
					if { [string compare each_key $empty] == 0 } {
 | 
						|
						continue;
 | 
						|
					}
 | 
						|
					set ssh_setup_string "$ssh_setup_string;$ssh_setup_cmd \"$each_key\""
 | 
						|
				}
 | 
						|
				# Trim semicolon at the tail
 | 
						|
				set ssh_setup_string [string range $ssh_setup_string 1 end]
 | 
						|
				set pid [ spawn $remoteshell $node -l $to_userid $ssh_setup_string ]
 | 
						|
				expect {
 | 
						|
					"Are you sure you want to continue connecting (yes/no)?" {
 | 
						|
						send "yes\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"*ssword*" {
 | 
						|
						send "$word\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"Permission denied*" {
 | 
						|
						exec /bin/kill $pid	
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		set word ""
 | 
						|
		set failed "0"
 | 
						|
		foreach node $nodelist2 {
 | 
						|
			set hostname $node
 | 
						|
			set hlist [split $hostname '.']
 | 
						|
			set name ""
 | 
						|
			set nlist ""
 | 
						|
			set j [llength $hlist]
 | 
						|
			for { set i 0 } { $i<$j} {incr i } {
 | 
						|
				set element [lindex $hlist $i]
 | 
						|
				if { $i == 0 } {
 | 
						|
					set name $element
 | 
						|
				} else {
 | 
						|
					set name "$name.$element"
 | 
						|
				}
 | 
						|
				lappend nlist $name
 | 
						|
			}
 | 
						|
			foreach hn $nlist {
 | 
						|
				set env(LC_ALL) "C"
 | 
						|
				set pid [ spawn $remoteshell $hn -l $to_userid echo test.success ]
 | 
						|
				expect {
 | 
						|
					"Are you sure you want to continue connecting (yes/no)?" {
 | 
						|
						send "yes\r"
 | 
						|
						exp_continue
 | 
						|
					}
 | 
						|
					"*ssword*" {
 | 
						|
						exec /bin/kill $pid
 | 
						|
						set failed "1"
 | 
						|
					}
 | 
						|
					"*refused." {
 | 
						|
						exec /bin/kill $pid
 | 
						|
						set failed "1"
 | 
						|
					}
 | 
						|
					"Permission denied*" {
 | 
						|
						exec /bin/kill $pid
 | 
						|
						set failed "1"
 | 
						|
					}
 | 
						|
					timeout {
 | 
						|
						exec /bin/kill $pid
 | 
						|
						set failed "1"
 | 
						|
					}
 | 
						|
					"test.success" { continue }
 | 
						|
					}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if { [string compare "1" $failed ] ==0 } {
 | 
						|
			exit 1
 | 
						|
		} else {
 | 
						|
			exit 0
 | 
						|
		}
 | 
						|
   } else {  #  usage  error 
 | 
						|
              puts "flag entered is not valid" 
 | 
						|
              puts "Usage: remoteshell.expect" 
 | 
						|
              puts "  -t remote_shell hostname - test the remoteshell on the host"
 | 
						|
              puts "  -k Generates the ssh keys needed" 
 | 
						|
              puts "  -s node_list  - copies keys to the nodes"
 | 
						|
	      exit  2
 | 
						|
	    }
 | 
						|
} else {   # usage error
 | 
						|
              puts "Command requires a flag" 
 | 
						|
              puts "Usage: remoteshell.expect" 
 | 
						|
              puts "  -t remote_shell hostname - test the remoteshell on the host"
 | 
						|
              puts "  -k Generates the ssh keys needed" 
 | 
						|
              puts "  -s node_list  - copies keys to the nodes"
 | 
						|
	      exit  2
 | 
						|
}
 |