diff options
Diffstat (limited to 'classes/Net/SSH/Multi/SessionActions.html')
-rw-r--r-- | classes/Net/SSH/Multi/SessionActions.html | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/classes/Net/SSH/Multi/SessionActions.html b/classes/Net/SSH/Multi/SessionActions.html new file mode 100644 index 0000000..ad9a7b4 --- /dev/null +++ b/classes/Net/SSH/Multi/SessionActions.html @@ -0,0 +1,272 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html lang='en'> + <head> + <title>: Net::SSH::Multi::SessionActions [Control multiple Net::SSH connections via a single interface.]</title> + <meta content='text/html; charset=utf-8' http-equiv='Content-Type'> + <link href='../../../../rdoc-style.css' media='screen' rel='stylesheet' type='text/css'> + <script type='text/javascript'> + //<![CDATA[ + function popupCode(url) { + window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400") + } + + function toggleCode(id) { + var code = document.getElementById(id) + + code.style.display = code.style.display != 'block' ? 'block' : 'none' + return true + } + + // Make codeblocks hidden by default + document.writeln('<' + 'style type="text/css">.method .source pre { display: none }<\/style>') + //]]> + </script> + </head> + <body class='page'> + <div class='class' id='wrapper'> + <div class='header'> + <h1 class='name'> + <span class='type'>Module</span> + Net::SSH::Multi::SessionActions + </h1> + <ol class='paths'> + <li> + <a href="../../../../files/lib/net/ssh/multi/session_actions_rb.html">lib/net/ssh/multi/session_actions.rb</a> + </li> + </ol> + </div> + <div id='content'> + <div id='text'> + <div id='description'> + <p> + This module represents the actions that are available on session + collections. Any class that includes this module needs only provide a + <tt>servers</tt> method that returns a list of <a + href="Server.html">Net::SSH::Multi::Server</a> instances, and the rest just + works. See <a href="Session.html">Net::SSH::Multi::Session</a> and <a + href="Subsession.html">Net::SSH::Multi::Subsession</a> for consumers of + this module. + </p> + </div> + <div id='method-list'> + <h2>Methods</h2> + <h3>public instance</h3> + <ol> + <li><a href="#M000004">busy?</a></li> + <li><a href="#M000003">connect!</a></li> + <li><a href="#M000008">exec</a></li> + <li><a href="#M000002">master</a></li> + <li><a href="#M000007">open_channel</a></li> + <li><a href="#M000006">send_global_request</a></li> + <li><a href="#M000005">sessions</a></li> + </ol> + </div> + <div id='section'> + <div id='methods'> + <h2>Public instance methods</h2> + <div class='method public-instance' id='method-M000004'> + <a name='M000004'> </a> + <div class='synopsis'> + <span class='name'>busy?</span> + <span class='arguments'>(include_invisible=false)</span> + </div> + <div class='description'> + <p> + Returns <tt>true</tt> if any server in the current container has an open <a + href="../../SSH.html">SSH</a> session that is currently processing any + channels. If <tt>include_invisible</tt> is <tt>false</tt> (the default) + then invisible channels (such as those created by port forwarding) will not + be counted; otherwise, they will be. + </p> + </div> + <div class='source'> + <a class='source-toggle' href='#' onclick="toggleCode('M000004-source'); return false"> + [show source] + </a> + <pre id='M000004-source'> <span class="ruby-comment cmt"># File lib/net/ssh/multi/session_actions.rb, line 29</span>
29: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">busy?</span>(<span class="ruby-identifier">include_invisible</span>=<span class="ruby-keyword kw">false</span>)
30: <span class="ruby-identifier">servers</span>.<span class="ruby-identifier">any?</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">server</span><span class="ruby-operator">|</span> <span class="ruby-identifier">server</span>.<span class="ruby-identifier">busy?</span>(<span class="ruby-identifier">include_invisible</span>) }
31: <span class="ruby-keyword kw">end</span></pre> + </div> + </div> + <div class='method public-instance' id='method-M000003'> + <a name='M000003'> </a> + <div class='synopsis'> + <span class='name'>connect!</span> + <span class='arguments'>()</span> + </div> + <div class='description'> + <p> + 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. + </p> + </div> + <div class='source'> + <a class='source-toggle' href='#' onclick="toggleCode('M000003-source'); return false"> + [show source] + </a> + <pre id='M000003-source'> <span class="ruby-comment cmt"># File lib/net/ssh/multi/session_actions.rb, line 20</span>
20: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">connect!</span>
21: <span class="ruby-identifier">sessions</span>
22: <span class="ruby-keyword kw">self</span>
23: <span class="ruby-keyword kw">end</span></pre> + </div> + </div> + <div class='method public-instance' id='method-M000008'> + <a name='M000008'> </a> + <div class='synopsis'> + <span class='name'>exec</span> + <span class='arguments'>(command, &block)</span> + </div> + <div class='description'> + <p> + 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 <a href="SessionActions.html#M000007">open_channel</a> and + active_sessions), and then executes a command on each channel + (Net::SSH::Connection::Channel#exec). + </p> + <p> + 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 (<tt>:stdout</tt> or + <tt>:stderr</tt>) and a string containing the data that was received: + </p> + <pre>session.exec("command") do |ch, stream, data|
 puts "[#{ch[:host]} : #{stream}] #{data}"
end</pre> + <p> + If no block is given, all output will be written to +$stdout+ or +$stderr+, + as appropriate. + </p> + <p> + Note that <a href="SessionActions.html#M000008">exec</a> will also capture + the exit status of the process in the <tt>:exit_status</tt> property of + each channel. Since <a href="SessionActions.html#M000008">exec</a> returns + all of the channels in a <a + href="Channel.html">Net::SSH::Multi::Channel</a> object, you can check for + the exit status like this: + </p> + <pre>channel = session.exec("command") { ... }
channel.wait

if channel.any? { |c| c[:exit_status] != 0 }
 puts "executing failed on at least one host!"
end</pre> + </div> + <div class='source'> + <a class='source-toggle' href='#' onclick="toggleCode('M000008-source'); return false"> + [show source] + </a> + <pre id='M000008-source'> <span class="ruby-comment cmt"># File lib/net/ssh/multi/session_actions.rb, line 119</span>
119: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">exec</span>(<span class="ruby-identifier">command</span>, <span class="ruby-operator">&</span><span class="ruby-identifier">block</span>)
120: <span class="ruby-identifier">open_channel</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">channel</span><span class="ruby-operator">|</span>
121: <span class="ruby-identifier">channel</span>.<span class="ruby-identifier">exec</span>(<span class="ruby-identifier">command</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">ch</span>, <span class="ruby-identifier">success</span><span class="ruby-operator">|</span>
122: <span class="ruby-identifier">raise</span> <span class="ruby-node">"could not execute command: #{command.inspect} (#{ch[:host]})"</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">success</span>
123: 
124: <span class="ruby-identifier">channel</span>.<span class="ruby-identifier">on_data</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">ch</span>, <span class="ruby-identifier">data</span><span class="ruby-operator">|</span>
125: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">block</span>
126: <span class="ruby-identifier">block</span>.<span class="ruby-identifier">call</span>(<span class="ruby-identifier">ch</span>, <span class="ruby-identifier">:stdout</span>, <span class="ruby-identifier">data</span>)
127: <span class="ruby-keyword kw">else</span>
128: <span class="ruby-identifier">data</span>.<span class="ruby-identifier">chomp</span>.<span class="ruby-identifier">each_line</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">line</span><span class="ruby-operator">|</span>
129: <span class="ruby-identifier">$stdout</span>.<span class="ruby-identifier">puts</span>(<span class="ruby-node">"[#{ch[:host]}] #{line}"</span>)
130: <span class="ruby-keyword kw">end</span>
131: <span class="ruby-keyword kw">end</span>
132: <span class="ruby-keyword kw">end</span>
133: 
134: <span class="ruby-identifier">channel</span>.<span class="ruby-identifier">on_extended_data</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">ch</span>, <span class="ruby-identifier">type</span>, <span class="ruby-identifier">data</span><span class="ruby-operator">|</span>
135: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">block</span>
136: <span class="ruby-identifier">block</span>.<span class="ruby-identifier">call</span>(<span class="ruby-identifier">ch</span>, <span class="ruby-identifier">:stderr</span>, <span class="ruby-identifier">data</span>)
137: <span class="ruby-keyword kw">else</span>
138: <span class="ruby-identifier">data</span>.<span class="ruby-identifier">chomp</span>.<span class="ruby-identifier">each_line</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">line</span><span class="ruby-operator">|</span>
139: <span class="ruby-identifier">$stderr</span>.<span class="ruby-identifier">puts</span>(<span class="ruby-node">"[#{ch[:host]}] #{line}"</span>)
140: <span class="ruby-keyword kw">end</span>
141: <span class="ruby-keyword kw">end</span>
142: <span class="ruby-keyword kw">end</span>
143: 
144: <span class="ruby-identifier">channel</span>.<span class="ruby-identifier">on_request</span>(<span class="ruby-value str">"exit-status"</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">ch</span>, <span class="ruby-identifier">data</span><span class="ruby-operator">|</span>
145: <span class="ruby-identifier">ch</span>[<span class="ruby-identifier">:exit_status</span>] = <span class="ruby-identifier">data</span>.<span class="ruby-identifier">read_long</span>
146: <span class="ruby-keyword kw">end</span>
147: <span class="ruby-keyword kw">end</span>
148: <span class="ruby-keyword kw">end</span>
149: <span class="ruby-keyword kw">end</span></pre> + </div> + </div> + <div class='method public-instance' id='method-M000002'> + <a name='M000002'> </a> + <div class='synopsis'> + <span class='name'>master</span> + <span class='arguments'>()</span> + </div> + <div class='description'> + <p> + Returns the session that is the “master”. This defaults to + <tt>self</tt>, but classes that include this module may wish to change this + if they are subsessions that depend on a master session. + </p> + </div> + <div class='source'> + <a class='source-toggle' href='#' onclick="toggleCode('M000002-source'); return false"> + [show source] + </a> + <pre id='M000002-source'> <span class="ruby-comment cmt"># File lib/net/ssh/multi/session_actions.rb, line 12</span>
12: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">master</span>
13: <span class="ruby-keyword kw">self</span>
14: <span class="ruby-keyword kw">end</span></pre> + </div> + </div> + <div class='method public-instance' id='method-M000007'> + <a name='M000007'> </a> + <div class='synopsis'> + <span class='name'>open_channel</span> + <span class='arguments'>(type="session", *extra, &on_confirm)</span> + </div> + <div class='description'> + <p> + Asks all sessions for all contained servers (see <a + href="SessionActions.html#M000005">sessions</a>) to open a new channel. + When each server responds, the <tt>on_confirm</tt> 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. + </p> + <p> + All new channels will be collected and returned, aggregated into a new <a + href="Channel.html">Net::SSH::Multi::Channel</a> instance. + </p> + <p> + 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: + </p> + <ul> + <li>:server => the <a href="Server.html">Net::SSH::Multi::Server</a> instance + that spawned the channel + + </li> + <li>:host => the host name of the server + + </li> + </ul> + <p> + Having access to these things lets you more easily report which host (e.g.) + data was received from: + </p> + <pre>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</pre> + </div> + <div class='source'> + <a class='source-toggle' href='#' onclick="toggleCode('M000007-source'); return false"> + [show source] + </a> + <pre id='M000007-source'> <span class="ruby-comment cmt"># File lib/net/ssh/multi/session_actions.rb, line 80</span>
80: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">open_channel</span>(<span class="ruby-identifier">type</span>=<span class="ruby-value str">"session"</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">extra</span>, <span class="ruby-operator">&</span><span class="ruby-identifier">on_confirm</span>)
81: <span class="ruby-identifier">channels</span> = <span class="ruby-identifier">sessions</span>.<span class="ruby-identifier">map</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">ssh</span><span class="ruby-operator">|</span>
82: <span class="ruby-identifier">ssh</span>.<span class="ruby-identifier">open_channel</span>(<span class="ruby-identifier">type</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">extra</span>) <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">c</span><span class="ruby-operator">|</span>
83: <span class="ruby-identifier">c</span>[<span class="ruby-identifier">:server</span>] = <span class="ruby-identifier">c</span>.<span class="ruby-identifier">connection</span>[<span class="ruby-identifier">:server</span>]
84: <span class="ruby-identifier">c</span>[<span class="ruby-identifier">:host</span>] = <span class="ruby-identifier">c</span>.<span class="ruby-identifier">connection</span>[<span class="ruby-identifier">:server</span>].<span class="ruby-identifier">host</span>
85: <span class="ruby-identifier">on_confirm</span>[<span class="ruby-identifier">c</span>] <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">on_confirm</span>
86: <span class="ruby-keyword kw">end</span>
87: <span class="ruby-keyword kw">end</span>
88: <span class="ruby-constant">Multi</span><span class="ruby-operator">::</span><span class="ruby-constant">Channel</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">master</span>, <span class="ruby-identifier">channels</span>)
89: <span class="ruby-keyword kw">end</span></pre> + </div> + </div> + <div class='method public-instance' id='method-M000006'> + <a name='M000006'> </a> + <div class='synopsis'> + <span class='name'>send_global_request</span> + <span class='arguments'>(type, *extra, &callback)</span> + </div> + <div class='description'> + <p> + Sends a global request to the sessions for all contained servers (see <a + href="SessionActions.html#M000005">sessions</a>). This can be used to + (e.g.) ping the remote servers to prevent them from timing out. + </p> + <pre>session.send_global_request("keep-alive@openssh.com")</pre> + <p> + If a block is given, it will be invoked when the server responds, with two + arguments: the <a href="../../SSH.html">Net::SSH</a> connection that is + responding, and a boolean indicating whether the request succeeded or not. + </p> + </div> + <div class='source'> + <a class='source-toggle' href='#' onclick="toggleCode('M000006-source'); return false"> + [show source] + </a> + <pre id='M000006-source'> <span class="ruby-comment cmt"># File lib/net/ssh/multi/session_actions.rb, line 50</span>
50: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">send_global_request</span>(<span class="ruby-identifier">type</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">extra</span>, <span class="ruby-operator">&</span><span class="ruby-identifier">callback</span>)
51: <span class="ruby-identifier">sessions</span>.<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">ssh</span><span class="ruby-operator">|</span> <span class="ruby-identifier">ssh</span>.<span class="ruby-identifier">send_global_request</span>(<span class="ruby-identifier">type</span>, <span class="ruby-operator">*</span><span class="ruby-identifier">extra</span>, <span class="ruby-operator">&</span><span class="ruby-identifier">callback</span>) }
52: <span class="ruby-keyword kw">self</span>
53: <span class="ruby-keyword kw">end</span></pre> + </div> + </div> + <div class='method public-instance' id='method-M000005'> + <a name='M000005'> </a> + <div class='synopsis'> + <span class='name'>sessions</span> + <span class='arguments'>()</span> + </div> + <div class='description'> + <p> + Returns an array of all <a href="../../SSH.html">SSH</a> sessions, blocking + until all sessions have connected. + </p> + </div> + <div class='source'> + <a class='source-toggle' href='#' onclick="toggleCode('M000005-source'); return false"> + [show source] + </a> + <pre id='M000005-source'> <span class="ruby-comment cmt"># File lib/net/ssh/multi/session_actions.rb, line 35</span>
35: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">sessions</span>
36: <span class="ruby-identifier">threads</span> = <span class="ruby-identifier">servers</span>.<span class="ruby-identifier">map</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">server</span><span class="ruby-operator">|</span> <span class="ruby-constant">Thread</span>.<span class="ruby-identifier">new</span> { <span class="ruby-identifier">server</span>.<span class="ruby-identifier">session</span>(<span class="ruby-keyword kw">true</span>) } <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">server</span>.<span class="ruby-identifier">session</span>.<span class="ruby-identifier">nil?</span> }
37: <span class="ruby-identifier">threads</span>.<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">thread</span><span class="ruby-operator">|</span> <span class="ruby-identifier">thread</span>.<span class="ruby-identifier">join</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">thread</span> }
38: <span class="ruby-identifier">servers</span>.<span class="ruby-identifier">map</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">server</span><span class="ruby-operator">|</span> <span class="ruby-identifier">server</span>.<span class="ruby-identifier">session</span> }.<span class="ruby-identifier">compact</span>
39: <span class="ruby-keyword kw">end</span></pre> + </div> + </div> + </div> + </div> + </div> + </div> + <div id='footer-push'></div> + </div> + <div id='footer'> + <a href="http://github.com/mislav/hanna/tree/master"><strong>Hanna</strong> RDoc template</a> + </div> + </body> +</html> |