Class: Net::SSH::Multi::Server

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/net/ssh/multi/server.rb

Overview

Encapsulates the connection information for a single remote server, as well as the Net::SSH session corresponding to that information. You’ll rarely need to instantiate one of these directly: instead, you should use Net::SSH::Multi::Session#use.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(master, host, options = {}) ⇒ Server

Creates a new Server instance with the given connection information. The master argument must be a reference to the Net::SSH::Multi::Session instance that will manage this server reference. The options hash must conform to the options described for Net::SSH::start, with two additions:

  • :via => a Net::SSH::Gateway instance to use when establishing a connection to this server.

  • :user => the name of the user to use when logging into this server.

The host argument may include the username and port number, in which case those values take precedence over similar values given in the options:

server = Net::SSH::Multi::Server.new(session, 'user@host:1234')
puts server.user #-> user
puts server.port #-> 1234


43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/net/ssh/multi/server.rb', line 43

def initialize(master, host, options={})
  @master = master
  @options = options.dup

  @user, @host, port = host.match(/^(?:([^;,:=]+)@|)(.*?)(?::(\d+)|)$/)[1,3]

  user_opt, port_opt = @options.delete(:user), @options.delete(:port)

  @user = @user || user_opt || master.default_user
  port ||= port_opt

  @options[:port] = port.to_i if port

  @gateway = @options.delete(:via)
  @failed = false
end

Instance Attribute Details

#gatewayObject (readonly)

The Net::SSH::Gateway instance to use to establish the connection. Will be nil if the connection should be established without a gateway.



26
27
28
# File 'lib/net/ssh/multi/server.rb', line 26

def gateway
  @gateway
end

#hostObject (readonly)

The host name (or IP address) of the server to connect to.



15
16
17
# File 'lib/net/ssh/multi/server.rb', line 15

def host
  @host
end

#masterObject (readonly)

The Net::SSH::Multi::Session instance that manages this server instance.



12
13
14
# File 'lib/net/ssh/multi/server.rb', line 12

def master
  @master
end

#optionsObject (readonly)

The Hash of additional options to pass to Net::SSH when connecting (including things like :password, and so forth).



22
23
24
# File 'lib/net/ssh/multi/server.rb', line 22

def options
  @options
end

#userObject (readonly)

The user name to use when logging into the server.



18
19
20
# File 'lib/net/ssh/multi/server.rb', line 18

def user
  @user
end

Instance Method Details

#<=>(server) ⇒ Object

Gives server definitions a sort order, and allows comparison.



79
80
81
# File 'lib/net/ssh/multi/server.rb', line 79

def <=>(server)
  [host, port, user] <=> [server.host, server.port, server.user]
end

#[](key) ⇒ Object

Returns the value of the server property with the given key. Server properties are described via the :properties key in the options hash when defining the Server.



63
64
65
# File 'lib/net/ssh/multi/server.rb', line 63

def [](key)
  (options[:properties] || {})[key]
end

#[]=(key, value) ⇒ Object

Sets the given key/value pair in the :properties key in the options hash. If the options hash has no :properties key, it will be created.



69
70
71
# File 'lib/net/ssh/multi/server.rb', line 69

def []=(key, value)
  (options[:properties] ||= {})[key] = value
end

#busy?(include_invisible = false) ⇒ Boolean

