A helper class for dealing with SSH connections.
An abstraction to make it possible to connect to the server via public key without prompting for the password. If the public key authentication fails this will fall back to password authentication.
server must be an instance of ServerDefinition.
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.
# File lib/capistrano/ssh.rb, line 33 33: def self.connect(server, options={}) 34: connection_strategy(server, options) do |host, user, connection_options| 35: connection = Net::SSH.start(host, user, connection_options) 36: Server.apply_to(connection, server) 37: end 38: end
Abstracts the logic for establishing an SSH connection (which includes testing for connection failures and retrying with a password, and so forth, mostly made complicated because of the fact that some of these variables might be lazily evaluated and try to do something like prompt the user, which should only happen when absolutely necessary.
This will yield the hostname, username, and a hash of connection options to the given block, which should return a new connection.
# File lib/capistrano/ssh.rb, line 48 48: def self.connection_strategy(server, options={}, &block) 49: methods = [ %(publickey hostbased), %(password keyboard-interactive) ] 50: password_value = nil 51: 52: # construct the hash of ssh options that should be passed more-or-less 53: # directly to Net::SSH. This will be the general ssh options, merged with 54: # the server-specific ssh-options. 55: ssh_options = (options[:ssh_options] || {}).merge(server.options[:ssh_options] || {}) 56: 57: # load any SSH configuration files that were specified in the SSH options. This 58: # will load from ~/.ssh/config and /etc/ssh_config by default (see Net::SSH 59: # for details). Merge the explicitly given ssh_options over the top of the info 60: # from the config file. 61: ssh_options = Net::SSH.configuration_for(server.host, ssh_options.fetch(:config, true)).merge(ssh_options) 62: 63: # Once we've loaded the config, we don't need Net::SSH to do it again. 64: ssh_options[:config] = false 65: 66: ssh_options[:verbose] = :debug if options[:verbose] && options[:verbose] > 0 67: 68: user = server.user || options[:user] || ssh_options[:username] || 69: ssh_options[:user] || ServerDefinition.default_user 70: port = server.port || options[:port] || ssh_options[:port] 71: 72: # the .ssh/config file might have changed the host-name on us 73: host = ssh_options.fetch(:host_name, server.host) 74: 75: ssh_options[:port] = port if port 76: 77: # delete these, since we've determined which username to use by this point 78: ssh_options.delete(:username) 79: ssh_options.delete(:user) 80: 81: begin 82: connection_options = ssh_options.merge( 83: :password => password_value, 84: :auth_methods => ssh_options[:auth_methods] || methods.shift 85: ) 86: 87: yield host, user, connection_options 88: rescue Net::SSH::AuthenticationFailed 89: raise if methods.empty? || ssh_options[:auth_methods] 90: password_value = options[:password] 91: retry 92: end 93: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.