Cache SSH connections to VMs.

This commit is contained in:
Mitchell Hashimoto 2011-07-07 23:15:19 -07:00
parent e625dba5ab
commit d77738b37f
3 changed files with 25 additions and 11 deletions

View File

@ -19,6 +19,8 @@
- Provisioner configuration is no longer cleared when the box - Provisioner configuration is no longer cleared when the box
needs to be downloaded during an `up`. [GH-308] needs to be downloaded during an `up`. [GH-308]
- Multiple Chef provisioners no longer overwrite cookbook folders. [GH-407] - Multiple Chef provisioners no longer overwrite cookbook folders. [GH-407]
- SSH connection is now cached after first access internally,
speeding up `vagrant up`, `reload`, etc. quite a bit.
## 0.7.6 (July 2, 2011) ## 0.7.6 (July 2, 2011)

View File

@ -18,6 +18,7 @@ module Vagrant
def initialize(environment) def initialize(environment)
@env = environment @env = environment
@current_session = nil
end end
# Connects to the environment's virtual machine, replacing the ruby # Connects to the environment's virtual machine, replacing the ruby
@ -71,17 +72,28 @@ module Vagrant
opts[:forward_agent] = true if env.config.ssh.forward_agent opts[:forward_agent] = true if env.config.ssh.forward_agent
opts[:port] ||= port opts[:port] ||= port
retryable(:tries => 5, :on => Errno::ECONNREFUSED) do # Check if we have a currently open SSH session which has the
Net::SSH.start(env.config.ssh.host, # same options, and use that if possible
session, options = @current_session
if !session || options != opts
session = retryable(:tries => 5, :on => Errno::ECONNREFUSED) do
connection = Net::SSH.start(env.config.ssh.host,
env.config.ssh.username, env.config.ssh.username,
opts.merge( :keys => [env.config.ssh.private_key_path], opts.merge( :keys => [env.config.ssh.private_key_path],
:keys_only => true, :keys_only => true,
:user_known_hosts_file => [], :user_known_hosts_file => [],
:paranoid => false, :paranoid => false,
:config => false)) do |ssh| :config => false))
yield SSH::Session.new(ssh, env) SSH::Session.new(connection, env)
end end
# Save the new session along with the options which created it
@current_session = [session, opts]
end end
# Yield our session for executing
return yield session if block_given?
rescue Errno::ECONNREFUSED rescue Errno::ECONNREFUSED
raise Errors::SSHConnectionRefused raise Errors::SSHConnectionRefused
end end

View File

@ -171,7 +171,7 @@ class SshTest < Test::Unit::TestCase
should "yield an SSH session object" do should "yield an SSH session object" do
raw = mock("raw") raw = mock("raw")
Net::SSH.expects(:start).yields(raw) Net::SSH.expects(:start).returns(raw)
@ssh.execute do |ssh| @ssh.execute do |ssh|
assert ssh.is_a?(Vagrant::SSH::Session) assert ssh.is_a?(Vagrant::SSH::Session)
assert_equal raw, ssh.session assert_equal raw, ssh.session