From 2ed6695f785f17792ae6302f21064d5f7a66187d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 28 Mar 2012 22:30:01 -0700 Subject: [PATCH] Improve the SSH ready? check [GH-841] --- CHANGELOG.md | 2 +- lib/vagrant/communication/ssh.rb | 22 +++++++++++++--------- lib/vagrant/errors.rb | 5 +++++ templates/locales/en.yml | 5 +++++ 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c09962bc..8ef935929 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## 1.1.0 (unreleased) - + - Improve the SSH "ready?" check. [GH-841] ## 1.0.2 (March 25, 2012) diff --git a/lib/vagrant/communication/ssh.rb b/lib/vagrant/communication/ssh.rb index feeac65c4..1287a1eb0 100644 --- a/lib/vagrant/communication/ssh.rb +++ b/lib/vagrant/communication/ssh.rb @@ -25,16 +25,15 @@ module Vagrant def ready? @logger.debug("Checking whether SSH is ready...") - Timeout.timeout(@vm.config.ssh.timeout) do - connect - end + # Attempt to connect. This will raise an exception if it fails. + connect # If we reached this point then we successfully connected @logger.info("SSH is ready!") true - rescue Timeout::Error, Errors::SSHConnectionRefused, Net::SSH::Disconnect => e - # The above errors represent various reasons that SSH may not be - # ready yet. Return false. + rescue Errors::VagrantError => e + # We catch a `VagrantError` which would signal that something went + # wrong expectedly in the `connect`, which means we didn't connect. @logger.info("SSH not up: #{e.inspect}") return false end @@ -131,11 +130,16 @@ module Vagrant # Connect to SSH, giving it a few tries connection = nil begin - @logger.info("Connecting to SSH: #{ssh_info[:host]}:#{ssh_info[:port]}") - exceptions = [Errno::ECONNREFUSED, Net::SSH::Disconnect] + exceptions = [Errno::ECONNREFUSED, Net::SSH::Disconnect, Timeout::Error] connection = retryable(:tries => @vm.config.ssh.max_tries, :on => exceptions) do - Net::SSH.start(ssh_info[:host], ssh_info[:username], opts) + Timeout.timeout(@vm.config.ssh.timeout) do + @logger.info("Attempting to connect to SSH: #{ssh_info[:host]}:#{ssh_info[:port]}") + Net::SSH.start(ssh_info[:host], ssh_info[:username], opts) + end end + rescue Timeout::Error + # This happens if we continued to timeout when attempting to connect. + raise Errors::SSHConnectionTimeout rescue Net::SSH::AuthenticationFailed # This happens if authentication failed. We wrap the error in our # own exception. diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 4b11d3433..0d863d9b7 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -313,6 +313,11 @@ module Vagrant error_key(:ssh_connection_refused) end + class SSHConnectionTimeout < VagrantError + status_code(78) + error_key(:ssh_connection_timeout) + end + class SSHKeyBadPermissions < VagrantError status_code(12) error_key(:ssh_key_bad_permissions) diff --git a/templates/locales/en.yml b/templates/locales/en.yml index a1a898d12..b3d0aeb7f 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -117,6 +117,11 @@ en: If that doesn't work, destroy your VM and recreate it with a `vagrant destroy` followed by a `vagrant up`. If that doesn't work, contact a Vagrant maintainer (support channels listed on the website) for more assistance. + ssh_connection_timeout: |- + Vagrant timed out while attempting to connect via SSH. This usually + means that the VM booted, but there are issues with the SSH configuration + or network connectivity issues. Please try to `vagrant reload` or + `vagrant up` again. ssh_key_bad_permissions: |- The private key to connect to this box via SSH has invalid permissions set on it. The permissions of the private key should be set to 0600, otherwise SSH will