Module Net::SSH::Multi::SessionActions
In: lib/net/ssh/multi/session_actions.rb

This module represents the actions that are available on session collections. Any class that includes this module needs only provide a servers method that returns a list of Net::SSH::Multi::Server instances, and the rest just works. See Net::SSH::Multi::Session and Net::SSH::Multi::Subsession for consumers of this module.

Methods

Public Instance methods

Returns true if any server in the current container has an open SSH session that is currently processing any channels. If include_invisible is false (the default) then invisible channels (such as those created by port forwarding) will not be counted; otherwise, they will be.

[Source]

    # File lib/net/ssh/multi/session_actions.rb, line 29
29:     def busy?(include_invisible=false)
30:       servers.any? { |server| server.busy?(include_invisible) }
31:     end

Connections are normally established lazily, as soon as they are needed. This method forces all servers in the current container to have their connections established immediately, blocking until the connections have been made.

[Source]

    # File lib/net/ssh/multi/session_actions.rb, line 20
20:     def connect!
21:       sessions
22:       self
23:     end

A convenience method for executing a command on multiple hosts and either displaying or capturing the output. It opens a channel on all active sessions (see open_channel and active_sessions), and then executes a command on each channel (Net::SSH::Connection::Channel#exec).

If a block is given, it will be invoked whenever data is received across the channel, with three arguments: the channel object, a symbol identifying which output stream the data was received on (+:stdout+ or +:stderr+) and a string containing the data that was received:

  session.exec("command") do |ch, stream, data|
    puts "[#{ch[:host]} : #{stream}] #{data}"
  end

If no block is given, all output will be written to +$stdout+ or +$stderr+, as appropriate.

Note that exec will also capture the exit status of the process in the +:exit_status+ property of each channel. Since exec returns all of the channels in a Net::SSH::Multi::Channel object, you can check for the exit status like this:

  channel = session.exec("command") { ... }
  channel.wait

  if channel.any? { |c| c[:exit_status] != 0 }
    puts "executing failed on at least one host!"
  end

[Source]

     # File lib/net/ssh/multi/session_actions.rb, line 119
119:     def exec(command, &block)
120:       open_channel do |channel|
121:         channel.exec(command) do |ch, success|
122:           raise "could not execute command: #{command.inspect} (#{ch[:host]})" unless success
123: 
124:           channel.on_data do |ch, data|
125:             if block
126:               block.call(ch, :stdout, data)
127:             else
128:               data.chomp.each_line do |line|
129:                 $stdout.puts("[#{ch[:host]}] #{line}")
130:               end
131:             end
132:           end
133: 
134:           channel.on_extended_data do |ch, type, data|
135:             if block
136:               block.call(ch, :stderr, data)
137:             else
138:               data.chomp.each_line do |line|
139:                 $stderr.puts("[#{ch[:host]}] #{line}")
140:               end
141:             end
142:           end
143: 
144:           channel.on_request("exit-status") do |ch, data|
145:             ch[:exit_status] = data.read_long
146:           end
147:         end
148:       end
149:     end

Returns the session that is the "master". This defaults to self, but classes that include this module may wish to change this if they are subsessions that depend on a master session.

[Source]

    # File lib/net/ssh/multi/session_actions.rb, line 12
12:     def master
13:       self
14:     end

Asks all sessions for all contained servers (see sessions) to open a new channel. When each server responds, the on_confirm block will be invoked with a single argument, the channel object for that server. This means that the block will be invoked one time for each session.

All new channels will be collected and returned, aggregated into a new Net::SSH::Multi::Channel instance.

Note that the channels are "enhanced" slightly—they have two properties set on them automatically, to make dealing with them in a multi-session environment slightly easier:

Having access to these things lets you more easily report which host (e.g.) data was received from:

  session.open_channel do |channel|
    channel.exec "command" do |ch, success|
      ch.on_data do |ch, data|
        puts "got data #{data} from #{ch[:host]}"
      end
    end
  end

[Source]

    # File lib/net/ssh/multi/session_actions.rb, line 80
80:     def open_channel(type="session", *extra, &on_confirm)
81:       channels = sessions.map do |ssh|
82:         ssh.open_channel(type, *extra) do |c|
83:           c[:server] = c.connection[:server]
84:           c[:host] = c.connection[:server].host
85:           on_confirm[c] if on_confirm
86:         end
87:       end
88:       Multi::Channel.new(master, channels)
89:     end

Sends a global request to the sessions for all contained servers (see sessions). This can be used to (e.g.) ping the remote servers to prevent them from timing out.

  session.send_global_request("keep-alive@openssh.com")

If a block is given, it will be invoked when the server responds, with two arguments: the Net::SSH connection that is responding, and a boolean indicating whether the request succeeded or not.

[Source]

    # File lib/net/ssh/multi/session_actions.rb, line 50
50:     def send_global_request(type, *extra, &callback)
51:       sessions.each { |ssh| ssh.send_global_request(type, *extra, &callback) }
52:       self
53:     end

Returns an array of all SSH sessions, blocking until all sessions have connected.

[Source]

    # File lib/net/ssh/multi/session_actions.rb, line 35
35:     def sessions
36:       threads = servers.map { |server| Thread.new { server.session(true) } if server.session.nil? }
37:       threads.each { |thread| thread.join if thread }
38:       servers.map { |server| server.session }.compact
39:     end

[Validate]