1
0
Fork 0
mirror of https://github.com/capistrano/capistrano synced 2023-03-27 23:21:18 -04:00

Use 'user' from .ssh/config appropriately, and bump Net::SSH dependency to 2.0.10

This commit is contained in:
Jamis Buck 2009-02-02 23:11:22 -07:00
parent f70fccaf37
commit 9a281b2d13
5 changed files with 42 additions and 15 deletions

View file

@ -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 file

@ -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 file

@ -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 @@ module Capistrano
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 @@ module Capistrano
: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 file

@ -30,6 +30,7 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
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 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
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 file

@ -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 @@ class SSHTest < Test::Unit::TestCase
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 @@ class SSHTest < Test::Unit::TestCase
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