SSH working with new changes

This commit is contained in:
Mitchell Hashimoto 2011-12-10 12:49:35 -08:00
parent bfd93eef4e
commit b4c5b854e2
4 changed files with 31 additions and 36 deletions

View File

@ -9,7 +9,7 @@ module Vagrant
attr_accessor :forwarded_port_destination attr_accessor :forwarded_port_destination
attr_accessor :max_tries attr_accessor :max_tries
attr_accessor :timeout attr_accessor :timeout
attr_writer :private_key_path attr_accessor :private_key_path
attr_accessor :forward_agent attr_accessor :forward_agent
attr_accessor :forward_x11 attr_accessor :forward_x11
attr_accessor :shell attr_accessor :shell
@ -22,10 +22,6 @@ module Vagrant
@forward_x11 = false @forward_x11 = false
end end
def private_key_path
File.expand_path(@private_key_path, env.root_path)
end
def validate(errors) def validate(errors)
[:username, :host, :forwarded_port_key, :max_tries, :timeout, :private_key_path].each do |field| [:username, :host, :forwarded_port_key, :max_tries, :timeout, :private_key_path].each do |field|
errors.add(I18n.t("vagrant.config.common.error_empty", :field => field)) if !instance_variable_get("@#{field}".to_sym) errors.add(I18n.t("vagrant.config.common.error_empty", :field => field)) if !instance_variable_get("@#{field}".to_sym)

View File

@ -14,12 +14,8 @@ module Vagrant
include Util::Retryable include Util::Retryable
include Util::SafeExec include Util::SafeExec
# Reference back up to the environment which this SSH object belongs def initialize(vm)
# to @vm = vm
attr_accessor :env
def initialize(environment)
@env = environment
@logger = Log4r::Logger.new("vagrant::ssh") @logger = Log4r::Logger.new("vagrant::ssh")
end end
@ -28,7 +24,7 @@ module Vagrant
# of options which override the configuration values. # of options which override the configuration values.
def connect(opts={}) def connect(opts={})
if Util::Platform.windows? if Util::Platform.windows?
raise Errors::SSHUnavailableWindows, :key_path => env.config.ssh.private_key_path, raise Errors::SSHUnavailableWindows, :key_path => private_key_path,
:ssh_port => port(opts) :ssh_port => port(opts)
end end
@ -37,7 +33,7 @@ module Vagrant
options = {} options = {}
options[:port] = port(opts) options[:port] = port(opts)
[:host, :username, :private_key_path].each do |param| [:host, :username, :private_key_path].each do |param|
options[param] = opts[param] || env.config.ssh.send(param) options[param] = opts[param] || @vm.config.ssh.send(param)
end end
check_key_permissions(options[:private_key_path]) check_key_permissions(options[:private_key_path])
@ -46,9 +42,9 @@ module Vagrant
command_options = ["-p #{options[:port]}", "-o UserKnownHostsFile=/dev/null", command_options = ["-p #{options[:port]}", "-o UserKnownHostsFile=/dev/null",
"-o StrictHostKeyChecking=no", "-o IdentitiesOnly=yes", "-o StrictHostKeyChecking=no", "-o IdentitiesOnly=yes",
"-i #{options[:private_key_path]}", "-o LogLevel=ERROR"] "-i #{options[:private_key_path]}", "-o LogLevel=ERROR"]
command_options << "-o ForwardAgent=yes" if env.config.ssh.forward_agent command_options << "-o ForwardAgent=yes" if @vm.config.ssh.forward_agent
if env.config.ssh.forward_x11 if @vm.config.ssh.forward_x11
# Both are required so that no warnings are shown regarding X11 # Both are required so that no warnings are shown regarding X11
command_options << "-o ForwardX11=yes" command_options << "-o ForwardX11=yes"
command_options << "-o ForwardX11Trusted=yes" command_options << "-o ForwardX11Trusted=yes"
@ -63,29 +59,29 @@ module Vagrant
# a Net::SSH object which can be used to execute remote commands. # a Net::SSH object which can be used to execute remote commands.
def execute(opts={}) def execute(opts={})
# Check the key permissions to avoid SSH hangs # Check the key permissions to avoid SSH hangs
check_key_permissions(env.config.ssh.private_key_path) check_key_permissions(private_key_path)
# Merge in any additional options # Merge in any additional options
opts = opts.dup opts = opts.dup
opts[:forward_agent] = true if env.config.ssh.forward_agent opts[:forward_agent] = true if @vm.config.ssh.forward_agent
opts[:port] ||= port opts[:port] ||= port
@logger.info("Connecting to SSH: #{env.config.ssh.host} #{opts[:port]}") @logger.info("Connecting to SSH: #{@vm.config.ssh.host} #{opts[:port]}")
# The exceptions which are acceptable to retry on during # The exceptions which are acceptable to retry on during
# attempts to connect to SSH # attempts to connect to SSH
exceptions = [Errno::ECONNREFUSED, Net::SSH::Disconnect] exceptions = [Errno::ECONNREFUSED, Net::SSH::Disconnect]
# Connect to SSH and gather the session # Connect to SSH and gather the session
session = retryable(:tries => env.config.ssh.max_tries, :on => exceptions) do session = retryable(:tries => @vm.config.ssh.max_tries, :on => exceptions) do
connection = Net::SSH.start(env.config.ssh.host, connection = Net::SSH.start(@vm.config.ssh.host,
env.config.ssh.username, @vm.config.ssh.username,
opts.merge( :keys => [env.config.ssh.private_key_path], opts.merge( :keys => [private_key_path],
:keys_only => true, :keys_only => true,
:user_known_hosts_file => [], :user_known_hosts_file => [],
:paranoid => false, :paranoid => false,
:config => false)) :config => false))
SSH::Session.new(connection, env) SSH::Session.new(connection, @vm)
end end
# Yield our session for executing # Yield our session for executing
@ -116,8 +112,8 @@ module Vagrant
ssh_port = port ssh_port = port
require 'timeout' require 'timeout'
Timeout.timeout(env.config.ssh.timeout) do Timeout.timeout(@vm.config.ssh.timeout) do
execute(:timeout => env.config.ssh.timeout, :port => ssh_port) do |ssh| execute(:timeout => @vm.config.ssh.timeout, :port => ssh_port) do |ssh|
# We run a basic command to test that the shell is up and # We run a basic command to test that the shell is up and
# ready to receive commands. Only then is our SSH connection # ready to receive commands. Only then is our SSH connection
# truly "up" # truly "up"
@ -170,20 +166,20 @@ module Vagrant
return opts[:port] if opts[:port] return opts[:port] if opts[:port]
# Check if a port was specified in the config # Check if a port was specified in the config
return env.config.ssh.port if env.config.ssh.port return @vm.config.ssh.port if @vm.config.ssh.port
# Check if we have an SSH forwarded port # Check if we have an SSH forwarded port
pnum_by_name = nil pnum_by_name = nil
pnum_by_destination = nil pnum_by_destination = nil
env.vm.vm.network_adapters.each do |na| @vm.vm.network_adapters.each do |na|
# Look for the port number by name... # Look for the port number by name...
pnum_by_name = na.nat_driver.forwarded_ports.detect do |fp| pnum_by_name = na.nat_driver.forwarded_ports.detect do |fp|
fp.name == env.config.ssh.forwarded_port_key fp.name == @vm.config.ssh.forwarded_port_key
end end
# Look for the port number by destination... # Look for the port number by destination...
pnum_by_destination = na.nat_driver.forwarded_ports.detect do |fp| pnum_by_destination = na.nat_driver.forwarded_ports.detect do |fp|
fp.guestport == env.config.ssh.forwarded_port_destination fp.guestport == @vm.config.ssh.forwarded_port_destination
end end
# pnum_by_name is what we're looking for here, so break early # pnum_by_name is what we're looking for here, so break early
@ -197,5 +193,9 @@ module Vagrant
# This should NEVER happen. # This should NEVER happen.
raise Errors::SSHPortNotDetected raise Errors::SSHPortNotDetected
end end
def private_key_path
File.expand_path(@vm.config.ssh.private_key_path, @vm.env.root_path)
end
end end
end end

