1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
|
<!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::Session</title>
<meta content='text/html; charset=US-ASCII' http-equiv='Content-Type'>
<link href='../../../../css/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'>class</span>
Net::SSH::Multi::Session
</h1>
<ol class='paths'>
<li>
<a target="docwin" href="../../../../files/lib/net/ssh/multi/session_rb.html">lib/net/ssh/multi/session.rb</a>
</li>
</ol>
<div class='parent'>
Parent:
<strong><a target="docwin" href="../Multi.html">Multi</a></strong>
</div>
</div>
<div id='content'>
<div id='text'>
<div id='description'>
<p>Represents a collection of connections to various servers. It provides an
interface for organizing the connections (<a
href="Session.html#method-i-group">group</a>), as well as a way to scope
commands to a subset of all connections (<a
href="Session.html#method-i-with">with</a>). You can also provide a default
gateway connection that servers should use when connecting (<a
href="Session.html#method-i-via">via</a>). It exposes an interface similar
to Net::SSH::Connection::Session for opening <a
href="../../SSH.html">SSH</a> channels and executing commands, allowing for
these operations to be done in parallel across multiple connections.</p>
<pre class="ruby"><span class="ruby-constant">Net</span><span class="ruby-operator">::</span><span class="ruby-constant">SSH</span><span class="ruby-operator">::</span><span class="ruby-constant">Multi</span>.<span class="ruby-identifier">start</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">session</span><span class="ruby-operator">|</span>
 <span class="ruby-comment"># access servers via a gateway</span>
 <span class="ruby-identifier">session</span>.<span class="ruby-identifier">via</span> <span class="ruby-string">'gateway'</span>, <span class="ruby-string">'gateway-user'</span>

 <span class="ruby-comment"># define the servers we want to use</span>
 <span class="ruby-identifier">session</span>.<span class="ruby-identifier">use</span> <span class="ruby-string">'user1@host1'</span>
 <span class="ruby-identifier">session</span>.<span class="ruby-identifier">use</span> <span class="ruby-string">'user2@host2'</span>

 <span class="ruby-comment"># define servers in groups for more granular access</span>
 <span class="ruby-identifier">session</span>.<span class="ruby-identifier">group</span> :<span class="ruby-identifier">app</span> <span class="ruby-keyword">do</span>
 <span class="ruby-identifier">session</span>.<span class="ruby-identifier">use</span> <span class="ruby-string">'user@app1'</span>
 <span class="ruby-identifier">session</span>.<span class="ruby-identifier">use</span> <span class="ruby-string">'user@app2'</span>
 <span class="ruby-keyword">end</span>

 <span class="ruby-comment"># execute commands on all servers</span>
 <span class="ruby-identifier">session</span>.<span class="ruby-identifier">exec</span> <span class="ruby-string">"uptime"</span>

 <span class="ruby-comment"># execute commands on a subset of servers</span>
 <span class="ruby-identifier">session</span>.<span class="ruby-identifier">with</span>(:<span class="ruby-identifier">app</span>).<span class="ruby-identifier">exec</span> <span class="ruby-string">"hostname"</span>

 <span class="ruby-comment"># run the aggregated event loop</span>
 <span class="ruby-identifier">session</span>.<span class="ruby-identifier">loop</span>
