diff --git a/lib/vagrant/communication/ssh.rb b/lib/vagrant/communication/ssh.rb index d4176dde5..34623cef1 100644 --- a/lib/vagrant/communication/ssh.rb +++ b/lib/vagrant/communication/ssh.rb @@ -87,6 +87,26 @@ module Vagrant # Opens an SSH connection and yields it to a block. def connect + if @connection && !@connection.closed? + # There is a chance that the socket is closed despite us checking + # 'closed?' above. To test this we need to send data through the + # socket. + begin + @connection.exec!("") + rescue IOError + @logger.info("Connection has been closed. Not re-using.") + @connection = nil + end + + # If the @connection is still around, then it is valid, + # and we use it. + if @connection + @logger.info("Re-using SSH connection.") + return yield @connection if block_given? + return + end + end + ssh_info = @vm.ssh.info # Build the options we'll use to initiate the connection via Net::SSH @@ -104,12 +124,14 @@ module Vagrant @vm.ssh.check_key_permissions(ssh_info[:private_key_path]) # Connect to SSH, giving it a few tries - @logger.debug("Connecting to SSH: #{ssh_info[:host]}:#{ssh_info[:port]}") + @logger.info("Connecting to SSH: #{ssh_info[:host]}:#{ssh_info[:port]}") exceptions = [Errno::ECONNREFUSED, Net::SSH::Disconnect] connection = retryable(:tries => @vm.config.ssh.max_tries, :on => exceptions) do Net::SSH.start(ssh_info[:host], ssh_info[:username], opts) end + @connection = connection + # This is hacky but actually helps with some issues where # Net::SSH is simply not robust enough to handle... see # issue #391, #455, etc. @@ -127,7 +149,7 @@ module Vagrant raise Errors::SSHConnectionRefused ensure # Be sure the connection is always closed - connection.close if connection && !connection.closed? + # connection.close if connection && !connection.closed? end # Executes the command on an SSH connection within a login shell. diff --git a/templates/locales/en.yml b/templates/locales/en.yml index cb2c0c3bc..d6dde5231 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -90,10 +90,6 @@ en: Vagrant assumes that this means the command failed! %{command} - - The output of the command prior to failing is outputted below: - - %{output} ssh_connection_refused: |- SSH connection was refused! This usually happens if the VM failed to boot properly. Some steps to try to fix this: First, try reloading your diff --git a/vagrant.gemspec b/vagrant.gemspec index 30e9be7d2..287f7f6a7 100644 --- a/vagrant.gemspec +++ b/vagrant.gemspec @@ -19,7 +19,7 @@ Gem::Specification.new do |s| s.add_dependency "erubis", "~> 2.7.0" s.add_dependency "json", "~> 1.5.1" s.add_dependency "log4r", "~> 1.1.9" - s.add_dependency "net-ssh", "~> 2.1.4" + s.add_dependency "net-ssh", "~> 2.2.2" s.add_dependency "net-scp", "~> 1.0.4" s.add_dependency "i18n", "~> 0.6.0"