dash 4.0.7 → 4.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d13e0fdb207715506d85fa85be2a719ca70640130f22ca948c075fd787b3dd88
4
- data.tar.gz: cc42a4346178f4ffbcf7b7b2f03820e49f99e9d54c78ab864493a0c0b8b214e4
3
+ metadata.gz: a417156134dd79a4724f87192f70baa55fdbc4478a115e021845e3742bacee88
4
+ data.tar.gz: ebdbb8d7f192b692c31c8cdaa9834584c01dec3653b744b1a481672fee179d28
5
5
  SHA512:
6
- metadata.gz: cdf2135081cc1acc7de1d73d7c7156f93262ad82a5848a6db6aaf484bf4859ed3e529fede60ac0c67df99ec021acdd2cbf6a9175982af8f31873afa03cc2113b
7
- data.tar.gz: 30eae7e9f41f2b216be4dd8d16ce583f5a8e2392d3b05b3ad15fcd4ba40645441c05c39a643cca2bf01876ee28aec2fa668a7ffe2a474e27c69b46edc341dbc6
6
+ metadata.gz: 3b263730b7ccf4eeeb857304477945fd9d2476bdf52cdb30a964b12b09143b36b5f585ae672d776eac29a6e009606add151aa6e9dd98385f9146980bbc40a9db
7
+ data.tar.gz: a3ebb3e0141a0f692bd70205aa3d438f9a3cbd1022d1b92c229bf1daf19294c4826a7420c0fefbb077f5a6d6cb46016ee6ab3926bb08f11383bb7a6eb0aaa23e
@@ -79,3 +79,11 @@ ssh:
79
79
  # host or tunnel that does not support agent forwarding (for example,
80
80
  # Cloudflare Access for Infrastructure with SSH).
81
81
  forward_agent: false
82
+
83
+ # Connect timeout
84
+ #
85
+ # Seconds to wait for the TCP connection and the SSH handshake with a
86
+ # host before giving up with `Net::SSH::ConnectionTimeout`. Defaults to
87
+ # 30. Without a bound, a host that accepts the connection but never
88
+ # answers the handshake hangs the deploy indefinitely.
89
+ connect_timeout: 30
@@ -23,7 +23,8 @@ sshkit:
23
23
  #
24
24
  # A pooled connection that the network dropped while idle is evicted and the command
25
25
  # retried once on a fresh connection, so a long wait elsewhere (a server-lock poll, a
26
- # loadbalancer reboot) does not fail the next command on another host.
26
+ # loadbalancer reboot) does not fail the next command on another host. A host that
27
+ # stops answering keepalives mid-command is not retried; that deploy fails.
27
28
  pool_idle_timeout: 300
28
29
 
29
30
  # DNS retry settings
@@ -57,8 +57,15 @@ class Dash::Configuration::Ssh
57
57
  ssh_config["forward_agent"]
58
58
  end
59
59
 
60
+ # net-ssh only bounds the TCP connect and the version/key exchange when
61
+ # `timeout` is set. Without it, a host that accepts the TCP connection but
62
+ # never finishes the handshake blocks the deploy forever.
63
+ def connect_timeout
64
+ ssh_config.fetch("connect_timeout", 30)
65
+ end
66
+
60
67
  def options
61
- { user: user, port: port, proxy: proxy, logger: logger, keepalive: true, keepalive_interval: 30, keys_only: keys_only, keys: keys, key_data: key_data, config: config, forward_agent: forward_agent }.compact
68
+ { user: user, port: port, proxy: proxy, logger: logger, keepalive: true, keepalive_interval: 30, keys_only: keys_only, keys: keys, key_data: key_data, config: config, forward_agent: forward_agent, timeout: connect_timeout }.compact
62
69
  end
63
70
 
64
71
  def to_h
@@ -181,8 +181,15 @@ class SSHKit::Backend::Netssh
181
181
  # The block is rerun, so a drop *mid-command* runs the command twice. That
182
182
  # is accepted: the errors here are the idle-drop ones, where nothing reached
183
183
  # the server, and the alternative is the deploy failing on the next host.
184
+ #
185
+ # Net::SSH::Timeout (a Disconnect subclass) is deliberately excluded. net-ssh
186
+ # raises it when a host has ignored `keepalive_maxcount` keepalives in a row,
187
+ # which is a host that stopped answering mid-command, not a dropped idle
188
+ # socket. Retrying that reconnects to a host that has just proven unresponsive
189
+ # and, if it accepts the connection but never finishes the handshake or the
190
+ # command, hangs the deploy with no further guard. Let it fail.
184
191
  module ReconnectOnStaleConnection
185
- STALE_CONNECTION_ERRORS = [ Errno::ECONNRESET, Errno::EPIPE, Net::SSH::Disconnect, Net::SSH::Timeout ].freeze
192
+ STALE_CONNECTION_ERRORS = [ Errno::ECONNRESET, Errno::EPIPE, Net::SSH::Disconnect ].freeze
186
193
 
187
194
  private
188
195
  def with_ssh
@@ -191,12 +198,12 @@ class SSHKit::Backend::Netssh
191
198
  begin
192
199
  super do |ssh|
193
200
  yield ssh
194
- rescue *STALE_CONNECTION_ERRORS
195
- evict_stale_session(ssh)
201
+ rescue *STALE_CONNECTION_ERRORS => e
202
+ evict_stale_session(ssh) if stale_connection_error?(e)
196
203
  raise
197
204
  end
198
205
  rescue *STALE_CONNECTION_ERRORS => e
199
- raise if reconnected
206
+ raise if reconnected || !stale_connection_error?(e)
200
207
 
201
208
  reconnected = true
202
209
  SSHKit.config.output.warn("Reconnecting to #{host}: #{e.message}")
@@ -204,6 +211,10 @@ class SSHKit::Backend::Netssh
204
211
  end
205
212
  end
206
213
 
214
+ def stale_connection_error?(error)
215
+ !error.is_a?(Net::SSH::Timeout)
216
+ end
217
+
207
218
  # `close` waits for channel-close acknowledgements, which never come over
208
219
  # a dead socket. `shutdown!` just closes the socket, and a closed session
209
220
  # is what makes the pool drop it instead of caching it again.
data/lib/dash/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Dash
2
- VERSION = "4.0.7"
2
+ VERSION = "4.0.8"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dash
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.7
4
+ version: 4.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikael Henriksson