Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Use 'user' from .ssh/config appropriately, and bump Net::SSH dependen…

…cy to 2.0.10
  • Loading branch information...
commit 9a281b2d13aef75e6afdd4132c6c1a8d5255099f 1 parent f70fcca
@jamis jamis authored
View
4 CHANGELOG.rdoc
@@ -1,5 +1,9 @@
== (unreleased)
+* Bump Net::SSH dependency to version 2.0.10 [Jamis Buck]
+
+* Use 'user' from .ssh/config appropriately [Jamis Buck]
+
* Allow respond_to?() method to accept optional second parameter (include_priv) [Matthias Marschall]
* Make sure sudo prompts are retried correctly even if "try again" and the prompt appear in the same text chunk from the server [Jamis Buck]
View
2  Rakefile
@@ -26,7 +26,7 @@ Echoe.new('capistrano', version) do |p|
p.need_zip = true
p.rdoc_pattern = /^(lib|README.rdoc|CHANGELOG.rdoc)/
- p.dependencies = ["net-ssh >=2.0.0",
+ p.dependencies = ["net-ssh >=2.0.10",
"net-sftp >=2.0.0",
"net-scp >=1.0.0",
"net-ssh-gateway >=1.0.0",
View
30 lib/capistrano/ssh.rb
@@ -1,6 +1,6 @@
begin
require 'rubygems'
- gem 'net-ssh', ">= 1.99.1"
+ gem 'net-ssh', ">= 2.0.10"
rescue LoadError, NameError
end
@@ -55,12 +55,32 @@ def self.connection_strategy(server, options={}, &block)
methods = [ %w(publickey hostbased), %w(password keyboard-interactive) ]
password_value = nil
- ssh_options = (server.options[:ssh_options] || {}).merge(options[:ssh_options] || {})
- user = server.user || options[:user] || ssh_options[:username] || ServerDefinition.default_user
- port = server.port || options[:port] || ssh_options[:port]
+ # construct the hash of ssh options that should be passed more-or-less
+ # directly to Net::SSH. This will be the general ssh options, merged with
+ # the server-specific ssh-options.
+ ssh_options = (options[:ssh_options] || {}).merge(server.options[:ssh_options] || {})
+
+ # load any SSH configuration files that were specified in the SSH options. This
+ # will load from ~/.ssh/config and /etc/ssh_config by default (see Net::SSH
+ # for details). Merge the explicitly given ssh_options over the top of the info
+ # from the config file.
+ ssh_options = Net::SSH.configuration_for(server.host, ssh_options.fetch(:config, true)).merge(ssh_options)
+
+ # Once we've loaded the config, we don't need Net::SSH to do it again.
+ ssh_options[:config] = false
+
+ user = server.user || options[:user] || ssh_options[:username] ||
+ ssh_options[:user] || ServerDefinition.default_user
+ port = server.port || options[:port] || ssh_options[:port]
+
+ # the .ssh/config file might have changed the host-name on us
+ host = ssh_options.fetch(:host_name, server.host)
ssh_options[:port] = port if port
+
+ # delete these, since we've determined which username to use by this point
ssh_options.delete(:username)
+ ssh_options.delete(:user)
begin
connection_options = ssh_options.merge(
@@ -68,7 +88,7 @@ def self.connection_strategy(server, options={}, &block)
:auth_methods => ssh_options[:auth_methods] || methods.shift
)
- yield server.host, user, connection_options
+ yield host, user, connection_options
rescue Net::SSH::AuthenticationFailed
raise if methods.empty? || ssh_options[:auth_methods]
password_value = options[:password]
View
11 test/configuration/connections_test.rb
@@ -30,6 +30,7 @@ def exists?(key)
def setup
@config = MockConfig.new
@config.stubs(:logger).returns(stub_everything)
+ Net::SSH.stubs(:configuration_for).returns({})
@ssh_options = {
:user => "user",
:port => 8080,
@@ -60,29 +61,29 @@ def test_default_connection_factory_honors_config_options
def test_should_connect_through_gateway_if_gateway_variable_is_set
@config.values[:gateway] = "j@gateway"
- Net::SSH::Gateway.expects(:new).with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
+ Net::SSH::Gateway.expects(:new).with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
end
def test_connection_factory_as_gateway_should_honor_config_options
@config.values[:gateway] = "gateway"
@config.values.update(@ssh_options)
- Net::SSH::Gateway.expects(:new).with("gateway", "user", :debug => :verbose, :port => 8080, :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
+ Net::SSH::Gateway.expects(:new).with("gateway", "user", :debug => :verbose, :port => 8080, :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
end
def test_connection_factory_as_gateway_should_chain_gateways_if_gateway_variable_is_an_array
@config.values[:gateway] = ["j@gateway1", "k@gateway2"]
gateway1 = mock
- Net::SSH::Gateway.expects(:new).with("gateway1", "j", :password => nil, :auth_methods => %w(publickey hostbased)).returns(gateway1)
+ Net::SSH::Gateway.expects(:new).with("gateway1", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(gateway1)
gateway1.expects(:open).returns(65535)
- Net::SSH::Gateway.expects(:new).with("127.0.0.1", "k", :port => 65535, :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
+ Net::SSH::Gateway.expects(:new).with("127.0.0.1", "k", :port => 65535, :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
end
def test_connection_factory_as_gateway_should_share_gateway_between_connections
@config.values[:gateway] = "j@gateway"
- Net::SSH::Gateway.expects(:new).once.with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased)).returns(stub_everything)
+ Net::SSH::Gateway.expects(:new).once.with("gateway", "j", :password => nil, :auth_methods => %w(publickey hostbased), :config => false).returns(stub_everything)
Capistrano::SSH.stubs(:connect).returns(stub_everything)
assert_instance_of Capistrano::Configuration::Connections::GatewayConnectionFactory, @config.connection_factory
@config.establish_connections_to(server("capistrano"))
View
10 test/ssh_test.rb
@@ -5,8 +5,10 @@ class SSHTest < Test::Unit::TestCase
def setup
Capistrano::ServerDefinition.stubs(:default_user).returns("default-user")
@options = { :password => nil,
- :auth_methods => %w(publickey hostbased) }
+ :auth_methods => %w(publickey hostbased),
+ :config => false }
@server = server("capistrano")
+ Net::SSH.stubs(:configuration_for).returns({})
end
def test_connect_with_bare_server_without_options_or_config_with_public_key_succeeding_should_only_loop_once
@@ -69,8 +71,8 @@ def test_connect_with_server_with_other_ssh_options_should_pass_ssh_options_to_n
end
def test_connect_with_ssh_options_should_use_ssh_options
- ssh_options = { :username => "JamisMan", :port => 8125 }
- Net::SSH.expects(:start).with(@server.host, "JamisMan", @options.merge(:port => 8125)).returns(success = Object.new)
+ ssh_options = { :username => "JamisMan", :port => 8125, :config => false }
+ Net::SSH.expects(:start).with(@server.host, "JamisMan", @options.merge(:port => 8125, :config => false)).returns(success = Object.new)
assert_equal success, Capistrano::SSH.connect(@server, {:ssh_options => ssh_options})
end
@@ -83,7 +85,7 @@ def test_connect_with_options_and_ssh_options_should_see_options_override_ssh_op
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, "jamis", @options.merge(:port => 1235, :forward_agent => true)).returns(success = Object.new)
+ Net::SSH.expects(:start).with(server.host, "jamis", @options.merge(:port => 1235, :forward_agent => true, :config => false)).returns(success = Object.new)
assert_equal success, Capistrano::SSH.connect(server, {:ssh_options => ssh_options})
end
Please sign in to comment.
Something went wrong with that request. Please try again.