Retry SSH connection on Errno::ECONNABORTED

In some cases the SSH connection may be aborted while waiting
for setup. This includes aborted connections in the list of
applicable exceptions to retry on while waiting for the connection
to become available.

Fixes #8520
This commit is contained in:
Chris Roberts 2017-04-25 13:38:24 -07:00
parent 5fa23c42dd
commit 2acded113c
3 changed files with 32 additions and 15 deletions

View File

@ -664,6 +664,10 @@ module Vagrant
error_key(:ssh_connection_refused)
end
class SSHConnectionAborted < VagrantError
error_key(:ssh_connection_aborted)
end
class SSHConnectionReset < VagrantError
error_key(:ssh_connection_reset)
end

View File

@ -25,6 +25,20 @@ module VagrantPlugins
PTY_DELIM_END = "bccbb768c119429488cfd109aacea6b5-pty"
# Marker for start of regular command output
CMD_GARBAGE_MARKER = "41e57d38-b4f7-4e46-9c38-13873d338b86-vagrant-ssh"
# These are the exceptions that we retry because they represent
# errors that are generally fixed from a retry and don't
# necessarily represent immediate failure cases.
SSH_RETRY_EXCEPTIONS = [
Errno::EACCES,
Errno::EADDRINUSE,
Errno::ECONNABORTED,
Errno::ECONNREFUSED,
Errno::ECONNRESET,
Errno::ENETUNREACH,
Errno::EHOSTUNREACH,
Net::SSH::Disconnect,
Timeout::Error
]
include Vagrant::Util::ANSIEscapeCodeRemover
include Vagrant::Util::Retryable
@ -81,6 +95,8 @@ module VagrantPlugins
message = "Connection refused."
rescue Vagrant::Errors::SSHConnectionReset
message = "Connection reset."
rescue Vagrant::Errors::SSHConnectionAborted
message = "Connection aborted."
rescue Vagrant::Errors::SSHHostDown
message = "Host appears down."
rescue Vagrant::Errors::SSHNoRoute
@ -350,24 +366,10 @@ module VagrantPlugins
# Connect to SSH, giving it a few tries
connection = nil
begin
# These are the exceptions that we retry because they represent
# errors that are generally fixed from a retry and don't
# necessarily represent immediate failure cases.
exceptions = [
Errno::EACCES,
Errno::EADDRINUSE,
Errno::ECONNREFUSED,
Errno::ECONNRESET,
Errno::ENETUNREACH,
Errno::EHOSTUNREACH,
Net::SSH::Disconnect,
Timeout::Error
]
timeout = 60
@logger.info("Attempting SSH connection...")
connection = retryable(tries: opts[:retries], on: exceptions) do
connection = retryable(tries: opts[:retries], on: SSH_RETRY_EXCEPTIONS) do
Timeout.timeout(timeout) do
begin
# This logger will get the Net-SSH log data for us.
@ -426,6 +428,10 @@ module VagrantPlugins
# This is raised if we failed to connect the max number of times
# due to an ECONNRESET.
raise Vagrant::Errors::SSHConnectionReset
rescue Errno::ECONNABORTED
# This is raised if we failed to connect the max number of times
# due to an ECONNABORTED
raise Vagrant::Errors::SSHConnectionAborted
rescue Errno::EHOSTDOWN
# This is raised if we get an ICMP DestinationUnknown error.
raise Vagrant::Errors::SSHHostDown

View File

@ -1189,6 +1189,13 @@ 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_aborted: |-
SSH connection was aborted! This usually happens when the machine is taking
too long to reboot or the SSH daemon is not properly configured on the VM.
First, try reloading your machine with `vagrant reload`, since a simple
restart sometimes fixes things. If that doesn't work, destroy your machine
and recreate it with a `vagrant destroy` followed by a `vagrant up`. If that
doesn't work, contact support.
ssh_connection_reset: |-
SSH connection was reset! This usually happens when the machine is
taking too long to reboot. First, try reloading your machine with