<span class="ruby-keyword">end</span></pre>
<p>Note that connections are established lazily, as soon as they are needed.
You can force the connections to be opened immediately, though, using the
<a href="SessionActions.html#method-i-connect-21">connect!</a> method.</p>
<h2 id="label-Concurrent+Connection+Limiting">Concurrent Connection Limiting</h2>
<p>Sometimes you may be dealing with a large number of servers, and if you try
to have connections open to all of them simultaneously you'll run into open
file handle limitations and such. If this happens to you, you can set the
<a
href="Session.html#attribute-i-concurrent_connections">concurrent_connections</a>
property of the session. <a href="../Multi.html">Net::SSH::Multi</a> will
then ensure that no more than this number of connections are ever open
simultaneously.</p>
<pre class="ruby"><span class="ruby-constant">Net</span><span class="ruby-operator">::</span><span class="ruby-constant">SSH</span><span class="ruby-operator">::</span><span class="ruby-constant">Multi</span>.<span class="ruby-identifier">start</span>(:<span class="ruby-identifier">concurrent_connections</span> =<span class="ruby-operator">></span> <span class="ruby-value">5</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">session</span><span class="ruby-operator">|</span>
 <span class="ruby-comment"># ...</span>
<span class="ruby-keyword">end</span></pre>
<p>Opening channels and executing commands will still work exactly as before,
but <a href="../Multi.html">Net::SSH::Multi</a> will transparently close
finished connections and open pending ones.</p>
<h2 id="label-Controlling+Connection+Errors">Controlling Connection Errors</h2>
<p>By default, <a href="../Multi.html">Net::SSH::Multi</a> will raise an
exception if a connection error occurs when connecting to a server. This
will typically bubble up and abort the entire connection process.
Sometimes, however, you might wish to ignore connection errors, for
instance when starting a daemon on a large number of boxes and you know
that some of the boxes are going to be unavailable.</p>
<p>To do this, simply set the <a
href="Session.html#attribute-i-on_error">on_error</a> property of the
session to :ignore (or to :warn, if you want a warning message when a
connection attempt fails):</p>
<pre class="ruby"><span class="ruby-constant">Net</span><span class="ruby-operator">::</span><span class="ruby-constant">SSH</span><span class="ruby-operator">::</span><span class="ruby-constant">Multi</span>.<span class="ruby-identifier">start</span>(:<span class="ruby-identifier">on_error</span> =<span class="ruby-operator">></span> :<span class="ruby-identifier">ignore</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">session</span><span class="ruby-operator">|</span>
 <span class="ruby-comment"># ...</span>
<span class="ruby-keyword">end</span></pre>
<p>The default is :fail, which causes the exception to bubble up.
Additionally, you can specify a Proc object as the value for <a
href="Session.html#attribute-i-on_error">on_error</a>, which will be
invoked with the server in question if the connection attempt fails. You
can force the connection attempt to retry by throwing the :go symbol, with
:retry as the payload, or force the exception to be reraised by throwing
:go with :raise as the payload:</p>
<pre class="ruby"><span class="ruby-identifier">handler</span> = <span class="ruby-constant">Proc</span>.<span class="ruby-identifier">new</span> <span class="ruby-keyword">do</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">connection_attempts</span>] <span class="ruby-operator">||=</span> <span class="ruby-value">0</span>
 <span class="ruby-keyword">if</span> <span class="ruby-identifier">server</span>[:<span class="ruby-identifier">connection_attempts</span>] <span class="ruby-operator"><</span> <span class="ruby-value">3</span>
 <span class="ruby-identifier">server</span>[:<span class="ruby-identifier">connection_attempts</span>] <span class="ruby-operator">+=</span> <span class="ruby-value">1</span>
 <span class="ruby-identifier">throw</span> :<span class="ruby-identifier">go</span>, :<span class="ruby-keyword">retry</span>
 <span class="ruby-keyword">else</span>
 <span class="ruby-identifier">throw</span> :<span class="ruby-identifier">go</span>, :<span class="ruby-identifier">raise</span>
 <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>

<span class="ruby-constant">Net</span><span class="ruby-operator">::</span><span class="ruby-constant">SSH</span><span class="ruby-operator">::</span><span class="ruby-constant">Multi</span>.<span class="ruby-identifier">start</span>(:<span class="ruby-identifier">on_error</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">handler</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">session</span><span class="ruby-operator">|</span>
 <span class="ruby-comment"># ...</span>
<span class="ruby-keyword">end</span></pre>
<p>Any other thrown value (or no thrown value at all) will result in the
failure being ignored.</p>
<h2 id="label-Lazily+Evaluated+Server+Definitions">Lazily Evaluated <a href="Server.html">Server</a> Definitions</h2>
<p>Sometimes you might be dealing with an environment where you don't know the
names or addresses of the servers until runtime. You can certainly
dynamically build server names and pass them to <a
href="Session.html#method-i-use">use</a>, but if the operation to determine
the server names is expensive, you might want to defer it until the server
is actually needed (especially if the logic of your program is such that
you might not even need to connect to that server every time the program
runs).</p>
<p>You can do this by passing a block to <a
href="Session.html#method-i-use">use</a>:</p>
<pre class="ruby"><span class="ruby-identifier">session</span>.<span class="ruby-identifier">use</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">opt</span><span class="ruby-operator">|</span>
 <span class="ruby-identifier">lookup_ip_address_of_remote_host</span>
<span class="ruby-keyword">end</span></pre>
<p>See <a href="Session.html#method-i-use">use</a> for more information about
this usage.</p>
</div>
<div id='method-list'>
<h2>Methods</h2>
<h3>Public Class</h3>
<ol>
<li><a target="docwin" href="#method-c-new">new</a></li>
</ol>
<h3>Public Instance</h3>
<ol>
<li><a target="docwin" href="#method-i-close">close</a></li>
<li><a target="docwin" href="#attribute-i-concurrent_connections">concurrent_connections</a></li>
<li><a target="docwin" href="#attribute-i-default_gateway">default_gateway</a></li>
<li><a target="docwin" href="#attribute-i-default_user">default_user</a></li>
<li><a target="docwin" href="#method-i-group">group</a></li>
<li><a target="docwin" href="#attribute-i-groups">groups</a></li>
<li><a target="docwin" href="#method-i-loop">loop</a></li>
<li><a target="docwin" href="#method-i-on">on</a></li>
<li><a target="docwin" href="#attribute-i-on_error">on_error</a></li>
<li><a target="docwin" href="#method-i-process">process</a></li>
<li><a target="docwin" href="#attribute-i-server_list">server_list</a></li>
<li><a target="docwin" href="#method-i-servers">servers</a></li>
<li><a target="docwin" href="#method-i-servers_for">servers_for</a></li>
<li><a target="docwin" href="#method-i-use">use</a></li>
<li><a target="docwin" href="#method-i-via">via</a></li>
<li><a target="docwin" href="#method-i-with">with</a></li>
</ol>
</div>
<div id='context'>
<div id='includes'>
<h2>Included modules</h2>
<ol>
<li><a target="docwin" href="SessionActions.html">SessionActions</a></li>
</ol>
</div>
</div>
<div id='section'>
<div id='aliases-list'>
<h2>Public Instance Aliases</h2>
<div class='name-list'>
<table summary='Public Instance Aliases'>
<tr class='top-aligned-row context-row'>
<td class='context-item-name'>loop_forever</td>
<td>-></td>
<td class='context-item-value'><a target="docwin" href="#method-i-loop">loop</a></td>
</tr>
</table>
</div>
</div>
<div id='attribute-list'>
<h2 class='section-bar'>Attributes</h2>
<div class='name-list'>
<table>
<tr class='top-aligned-row context-row'>
<td class='context-item-name'>
<a name='attribute-i-concurrent_connections'>concurrent_connections</a>
</td>
<td class='context-item-value'>[RW]</td>
<td class='context-item-desc'>
<p>The number of allowed concurrent connections. No more than this number of
sessions will be open at any given time.</p>
</td>
</tr>
<tr class='top-aligned-row context-row'>
<td class='context-item-name'>
<a name='attribute-i-default_gateway'>default_gateway</a>
</td>
<td class='context-item-value'>[R]</td>
<td class='context-item-desc'>
<p>The default Net::SSH::Gateway instance to use to connect to the servers. If
<code>nil</code>, no default gateway will be used.</p>
</td>
</tr>
<tr class='top-aligned-row context-row'>
<td class='context-item-name'>
<a name='attribute-i-default_user'>default_user</a>
</td>
<td class='context-item-value'>[RW]</td>
<td class='context-item-desc'>
<p>The default user name to use when connecting to a server. If a user name is
not given for a particular server, this value will be used. It defaults to
<a target="_top" href="http://'USER'">ENV</a> || <a target="_top" href="http://'USERNAME'">ENV</a>, or
"unknown" if neither of those are set.</p>
</td>
</tr>
<tr class='top-aligned-row context-row'>
<td class='context-item-name'>
<a name='attribute-i-groups'>groups</a>
</td>
<td class='context-item-value'>[R]</td>
<td class='context-item-desc'>
<p>The hash of group definitions, mapping each group name to a corresponding
<a href="ServerList.html">Net::SSH::Multi::ServerList</a>.</p>
</td>
</tr>
<tr class='top-aligned-row context-row'>
<td class='context-item-name'>
<a name='attribute-i-on_error'>on_error</a>
</td>
<td class='context-item-value'>[RW]</td>
<td class='context-item-desc'>
<p>How connection errors should be handled. This defaults to :fail, but may be
set to :ignore if connection errors should be ignored, or :warn if
connection errors should cause a warning.</p>
</td>
</tr>
<tr class='top-aligned-row context-row'>
<td class='context-item-name'>
<a name='attribute-i-server_list'>server_list</a>
</td>
<td class='context-item-value'>[R]</td>
<td class='context-item-desc'>
<p>The <a href="ServerList.html">Net::SSH::Multi::ServerList</a> managed by
this session.</p>
</td>
</tr>
</table>
</div>
</div>
<div id='methods'>
<h2>Public Class methods</h2>
<div class='method public-class' id='method-method-c-new'>
<a name='method-c-new'></a>
<div class='synopsis'>
<span class='name'>new</span>
<span class='arguments'>(options={})</span>
</div>
<div class='description'>
<p>Creates a new <a href="Session.html">Net::SSH::Multi::Session</a> instance.
Initially, it contains no server definitions, no group definitions, and no
default gateway.</p>
<p>You can set the <a
href="Session.html#attribute-i-concurrent_connections">concurrent_connections</a>
property in the options. Setting it to <code>nil</code> (the default) will
cause <a href="../Multi.html">Net::SSH::Multi</a> to ignore any concurrent
connection limit and allow all defined sessions to be open simultaneously.
Setting it to an integer will cause <a
href="../Multi.html">Net::SSH::Multi</a> to allow no more than that number
of concurrently open sessions, opening subsequent sessions only when other
sessions finish and close.</p>
<pre class="ruby"><span class="ruby-constant">Net</span><span class="ruby-operator">::</span><span class="ruby-constant">SSH</span><span class="ruby-operator">::</span><span class="ruby-constant">Multi</span>.<span class="ruby-identifier">start</span>(:<span class="ruby-identifier">concurrent_connections</span> =<span class="ruby-operator">></span> <span class="ruby-value">10</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">session</span><span class="ruby-operator">|</span>
 <span class="ruby-identifier">session</span>.<span class="ruby-identifier">use</span> <span class="ruby-operator">...</span>
<span class="ruby-keyword">end</span></pre>
</div>
<div class='source'>
<a class='source-toggle' href='#' onclick="toggleCode('method-c-new-source'); return false">
[show source]
</a>
<pre id='method-c-new-source'><span class="ruby-comment"># File lib/net/ssh/multi/session.rb, line 171</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">options</span>={})
 <span class="ruby-ivar">@server_list</span> = <span class="ruby-constant">ServerList</span>.<span class="ruby-identifier">new</span>
 <span class="ruby-ivar">@groups</span> = <span class="ruby-constant">Hash</span>.<span class="ruby-identifier">new</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">h</span>,<span class="ruby-identifier">k</span><span class="ruby-operator">|</span> <span class="ruby-identifier">h</span>[<span class="ruby-identifier">k</span>] = <span class="ruby-constant">ServerList</span>.<span class="ruby-identifier">new</span> }
 <span class="ruby-ivar">@gateway</span> = <span class="ruby-keyword">nil</span>
 <span class="ruby-ivar">@open_groups</span> = []
 <span class="ruby-ivar">@connect_threads</span> = []
 <span class="ruby-ivar">@on_error</span> = <span class="ruby-value">:fail</span>
 <span class="ruby-ivar">@default_user</span> = <span class="ruby-constant">ENV</span>[<span class="ruby-string">'USER'</span>] <span class="ruby-operator">||</span> <span class="ruby-constant">ENV</span>[<span class="ruby-string">'USERNAME'</span>] <span class="ruby-operator">||</span> <span class="ruby-string">"unknown"</span>

 <span class="ruby-ivar">@open_connections</span> = <span class="ruby-value">0</span>
 <span class="ruby-ivar">@pending_sessions</span> = []
 <span class="ruby-ivar">@session_mutex</span> = <span class="ruby-constant">Mutex</span>.<span class="ruby-identifier">new</span>

 <span class="ruby-identifier">options</span>.<span class="ruby-identifier">each</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">opt</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span> <span class="ruby-identifier">send</span>(<span class="ruby-node">"#{opt}="</span>, <span class="ruby-identifier">value</span>) }
<span class="ruby-keyword">end</span></pre>
</div>
</div>
<h2>Public Instance methods</h2>
<div class='method public-instance' id='method-method-i-close'>
<a name='method-i-close'></a>
<div class='synopsis'>
<span class='name'>close</span>
<span class='arguments'>()</span>
</div>
<div class='description'>
<p>Closes the multi-session by shutting down all open server sessions, and the
default gateway (if one was specified using <a
href="Session.html#method-i-via">via</a>). Note that other gateway
connections (e.g., those passed to <a
href="Session.html#method-i-use">use</a> directly) will <em>not</em> be
closed by this method, and must be managed externally.</p>
</div>
<div class='source'>
<a class='source-toggle' href='#' onclick="toggleCode('method-i-close-source'); return false">
[show source]
</a>
<pre id='method-i-close-source'><span class="ruby-comment"># File lib/net/ssh/multi/session.rb, line 402</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier">close</span>
 <span class="ruby-identifier">server_list</span>.<span class="ruby-identifier">each</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">close_channels</span> }
 <span class="ruby-identifier">loop</span>(<span class="ruby-value">0</span>) { <span class="ruby-identifier">busy?</span>(<span class="ruby-keyword">true</span>) }
 <span class="ruby-identifier">server_list</span>.<span class="ruby-identifier">each</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">close</span> }
 <span class="ruby-identifier">default_gateway</span>.<span class="ruby-identifier">shutdown!</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">default_gateway</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
<div class='method public-instance' id='method-method-i-group'>
<a name='method-i-group'></a>
<div class='synopsis'>
<span class='name'>group</span>
<span class='arguments'>(*args)</span>
</div>
<div class='description'>
<p>At its simplest, this associates a named group with a server definition. It
can be used in either of two ways:</p>
<p>First, you can use it to associate a group (or array of groups) with a
server definition (or array of server definitions). The server definitions
must already exist in the <a
href="Session.html#attribute-i-server_list">server_list</a> array
(typically by calling <a href="Session.html#method-i-use">use</a>):</p>
<pre class="ruby"><span class="ruby-identifier">server1</span> = <span class="ruby-identifier">session</span>.<span class="ruby-identifier">use</span>(<span class="ruby-string">'host1'</span>, <span class="ruby-string">'user1'</span>)
<span class="ruby-identifier">server2</span> = <span class="ruby-identifier">session</span>.<span class="ruby-identifier">use</span>(<span class="ruby-string">'host2'</span>, <span class="ruby-string">'user2'</span>)
<span class="ruby-identifier">session</span>.<span class="ruby-identifier">group</span> :<span class="ruby-identifier">app</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">server1</span>, :<span class="ruby-identifier">web</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">server2</span>
<span class="ruby-identifier">session</span>.<span class="ruby-identifier">group</span> :<span class="ruby-identifier">staging</span> =<span class="ruby-operator">></span> [<span class="ruby-identifier">server1</span>, <span class="ruby-identifier">server2</span>]
<span class="ruby-identifier">session</span>.<span class="ruby-identifier">group</span> <span class="ruby-node">%w(xen linux)</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">server2</span>
<span class="ruby-identifier">session</span>.<span class="ruby-identifier">group</span> <span class="ruby-node">%w(rackspace backup)</span> =<span class="ruby-operator">></span> [<span class="ruby-identifier">server1</span>, <span class="ruby-identifier">server2</span>]</pre>
<p>Secondly, instead of a mapping of groups to servers, you can just provide a
list of group names, and then a block. Inside the block, any calls to <a
href="Session.html#method-i-use">use</a> will automatically associate the
new server definition with those groups. You can nest <a
href="Session.html#method-i-group">group</a> calls, too, which will
aggregate the group definitions.</p>
<pre>session.group :rackspace, :backup do
 session.use 'host1', 'user1'
 session.group :xen do
 session.use 'host2', 'user2'
 end
end</pre>
</div>
<div class='source'>
<a class='source-toggle' href='#' onclick="toggleCode('method-i-group-source'); return false">
[show source]
</a>
<pre id='method-i-group-source'><span class="ruby-comment"># File lib/net/ssh/multi/session.rb, line 213</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier">group</span>(*<span class="ruby-identifier">args</span>)
 <span class="ruby-identifier">mapping</span> = <span class="ruby-identifier">args</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Hash</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">args</span>.<span class="ruby-identifier">pop</span> <span class="ruby-operator">:</span> {}

 <span class="ruby-keyword">if</span> <span class="ruby-identifier">mapping</span>.<span class="ruby-identifier">any?</span> <span class="ruby-operator">&&</span> <span class="ruby-identifier">block_given?</span>
 <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>, <span class="ruby-string">"must provide group mapping OR block, not both"</span>
 <span class="ruby-keyword">elsif</span> <span class="ruby-identifier">block_given?</span>
 <span class="ruby-keyword">begin</span>
 <span class="ruby-identifier">saved_groups</span> = <span class="ruby-identifier">open_groups</span>.<span class="ruby-identifier">dup</span>
 <span class="ruby-identifier">open_groups</span>.<span class="ruby-identifier">concat</span>(<span class="ruby-identifier">args</span>.<span class="ruby-identifier">map</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">a</span><span class="ruby-operator">|</span> <span class="ruby-identifier">a</span>.<span class="ruby-identifier">to_sym</span> }).<span class="ruby-identifier">uniq!</span>
 <span class="ruby-keyword">yield</span> <span class="ruby-keyword">self</span>
 <span class="ruby-keyword">ensure</span>
 <span class="ruby-identifier">open_groups</span>.<span class="ruby-identifier">replace</span>(<span class="ruby-identifier">saved_groups</span>)
 <span class="ruby-keyword">end</span>
 <span class="ruby-keyword">else</span>
 <span class="ruby-identifier">mapping</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">key</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span>
 (<span class="ruby-identifier">open_groups</span> <span class="ruby-operator">+</span> <span class="ruby-constant">Array</span>(<span class="ruby-identifier">key</span>)).<span class="ruby-identifier">uniq</span>.<span class="ruby-identifier">each</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">grp</span><span class="ruby-operator">|</span>
 <span class="ruby-identifier">groups</span>[<span class="ruby-identifier">grp</span>.<span class="ruby-identifier">to_sym</span>].<span class="ruby-identifier">concat</span>(<span class="ruby-constant">Array</span>(<span class="ruby-identifier">value</span>))
 <span class="ruby-keyword">end</span>
 <span class="ruby-keyword">end</span>
 <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
<div class='method public-instance' id='method-method-i-loop'>
<a name='method-i-loop'></a>
<div class='synopsis'>
<span class='name'>loop</span>
<span class='arguments'>(wait=nil, &block)</span>
</div>
<div class='description'>
<p>Run the aggregated event loop for all open server sessions, until the given
block returns <code>false</code>. If no block is given, the loop will run
for as long as <a href="SessionActions.html#method-i-busy-3F">busy?</a>
returns <code>true</code> (in other words, for as long as there are any
(non-invisible) channels open).</p>
</div>
<div class='source'>
<a class='source-toggle' href='#' onclick="toggleCode('method-i-loop-source'); return false">
[show source]
</a>
<pre id='method-i-loop-source'><span class="ruby-comment"># File lib/net/ssh/multi/session.rb, line 415</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier">loop</span>(<span class="ruby-identifier">wait</span>=<span class="ruby-keyword">nil</span>, &<span class="ruby-identifier">block</span>)
 <span class="ruby-identifier">running</span> = <span class="ruby-identifier">block</span> <span class="ruby-operator">||</span> <span class="ruby-constant">Proc</span>.<span class="ruby-identifier">new</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">c</span><span class="ruby-operator">|</span> <span class="ruby-identifier">busy?</span> }
 <span class="ruby-identifier">loop_forever</span> { <span class="ruby-keyword">break</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">process</span>(<span class="ruby-identifier">wait</span>, &<span class="ruby-identifier">running</span>) }
<span class="ruby-keyword">end</span></pre>
</div>
</div>
<div class='method public-instance' id='method-method-i-on'>
<a name='method-i-on'></a>
<div class='synopsis'>
<span class='name'>on</span>
<span class='arguments'>(*servers)</span>
</div>
<div class='description'>
<p>Works as <a href="Session.html#method-i-with">with</a>, but for specific
servers rather than groups. It will return a new subsession (<a
href="Subsession.html">Net::SSH::Multi::Subsession</a>) consisting of the
given servers. (Note that it requires that the servers in question have
been created via calls to <a href="Session.html#method-i-use">use</a> on
this session object, or things will not work quite right.) If a block is
given, the new subsession will also be yielded to the block.</p>
<pre>srv1 = session.use('host1', 'user')
srv2 = session.use('host2', 'user')
# ...
session.on(srv1, srv2).exec('hostname')</pre>
</div>
<div class='source'>
<a class='source-toggle' href='#' onclick="toggleCode('method-i-on-source'); return false">
[show source]
</a>
<pre id='method-i-on-source'><span class="ruby-comment"># File lib/net/ssh/multi/session.rb, line 392</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier">on</span>(*<span class="ruby-identifier">servers</span>)
 <span class="ruby-identifier">subsession</span> = <span class="ruby-constant">Subsession</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword">self</span>, <span class="ruby-identifier">servers</span>)
 <span class="ruby-keyword">yield</span> <span class="ruby-identifier">subsession</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">block_given?</span>
 <span class="ruby-identifier">subsession</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
<div class='method public-instance' id='method-method-i-process'>
<a name='method-i-process'></a>
<div class='synopsis'>
<span class='name'>process</span>
<span class='arguments'>(wait=nil, &block)</span>
</div>
<div class='description'>
<p>Run a single iteration of the aggregated event loop for all open server
sessions. The <code>wait</code> parameter indicates how long to wait for an
event to appear on any of the different sessions; <code>nil</code> (the
default) means "wait forever". If the block is given, then it will be used
to determine whether <a href="Session.html#method-i-process">process</a>
returns <code>true</code> (the block did not return <code>false</code>), or
<code>false</code> (the block returned <code>false</code>).</p>
</div>
<div class='source'>
<a class='source-toggle' href='#' onclick="toggleCode('method-i-process-source'); return false">
[show source]
</a>
<pre id='method-i-process-source'><span class="ruby-comment"># File lib/net/ssh/multi/session.rb, line 426</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier">process</span>(<span class="ruby-identifier">wait</span>=<span class="ruby-keyword">nil</span>, &<span class="ruby-identifier">block</span>)
 <span class="ruby-identifier">realize_pending_connections!</span>
 <span class="ruby-identifier">wait</span> = <span class="ruby-ivar">@connect_threads</span>.<span class="ruby-identifier">any?</span> <span class="ruby-operator">?</span> <span class="ruby-value">0</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">wait</span>

 <span class="ruby-keyword">return</span> <span class="ruby-keyword">false</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">preprocess</span>(&<span class="ruby-identifier">block</span>)

 <span class="ruby-identifier">readers</span> = <span class="ruby-identifier">server_list</span>.<span class="ruby-identifier">map</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">s</span><span class="ruby-operator">|</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">readers</span> }.<span class="ruby-identifier">flatten</span>
 <span class="ruby-identifier">writers</span> = <span class="ruby-identifier">server_list</span>.<span class="ruby-identifier">map</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">s</span><span class="ruby-operator">|</span> <span class="ruby-identifier">s</span>.<span class="ruby-identifier">writers</span> }.<span class="ruby-identifier">flatten</span>

 <span class="ruby-identifier">readers</span>, <span class="ruby-identifier">writers</span>, = <span class="ruby-constant">IO</span>.<span class="ruby-identifier">select</span>(<span class="ruby-identifier">readers</span>, <span class="ruby-identifier">writers</span>, <span class="ruby-keyword">nil</span>, <span class="ruby-identifier">wait</span>)

 <span class="ruby-keyword">if</span> <span class="ruby-identifier">readers</span>
 <span class="ruby-keyword">return</span> <span class="ruby-identifier">postprocess</span>(<span class="ruby-identifier">readers</span>, <span class="ruby-identifier">writers</span>)
 <span class="ruby-keyword">else</span>
 <span class="ruby-keyword">return</span> <span class="ruby-keyword">true</span>
 <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
<div class='method public-instance' id='method-method-i-servers'>
<a name='method-i-servers'></a>
<div class='synopsis'>
<span class='name'>servers</span>
<span class='arguments'>()</span>
</div>
<div class='description'>
<p>Essentially an alias for <a
href="Session.html#method-i-servers_for">servers_for</a> without any
arguments. This is used primarily to satistfy the expectations of the <a
href="SessionActions.html">Net::SSH::Multi::SessionActions</a> module.</p>
</div>
<div class='source'>
<a class='source-toggle' href='#' onclick="toggleCode('method-i-servers-source'); return false">
[show source]
</a>
<pre id='method-i-servers-source'><span class="ruby-comment"># File lib/net/ssh/multi/session.rb, line 293</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier">servers</span>
 <span class="ruby-identifier">servers_for</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
<div class='method public-instance' id='method-method-i-servers_for'>
<a name='method-i-servers_for'></a>
<div class='synopsis'>
<span class='name'>servers_for</span>
<span class='arguments'>(*criteria)</span>
</div>
<div class='description'>
<p>Returns the set of servers that match the given criteria. It can be used in
any (or all) of three ways.</p>
<p>First, you can omit any arguments. In this case, the full list of servers
will be returned.</p>
<pre>all = session.servers_for</pre>
<p>Second, you can simply specify a list of group names. All servers in all
named groups will be returned. If a server belongs to multiple matching
groups, then it will appear only once in the list (the resulting list will
contain only unique servers).</p>
<pre>servers = session.servers_for(:app, :db)</pre>
<p>Last, you can specify a hash with group names as keys, and property
constraints as the values. These property constraints are either "only"
constraints (which restrict the set of servers to "only" those that match
the given properties) or "except" constraints (which restrict the set of
servers to those whose properties do <em>not</em> match). Properties are
described when the server is defined (via the :properties key):</p>
<pre class="ruby"><span class="ruby-identifier">session</span>.<span class="ruby-identifier">group</span> :<span class="ruby-identifier">db</span> <span class="ruby-keyword">do</span>
 <span class="ruby-identifier">session</span>.<span class="ruby-identifier">use</span> <span class="ruby-string">'dbmain'</span>, <span class="ruby-string">'user'</span>, :<span class="ruby-identifier">properties</span> =<span class="ruby-operator">></span> { :<span class="ruby-identifier">primary</span> =<span class="ruby-operator">></span> <span class="ruby-keyword">true</span> }
 <span class="ruby-identifier">session</span>.<span class="ruby-identifier">use</span> <span class="ruby-string">'dbslave'</span>, <span class="ruby-string">'user2'</span>
 <span class="ruby-identifier">session</span>.<span class="ruby-identifier">use</span> <span class="ruby-string">'dbslve2'</span>, <span class="ruby-string">'user2'</span>
<span class="ruby-keyword">end</span>

<span class="ruby-comment"># return ONLY on the servers in the :db group which have the :primary</span>
<span class="ruby-comment"># property set to true.</span>
<span class="ruby-identifier">primary</span> = <span class="ruby-identifier">session</span>.<span class="ruby-identifier">servers_for</span>(:<span class="ruby-identifier">db</span> =<span class="ruby-operator">></span> { :<span class="ruby-identifier">only</span> =<span class="ruby-operator">></span> { :<span class="ruby-identifier">primary</span> =<span class="ruby-operator">></span> <span class="ruby-keyword">true</span> } })</pre>
<p>You can, naturally, combine these methods:</p>
<pre class="ruby"><span class="ruby-comment"># all servers in :app and :web, and all servers in :db with the</span>
<span class="ruby-comment"># :primary property set to true</span>
<span class="ruby-identifier">servers</span> = <span class="ruby-identifier">session</span>.<span class="ruby-identifier">servers_for</span>(:<span class="ruby-identifier">app</span>, :<span class="ruby-identifier">web</span>, :<span class="ruby-identifier">db</span> =<span class="ruby-operator">></span> { :<span class="ruby-identifier">only</span> =<span class="ruby-operator">></span> { :<span class="ruby-identifier">primary</span> =<span class="ruby-operator">></span> <span class="ruby-keyword">true</span> } })</pre>
</div>
<div class='source'>
<a class='source-toggle' href='#' onclick="toggleCode('method-i-servers_for-source'); return false">
[show source]
</a>
<pre id='method-i-servers_for-source'><span class="ruby-comment"># File lib/net/ssh/multi/session.rb, line 334</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier">servers_for</span>(*<span class="ruby-identifier">criteria</span>)
 <span class="ruby-keyword">if</span> <span class="ruby-identifier">criteria</span>.<span class="ruby-identifier">empty?</span>
 <span class="ruby-identifier">server_list</span>.<span class="ruby-identifier">flatten</span>
 <span class="ruby-keyword">else</span>
 <span class="ruby-comment"># normalize the criteria list, so that every entry is a key to a</span>
 <span class="ruby-comment"># criteria hash (possibly empty).</span>
 <span class="ruby-identifier">criteria</span> = <span class="ruby-identifier">criteria</span>.<span class="ruby-identifier">inject</span>({}) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">hash</span>, <span class="ruby-identifier">entry</span><span class="ruby-operator">|</span>
 <span class="ruby-keyword">case</span> <span class="ruby-identifier">entry</span>
 <span class="ruby-keyword">when</span> <span class="ruby-constant">Hash</span> <span class="ruby-keyword">then</span> <span class="ruby-identifier">hash</span>.<span class="ruby-identifier">merge</span>(<span class="ruby-identifier">entry</span>)
 <span class="ruby-keyword">else</span> <span class="ruby-identifier">hash</span>.<span class="ruby-identifier">merge</span>(<span class="ruby-identifier">entry</span> =<span class="ruby-operator">></span> {})
 <span class="ruby-keyword">end</span>
 <span class="ruby-keyword">end</span>

 <span class="ruby-identifier">list</span> = <span class="ruby-identifier">criteria</span>.<span class="ruby-identifier">inject</span>([]) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">aggregator</span>, (<span class="ruby-identifier">group</span>, <span class="ruby-identifier">properties</span>)<span class="ruby-operator">|</span>
 <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>, <span class="ruby-node">"the value for any group must be a Hash, but got a #{properties.class} for #{group.inspect}"</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">properties</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Hash</span>)
 <span class="ruby-identifier">bad_keys</span> = <span class="ruby-identifier">properties</span>.<span class="ruby-identifier">keys</span> <span class="ruby-operator">-</span> [<span class="ruby-value">:only</span>, <span class="ruby-value">:except</span>]
 <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>, <span class="ruby-node">"unknown constraint(s) #{bad_keys.inspect} for #{group.inspect}"</span> <span class="ruby-keyword">unless</span> <span class="ruby-identifier">bad_keys</span>.<span class="ruby-identifier">empty?</span>

 <span class="ruby-identifier">servers</span> = <span class="ruby-identifier">groups</span>[<span class="ruby-identifier">group</span>].<span class="ruby-identifier">select</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">server</span><span class="ruby-operator">|</span>
 (<span class="ruby-identifier">properties</span>[<span class="ruby-value">:only</span>] <span class="ruby-operator">||</span> {}).<span class="ruby-identifier">all?</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">prop</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span> <span class="ruby-identifier">server</span>[<span class="ruby-identifier">prop</span>] <span class="ruby-operator">==</span> <span class="ruby-identifier">value</span> } <span class="ruby-operator">&&</span>
 <span class="ruby-operator">!</span>(<span class="ruby-identifier">properties</span>[<span class="ruby-value">:except</span>] <span class="ruby-operator">||</span> {}).<span class="ruby-identifier">any?</span> { <span class="ruby-operator">|</span><span class="ruby-identifier">prop</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span> <span class="ruby-identifier">server</span>[<span class="ruby-identifier">prop</span>] <span class="ruby-operator">==</span> <span class="ruby-identifier">value</span> }
 <span class="ruby-keyword">end</span>

 <span class="ruby-identifier">aggregator</span>.<span class="ruby-identifier">concat</span>(<span class="ruby-identifier">servers</span>)
 <span class="ruby-keyword">end</span>

 <span class="ruby-identifier">list</span>.<span class="ruby-identifier">uniq</span>
 <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
<div class='method public-instance' id='method-method-i-use'>
<a name='method-i-use'></a>
<div class='synopsis'>
<span class='name'>use</span>
<span class='arguments'>(*hosts, &block)</span>
</div>
<div class='description'>
<p>Defines a new server definition, to be managed by this session. The server
is at the given <code>host</code>, and will be connected to as the given
<code>user</code>. The other options are passed as-is to the <a
href="../../SSH.html">Net::SSH</a> session constructor.</p>
<p>If a default gateway has been specified previously (with <a
href="Session.html#method-i-via">via</a>) it will be passed to the new
server definition. You can override this by passing a different
Net::SSH::Gateway instance (or <code>nil</code>) with the :via key in the
<code>options</code>.</p>
<pre class="ruby"><span class="ruby-identifier">session</span>.<span class="ruby-identifier">use</span> <span class="ruby-string">'host'</span>
<span class="ruby-identifier">session</span>.<span class="ruby-identifier">use</span> <span class="ruby-string">'user@host2'</span>, :<span class="ruby-identifier">via</span> =<span class="ruby-operator">></span> <span class="ruby-keyword">nil</span>
<span class="ruby-identifier">session</span>.<span class="ruby-identifier">use</span> <span class="ruby-string">'host3'</span>, :<span class="ruby-identifier">user</span> =<span class="ruby-operator">></span> <span class="ruby-string">"user3"</span>, :<span class="ruby-identifier">via</span> =<span class="ruby-operator">></span> <span class="ruby-constant">Net</span><span class="ruby-operator">::</span><span class="ruby-constant">SSH</span><span class="ruby-operator">::</span><span class="ruby-constant">Gateway</span>.<span class="ruby-identifier">new</span>(<span class="ruby-string">'gateway.host'</span>, <span class="ruby-string">'user'</span>)</pre>
<p>If only a single host is given, the new server instance is returned. You
can give multiple hosts at a time, though, in which case an array of server
instances will be returned.</p>
<pre>server1, server2 = session.use "host1", "host2"</pre>
<p>If given a block, this will save the block as a <a
href="DynamicServer.html">Net::SSH::Multi::DynamicServer</a> definition, to
be evaluated lazily the first time the server is needed. The block will
recive any options hash given to <a
href="Session.html#method-i-use">use</a>, and should return
<code>nil</code> (if no servers are to be added), a String or an array of
Strings (to be interpreted as a connection specification), or a <a
href="Server.html">Server</a> or an array of Servers.</p>
</div>
<div class='source'>
<a class='source-toggle' href='#' onclick="toggleCode('method-i-use-source'); return false">
[show source]
</a>
<pre id='method-i-use-source'><span class="ruby-comment"># File lib/net/ssh/multi/session.rb, line 274</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier">use</span>(*<span class="ruby-identifier">hosts</span>, &<span class="ruby-identifier">block</span>)
 <span class="ruby-identifier">options</span> = <span class="ruby-identifier">hosts</span>.<span class="ruby-identifier">last</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Hash</span>) <span class="ruby-operator">?</span> <span class="ruby-identifier">hosts</span>.<span class="ruby-identifier">pop</span> <span class="ruby-operator">:</span> {}
 <span class="ruby-identifier">options</span> = { <span class="ruby-value">:via</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">default_gateway</span> }.<span class="ruby-identifier">merge</span>(<span class="ruby-identifier">options</span>)

 <span class="ruby-identifier">results</span> = <span class="ruby-identifier">hosts</span>.<span class="ruby-identifier">map</span> <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">host</span><span class="ruby-operator">|</span>
 <span class="ruby-identifier">server_list</span>.<span class="ruby-identifier">add</span>(<span class="ruby-constant">Server</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword">self</span>, <span class="ruby-identifier">host</span>, <span class="ruby-identifier">options</span>))
 <span class="ruby-keyword">end</span>

 <span class="ruby-keyword">if</span> <span class="ruby-identifier">block</span>
 <span class="ruby-identifier">results</span> <span class="ruby-operator"><<</span> <span class="ruby-identifier">server_list</span>.<span class="ruby-identifier">add</span>(<span class="ruby-constant">DynamicServer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword">self</span>, <span class="ruby-identifier">options</span>, <span class="ruby-identifier">block</span>))
 <span class="ruby-keyword">end</span>

 <span class="ruby-identifier">group</span> [] =<span class="ruby-operator">></span> <span class="ruby-identifier">results</span>
 <span class="ruby-identifier">results</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">></span> <span class="ruby-value">1</span> <span class="ruby-operator">?</span> <span class="ruby-identifier">results</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">results</span>.<span class="ruby-identifier">first</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
<div class='method public-instance' id='method-method-i-via'>
<a name='method-i-via'></a>
<div class='synopsis'>
<span class='name'>via</span>
<span class='arguments'>(host, user, options={})</span>
</div>
<div class='description'>
<p>Sets up a default gateway to use when establishing connections to servers.
Note that any servers defined prior to this invocation will not use the
default gateway; it only affects servers defined subsequently.</p>
<pre>session.via 'gateway.host', 'user'</pre>
<p>You may override the default gateway on a per-server basis by passing the
:via key to the <a href="Session.html#method-i-use">use</a> method; see <a
href="Session.html#method-i-use">use</a> for details.</p>
</div>
<div class='source'>
<a class='source-toggle' href='#' onclick="toggleCode('method-i-via-source'); return false">
[show source]
</a>
<pre id='method-i-via-source'><span class="ruby-comment"># File lib/net/ssh/multi/session.rb, line 243</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier">via</span>(<span class="ruby-identifier">host</span>, <span class="ruby-identifier">user</span>, <span class="ruby-identifier">options</span>={})
 <span class="ruby-ivar">@default_gateway</span> = <span class="ruby-constant">Net</span><span class="ruby-operator">::</span><span class="ruby-constant">SSH</span><span class="ruby-operator">::</span><span class="ruby-constant">Gateway</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">host</span>, <span class="ruby-identifier">user</span>, <span class="ruby-identifier">options</span>)
 <span class="ruby-keyword">self</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
<div class='method public-instance' id='method-method-i-with'>
<a name='method-i-with'></a>
<div class='synopsis'>
<span class='name'>with</span>
<span class='arguments'>(*groups)</span>
</div>
<div class='description'>
<p>Returns a new <a href="Subsession.html">Net::SSH::Multi::Subsession</a>
instance consisting of the servers that meet the given criteria. If a block
is given, the subsession will be yielded to it. See <a
href="Session.html#method-i-servers_for">servers_for</a> for a discussion
of how these criteria are interpreted.</p>
<pre class="ruby"><span class="ruby-identifier">session</span>.<span class="ruby-identifier">with</span>(:<span class="ruby-identifier">app</span>).<span class="ruby-identifier">exec</span>(<span class="ruby-string">'hostname'</span>)

<span class="ruby-identifier">session</span>.<span class="ruby-identifier">with</span>(:<span class="ruby-identifier">app</span>, :<span class="ruby-identifier">db</span> =<span class="ruby-operator">></span> { :<span class="ruby-identifier">primary</span> =<span class="ruby-operator">></span> <span class="ruby-keyword">true</span> }) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">s</span><span class="ruby-operator">|</span>
 <span class="ruby-identifier">s</span>.<span class="ruby-identifier">exec</span> <span class="ruby-string">'date'</span>
 <span class="ruby-identifier">s</span>.<span class="ruby-identifier">exec</span> <span class="ruby-string">'uptime'</span>
<span class="ruby-keyword">end</span></pre>
</div>
<div class='source'>
<a class='source-toggle' href='#' onclick="toggleCode('method-i-with-source'); return false">
[show source]
</a>
<pre id='method-i-with-source'><span class="ruby-comment"># File lib/net/ssh/multi/session.rb, line 375</span>
<span class="ruby-keyword">def</span> <span class="ruby-identifier">with</span>(*<span class="ruby-identifier">groups</span>)
 <span class="ruby-identifier">subsession</span> = <span class="ruby-constant">Subsession</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword">self</span>, <span class="ruby-identifier">servers_for</span>(*<span class="ruby-identifier">groups</span>))
 <span class="ruby-keyword">yield</span> <span class="ruby-identifier">subsession</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">block_given?</span>
 <span class="ruby-identifier">subsession</span>
<span class="ruby-keyword">end</span></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='footer-push'></div>
</div>
<div id='footer'>
<a target="docwin" href="http://github.com/mislav/hanna/tree/master"><strong>Hanna</strong> RDoc template</a>
</div>
</body>
</html>
|