View File

@ -7,11 +7,10 @@ module Vagrant
include Util::Retryable include Util::Retryable
attr_reader :session attr_reader :session
attr_reader :env
def initialize(session, env) def initialize(session, vm)
@session = session @session = session
@env = env @vm = vm
end end
# Executes a given command and simply returns true/false if the # Executes a given command and simply returns true/false if the
@ -34,7 +33,7 @@ module Vagrant
# of `sudo`. # of `sudo`.
def sudo!(commands, options=nil, &block) def sudo!(commands, options=nil, &block)
channel = session.open_channel do |ch| channel = session.open_channel do |ch|
ch.exec("sudo -H #{env.config.ssh.shell} -l") do |ch2, success| ch.exec("sudo -H #{@vm.config.ssh.shell} -l") do |ch2, success|
# Set the terminal # Set the terminal
ch2.send_data "export TERM=vt100\n" ch2.send_data "export TERM=vt100\n"
@ -61,9 +60,9 @@ module Vagrant
# the actual `exec!` implementation, except that this # the actual `exec!` implementation, except that this
# implementation also reports `:exit_status` to the block if given. # implementation also reports `:exit_status` to the block if given.
def exec!(commands, options=nil, &block) def exec!(commands, options=nil, &block)
retryable(:tries => env.config.ssh.max_tries, :on => [IOError, Net::SSH::Disconnect], :sleep => 1.0) do retryable(:tries => @vm.config.ssh.max_tries, :on => [IOError, Net::SSH::Disconnect], :sleep => 1.0) do
metach = session.open_channel do |ch| metach = session.open_channel do |ch|
ch.exec("#{env.config.ssh.shell} -l") do |ch2, success| ch.exec("#{@vm.config.ssh.shell} -l") do |ch2, success|
# Set the terminal # Set the terminal
ch2.send_data "export TERM=vt100\n" ch2.send_data "export TERM=vt100\n"

View File

@ -75,7 +75,7 @@ module Vagrant
# On the initial call, this will initialize the object. On # On the initial call, this will initialize the object. On
# subsequent calls it will reuse the existing object. # subsequent calls it will reuse the existing object.
def ssh def ssh
@ssh ||= SSH.new(env) @ssh ||= SSH.new(self)
end end
# Returns a boolean true if the VM has been created, otherwise # Returns a boolean true if the VM has been created, otherwise