From d9bd858855b1285918bb26e6214a48dbf993c42a Mon Sep 17 00:00:00 2001 From: Jamis Buck Date: Tue, 12 Jun 2007 20:29:00 +0000 Subject: [PATCH] work around net::ssh's lazy requiring of files git-svn-id: http://svn.rubyonrails.org/rails/tools/capistrano@7009 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- lib/capistrano/configuration/connections.rb | 17 ++------------- lib/capistrano/ssh.rb | 23 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/lib/capistrano/configuration/connections.rb b/lib/capistrano/configuration/connections.rb index ce17bbed..88c40f71 100644 --- a/lib/capistrano/configuration/connections.rb +++ b/lib/capistrano/configuration/connections.rb @@ -56,21 +56,8 @@ module Capistrano # Ensures that there are active sessions for each server in the list. def establish_connections_to(servers) - servers = Array(servers) - - # because Net::SSH uses lazy loading for things, we need to make sure - # that at least one connection has been made successfully, to kind of - # "prime the pump", before we go gung-ho and do mass connection in - # parallel. Otherwise, the threads start doing things in wierd orders - # and causing Net::SSH to die of confusion. - # TODO investigate Net::SSH and see if this can't be solved there - - if sessions.empty? - server, servers = servers.first, servers[1..-1] - sessions[server] = connection_factory.connect_to(server) - end - - servers.map { |server| establish_connection_to(server) }.each { |t| t.join } + threads = Array(servers).map { |server| establish_connection_to(server) } + threads.each { |t| t.join } end # Determines the set of servers within the current task's scope and diff --git a/lib/capistrano/ssh.rb b/lib/capistrano/ssh.rb index 460a9dde..b18bdeeb 100644 --- a/lib/capistrano/ssh.rb +++ b/lib/capistrano/ssh.rb @@ -10,6 +10,29 @@ module Capistrano end end + # Now, Net::SSH is kind of silly, and tries to lazy-load everything. This + # wreaks havoc with the parallel connection trick that Capistrano wants to + # use, so we're going to do something hideously ugly here and force all the + # files that Net::SSH uses to load RIGHT NOW, rather than lazily. + + net_ssh_dependencies = %w(connection/services connection/channel connection/driver + service/agentforward/services service/agentforward/driver + service/forward/services service/forward/driver service/forward/local-network-handler service/forward/remote-network-handler + lenient-host-key-verifier + transport/compress/services transport/compress/zlib-compressor transport/compress/none-compressor transport/compress/zlib-decompressor transport/compress/none-decompressor + transport/kex/services transport/kex/dh transport/kex/dh-gex + transport/ossl/services + transport/ossl/hmac/services transport/ossl/hmac/sha1 transport/ossl/hmac/sha1-96 transport/ossl/hmac/md5 transport/ossl/hmac/md5-96 transport/ossl/hmac/none + transport/ossl/cipher-factory transport/ossl/hmac-factory transport/ossl/buffer-factory transport/ossl/key-factory transport/ossl/digest-factory + transport/identity-cipher transport/packet-stream transport/version-negotiator transport/algorithm-negotiator transport/session + userauth/methods/services userauth/methods/password userauth/methods/keyboard-interactive userauth/methods/publickey userauth/methods/hostbased + userauth/services userauth/agent userauth/userkeys userauth/driver + transport/services + ) + + net_ssh_dependencies << "userauth/pageant" if File::ALT_SEPARATOR + net_ssh_dependencies.each { |path| require "net/ssh/#{path}" } + # A helper class for dealing with SSH connections. class SSH # Patch an accessor onto an SSH connection so that we can record the server