From 9d7f47b87f05f73fcc81a36794de30cc73368f4b Mon Sep 17 00:00:00 2001 From: Jamis Buck Date: Thu, 14 Jun 2007 16:01:49 +0000 Subject: [PATCH] server options take precedence over ssh_options (closes #6547) git-svn-id: http://svn.rubyonrails.org/rails/tools/capistrano@7024 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- CHANGELOG | 2 ++ lib/capistrano/ssh.rb | 22 +++++++++++++++------- test/ssh_test.rb | 14 ++++++++++---- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8cd685c5..17910d44 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* ssh_options < server options when connecting [Jamis Buck] + * Logger defaults to $stderr instead of STDERR [lhartley] * Use cp -RPp instead of -a in the remote cache strategy diff --git a/lib/capistrano/ssh.rb b/lib/capistrano/ssh.rb index b18bdeeb..f4f79a61 100644 --- a/lib/capistrano/ssh.rb +++ b/lib/capistrano/ssh.rb @@ -60,22 +60,30 @@ module Capistrano # # If a block is given, the new session is yielded to it, otherwise the new # session is returned. + # + # If an :ssh_options key exists in +options+, it is passed to the Net::SSH + # constructor. Values in +options+ are then merged into it, and any + # connection information in +server+ is added last, so that +server+ info + # takes precedence over +options+, which takes precendence over ssh_options. def self.connect(server, options={}, &block) methods = [ %w(publickey hostbased), %w(password keyboard-interactive) ] password_value = nil + ssh_options = (options[:ssh_options] || {}).dup + ssh_options[:username] = server.user || options[:user] || ssh_options[:username] + ssh_options[:port] = server.port || options[:port] || ssh_options[:port] || DEFAULT_PORT + begin - ssh_options = { :username => (server.user || options[:user]), - :password => password_value, - :port => (server.port || options[:port] || DEFAULT_PORT), - :auth_methods => methods.shift } - ssh_options.update(options[:ssh_options]) if options[:ssh_options] + connection_options = ssh_options.merge( + :password => password_value, + :auth_methods => ssh_options[:auth_methods] || methods.shift + ) - connection = Net::SSH.start(server.host, ssh_options, &block) + connection = Net::SSH.start(server.host, connection_options, &block) Server.apply_to(connection, server) rescue Net::SSH::AuthenticationFailed - raise if methods.empty? || options[:ssh_options] && options[:ssh_options][:auth_methods] + raise if methods.empty? || ssh_options[:auth_methods] password_value = options[:password] retry end diff --git a/test/ssh_test.rb b/test/ssh_test.rb index b08b3780..29b26d34 100644 --- a/test/ssh_test.rb +++ b/test/ssh_test.rb @@ -63,16 +63,22 @@ class SSHTest < Test::Unit::TestCase assert_equal success, Capistrano::SSH.connect(server) end - def test_connect_with_ssh_options_should_override_options + def test_connect_with_ssh_options_should_use_ssh_options ssh_options = { :username => "JamisMan", :port => 8125 } Net::SSH.expects(:start).with(@server.host, @options.merge(:username => "JamisMan", :port => 8125)).returns(success = Object.new) + assert_equal success, Capistrano::SSH.connect(@server, {:ssh_options => ssh_options}) + end + + def test_connect_with_options_and_ssh_options_should_see_options_override_ssh_options + ssh_options = { :username => "JamisMan", :port => 8125, :forward_agent => true } + Net::SSH.expects(:start).with(@server.host, @options.merge(:username => "jamis", :port => 1235, :forward_agent => true)).returns(success = Object.new) assert_equal success, Capistrano::SSH.connect(@server, {:ssh_options => ssh_options, :user => "jamis", :port => 1235}) end - def test_connect_with_ssh_options_should_override_server_options - ssh_options = { :username => "JamisMan", :port => 8125 } + def test_connect_with_ssh_options_should_see_server_options_override_ssh_options + ssh_options = { :username => "JamisMan", :port => 8125, :forward_agent => true } server = server("jamis@capistrano:1235") - Net::SSH.expects(:start).with(server.host, @options.merge(:username => "JamisMan", :port => 8125)).returns(success = Object.new) + Net::SSH.expects(:start).with(server.host, @options.merge(:username => "jamis", :port => 1235, :forward_agent => true)).returns(success = Object.new) assert_equal success, Capistrano::SSH.connect(server, {:ssh_options => ssh_options}) end