diff --git a/config/default.rb b/config/default.rb index 348b1c198..99608ea22 100644 --- a/config/default.rb +++ b/config/default.rb @@ -11,6 +11,7 @@ Vagrant::Config.run do |config| config.ssh.max_tries = 10 config.ssh.timeout = 30 config.ssh.private_key_path = File.join(PROJECT_ROOT, 'keys', 'vagrant') + config.ssh.forward_agent = false config.vm.auto_port_range = (2200..2250) config.vm.box_ovf = "box.ovf" diff --git a/lib/vagrant/config.rb b/lib/vagrant/config.rb index aab31584a..b1593ff61 100644 --- a/lib/vagrant/config.rb +++ b/lib/vagrant/config.rb @@ -67,6 +67,7 @@ module Vagrant attr_accessor :max_tries attr_accessor :timeout attr_accessor :private_key_path + attr_accessor :forward_agent # The attribute(s) below do nothing. They are just kept here to # prevent syntax errors for backwards compat. diff --git a/lib/vagrant/ssh.rb b/lib/vagrant/ssh.rb index f2e226b34..3757fa94c 100644 --- a/lib/vagrant/ssh.rb +++ b/lib/vagrant/ssh.rb @@ -31,12 +31,17 @@ module Vagrant check_key_permissions(options[:private_key_path]) + # Command line options + command_options = ["-p #{options[:port]}", "-o UserKnownHostsFile=/dev/null", + "-o StrictHostKeyChecking=no", "-i #{options[:private_key_path]}"] + command_options << "-o ForwardAgent=yes" if env.config.ssh.forward_agent + # Some hackery going on here. On Mac OS X Leopard (10.5), exec fails # (GH-51). As a workaround, we fork and wait. On all other platforms, # we simply exec. pid = nil pid = fork if Util::Platform.leopard? - Kernel.exec "ssh -p #{options[:port]} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i #{options[:private_key_path]} #{options[:username]}@#{options[:host]}".strip if pid.nil? + Kernel.exec "ssh #{command_options.join(" ")} #{options[:username]}@#{options[:host]}".strip if pid.nil? Process.wait(pid) if pid end @@ -46,6 +51,10 @@ module Vagrant # Check the key permissions to avoid SSH hangs check_key_permissions(env.config.ssh.private_key_path) + # Merge in any additional options + opts = opts.dup + opts[:forward_agent] = true if env.config.ssh.forward_agent + Net::SSH.start(env.config.ssh.host, env.config[:ssh][:username], opts.merge( :port => port, diff --git a/test/vagrant/ssh_test.rb b/test/vagrant/ssh_test.rb index 987d614a3..8c4ffadd6 100644 --- a/test/vagrant/ssh_test.rb +++ b/test/vagrant/ssh_test.rb @@ -52,6 +52,17 @@ class SshTest < Test::Unit::TestCase @ssh.connect(args) end + should "add forward agent option if enabled" do + @env.config.ssh.forward_agent = true + ssh_exec_expect(@ssh.port, + @env.config.ssh.private_key_path, + @env.config.ssh.username, + @env.config.ssh.host) do |args| + assert args =~ /-o ForwardAgent=yes/ + end + @ssh.connect + end + context "on leopard" do setup do Vagrant::Util::Platform.stubs(:leopard?).returns(true) @@ -88,7 +99,7 @@ class SshTest < Test::Unit::TestCase assert arg =~ /-p #{port}/ assert arg =~ /-i #{key_path}/ assert arg =~ /#{uname}@#{host}/ - # TODO options not tested for as they may be removed + yield arg if block_given? true end end @@ -119,6 +130,16 @@ class SshTest < Test::Unit::TestCase @ssh.execute end + should "forward agent if configured" do + @env.config.ssh.forward_agent = true + Net::SSH.expects(:start).once.with() do |host, username, opts| + assert opts[:forward_agent] + true + end + + @ssh.execute + end + should "use custom host if set" do @env.config.ssh.host = "foo" Net::SSH.expects(:start).with(@env.config.ssh.host, @env.config.ssh.username, anything).once