Returns true if the session has been opened, and the session is currently busy (as defined by Net::SSH::Connection::Session#busy?).

Returns:

  • (Boolean)


143
144
145
# File 'lib/net/ssh/multi/server.rb', line 143

def busy?(include_invisible=false)
  session && session.busy?(include_invisible)
end

#closeObject

Closes this server’s session. If the session has not yet been opened, this does nothing.



149
150
151
152
153
154
# File 'lib/net/ssh/multi/server.rb', line 149

def close
  session.close if session
ensure
  master.server_closed(self) if session
  @session = nil
end

#close_channelsObject

Closes all open channels on this server’s session. If the session has not yet been opened, this does nothing.



198
199
200
# File 'lib/net/ssh/multi/server.rb', line 198

def close_channels #:nodoc:
  session.channels.each { |id, channel| channel.close } if session
end

#fail!(flag = true) ⇒ Object

Indicates (by default) that this server has just failed a connection attempt. If flag is false, this can be used to reset the failed flag so that a retry may be attempted.



115
116
117
# File 'lib/net/ssh/multi/server.rb', line 115

def fail!(flag=true)
  @failed = flag
end

#failed?Boolean

Returns true if this server has ever failed a connection attempt.

Returns:

  • (Boolean)


108
109
110
# File 'lib/net/ssh/multi/server.rb', line 108

def failed?
  @failed
end

#hashObject

Generates a Fixnum hash value for this object. This function has the property that a.eql?(b) implies a.hash == b.hash. The hash value is used by class Hash. Any hash value that exceeds the capacity of a Fixnum will be truncated before being used.



89
90
91
# File 'lib/net/ssh/multi/server.rb', line 89

def hash
  @hash ||= [host, user, port].hash
end

#inspectObject

Returns a human-readable representation of this server instance.



103
104
105
# File 'lib/net/ssh/multi/server.rb', line 103

def inspect
  @inspect ||= "#<%s:0x%x %s>" % [self.class.name, object_id, to_s]
end

#new_sessionObject

Returns a new session object based on this server’s connection criteria. Note that this will not associate the session with the server, and should not be called directly; it is called internally from Net::SSH::Multi::Session when a new session is required.



181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/net/ssh/multi/server.rb', line 181

def new_session #:nodoc:
  session = if gateway
    gateway.ssh(host, user, options)
  else
    Net::SSH.start(host, user, options)
  end

  session[:server] = self
  session
rescue ::Timeout::Error => error
  raise Net::SSH::ConnectionTimeout.new("#{error.message} for #{host}")
rescue Net::SSH::AuthenticationFailed => error
  raise Net::SSH::AuthenticationFailed.new("#{error.message}@#{host}")
end

#portObject

Returns the port number to use for this connection.



74
75
76
# File 'lib/net/ssh/multi/server.rb', line 74

def port
  options[:port] || 22
end

#postprocess(readers, writers) ⇒ Object

Runs the post-process action on the session, if the session has been opened. Only the readers and writers that actually belong to this session will be postprocessed by this server.



225
226
227
228
229
# File 'lib/net/ssh/multi/server.rb', line 225

def postprocess(readers, writers) #:nodoc:
  return true unless session
  listeners = session.listeners.keys
  session.postprocess(listeners & readers, listeners & writers)
end

#preprocessObject

Runs the session’s preprocess action, if the session has been opened.



203
204
205
# File 'lib/net/ssh/multi/server.rb', line 203

def preprocess #:nodoc:
  session.preprocess if session
end

#readersObject

Returns all registered readers on the session, or an empty array if the session is not open.



209
210
211
212
# File 'lib/net/ssh/multi/server.rb', line 209

def readers #:nodoc:
  return [] unless session
  session.listeners.keys.reject { |io| io.closed? }
end

#replace_session(session) ⇒ Object

Indicate that the session currently in use by this server instance should be replaced by the given session argument. This is used when a pending session has been “realized”. Note that this does not actually replace the session–see #update_session! for that.



162
163
164
# File 'lib/net/ssh/multi/server.rb', line 162

def replace_session(session) #:nodoc:
  @ready_session = session
end

#session(require_session = false) ⇒ Object

Returns the Net::SSH session object for this server. If require_session is false and the session has not previously been created, this will return nil. If require_session is true, the session will be instantiated if it has not already been instantiated, via the gateway if one is given, or directly (via Net::SSH::start) otherwise.

if server.session.nil?
  puts "connecting..."
  server.session(true)
end

Note that the sessions returned by this are “enhanced” slightly, to make them easier to deal with in a multi-session environment: they have a :server property automatically set on them, that refers to this object (the Server instance that spawned them).

assert_equal server, server.session[:server]


136
137
138
139
# File 'lib/net/ssh/multi/server.rb', line 136

def session(require_session=false)
  return @session if @session || !require_session
  @session ||= master.next_session(self)
end

#to_sObject

Returns a human-readable representation of this server instance.



94
95
96
97
98
99
100
# File 'lib/net/ssh/multi/server.rb', line 94

def to_s
  @to_s ||= begin
    s = "#{user}@#{host}"
    s << ":#{options[:port]}" if options[:port]
    s
  end
end

#update_session!Object

If a new session has been made ready (see #replace_session), this will replace the current session with the “ready” session. This method is called from the event loop to ensure that sessions are swapped in at the appropriate point (instead of in the middle of an event poll).



171
172
173
174
175
# File 'lib/net/ssh/multi/server.rb', line 171

def update_session! #:nodoc:
  if @ready_session
    @session, @ready_session = @ready_session, nil
  end
end

#writersObject

Returns all registered and pending writers on the session, or an empty array if the session is not open.



216
217
218
219
220
# File 'lib/net/ssh/multi/server.rb', line 216

def writers #:nodoc:
  readers.select do |io|
    io.respond_to?(:pending_write?) && io.pending_write?
  end
end