delano-rye 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +8 -0
- data/README.rdoc +1 -1
- data/lib/rye/box.rb +79 -18
- data/lib/rye/cmd.rb +2 -1
- data/rye.gemspec +1 -1
- metadata +1 -1
data/CHANGES.txt
CHANGED
@@ -6,6 +6,14 @@ TODO
|
|
6
6
|
* Fingerprints: ssh-keygen -l -f id_rsa_repos.pub
|
7
7
|
|
8
8
|
|
9
|
+
#### 0.6.4 (2009-05-04) #############################
|
10
|
+
|
11
|
+
* FIXED: authorize_remote was not returning to the directory it started with.
|
12
|
+
* ADDED: pre and post command hooks to Rye::Box
|
13
|
+
* ADDED: Rye::Box.batch
|
14
|
+
* ADDED: Support for OS X for Rye::Box.guess_user_home
|
15
|
+
|
16
|
+
|
9
17
|
#### 0.6.3 (2009-05-02) #############################
|
10
18
|
|
11
19
|
* FIXED: Rye::Box.guess_user_home wasn't handling the username arg (only using default name)
|
data/README.rdoc
CHANGED
data/lib/rye/box.rb
CHANGED
@@ -46,6 +46,9 @@ module Rye
|
|
46
46
|
# The most recent valud for umask (or 0022)
|
47
47
|
attr_reader :current_umask
|
48
48
|
|
49
|
+
attr_writer :post_command_hook
|
50
|
+
attr_writer :pre_command_hook
|
51
|
+
|
49
52
|
# * +host+ The hostname to connect to. The default is localhost.
|
50
53
|
# * +opts+ a hash of optional arguments.
|
51
54
|
#
|
@@ -267,19 +270,14 @@ module Rye
|
|
267
270
|
end
|
268
271
|
alias :add_env :setenv # deprecated?
|
269
272
|
|
270
|
-
|
271
|
-
|
272
|
-
end
|
273
|
+
# The name of the user that opened the SSH connection
|
274
|
+
def user; (@opts || {})[:user]; end
|
273
275
|
|
274
276
|
# See Rye.keys
|
275
|
-
def keys
|
276
|
-
Rye.keys
|
277
|
-
end
|
277
|
+
def keys; Rye.keys; end
|
278
278
|
|
279
|
-
# Returns
|
280
|
-
def to_s
|
281
|
-
@host
|
282
|
-
end
|
279
|
+
# Returns +user@host+
|
280
|
+
def to_s; '%s@%s' % [user, @host]; end
|
283
281
|
|
284
282
|
def inspect
|
285
283
|
%q{#<%s:%s cwd=%s umask=%s env=%s safe=%s opts=%s>} %
|
@@ -301,7 +299,6 @@ module Rye
|
|
301
299
|
Rye.remote_host_keys(@host)
|
302
300
|
end
|
303
301
|
|
304
|
-
|
305
302
|
# Uses the output of "useradd -D" to determine the default home
|
306
303
|
# directory. This returns a GUESS rather than the a user's real
|
307
304
|
# home directory. Currently used only by authorize_keys_remote.
|
@@ -320,9 +317,10 @@ module Rye
|
|
320
317
|
# /etc/adduser.config, DHOME=/home OR ??
|
321
318
|
user_defaults = {}
|
322
319
|
raw = self.useradd(:D) rescue ["HOME=/home"]
|
320
|
+
ostmp = self.ostype
|
323
321
|
raw.each do |nv|
|
324
322
|
|
325
|
-
if
|
323
|
+
if ostmp == "sunos"
|
326
324
|
#nv.scan(/([\w_-]+?)=(.+?)\s/).each do |n, v|
|
327
325
|
# n = 'HOME' if n == 'basedir'
|
328
326
|
# user_defaults[n.upcase] = v.strip
|
@@ -330,6 +328,8 @@ module Rye
|
|
330
328
|
# In Solaris, useradd -D says the default home path is /home
|
331
329
|
# but that directory is not writable. See: http://bit.ly/IJDD0
|
332
330
|
user_defaults['HOME'] = '/export/home'
|
331
|
+
elsif ostmp == "darwin"
|
332
|
+
user_defaults['HOME'] = '/Users'
|
333
333
|
else
|
334
334
|
n, v = nv.scan(/\A([\w_-]+?)=(.+)\z/).flatten
|
335
335
|
user_defaults[n] = v
|
@@ -353,6 +353,8 @@ module Rye
|
|
353
353
|
added_keys = []
|
354
354
|
rap = Rye::Rap.new(self)
|
355
355
|
|
356
|
+
prevdir = self.current_working_directory
|
357
|
+
|
356
358
|
# The homedir path is important b/c this is where we're going to
|
357
359
|
# look for the .ssh directory. That's where auth love is stored.
|
358
360
|
homedir = self.guess_user_home(this_user)
|
@@ -395,6 +397,8 @@ module Rye
|
|
395
397
|
self.chown(:R, this_user.to_s, File.dirname(akey_path))
|
396
398
|
end
|
397
399
|
|
400
|
+
# And let's return to the directory we came from.
|
401
|
+
self.cd prevdir
|
398
402
|
|
399
403
|
rap.add_exit_code(0)
|
400
404
|
rap
|
@@ -423,10 +427,50 @@ module Rye
|
|
423
427
|
def method_missing(meth, *args, &block)
|
424
428
|
raise Rye::CommandNotFound, "#{meth.to_s}"
|
425
429
|
end
|
430
|
+
|
431
|
+
# Returns the command an arguments as a String.
|
426
432
|
def preview_command(*args)
|
427
433
|
prep_args(*args).join(' ')
|
428
434
|
end
|
429
435
|
|
436
|
+
|
437
|
+
# Supply a block to be called before every command. It's called
|
438
|
+
# with three arguments: command name, an Array of arguments, user name
|
439
|
+
#
|
440
|
+
def pre_command_hook(&block)
|
441
|
+
@pre_command_hook = block if block
|
442
|
+
@pre_command_hook
|
443
|
+
end
|
444
|
+
|
445
|
+
# Execute a block in the context of an instance of Rye::Box.
|
446
|
+
#
|
447
|
+
# rbox = Rye::Box.new
|
448
|
+
#
|
449
|
+
# rbox.batch do
|
450
|
+
# ls :l
|
451
|
+
# uname :a
|
452
|
+
# end
|
453
|
+
# OR
|
454
|
+
# rbox.batch(&block)
|
455
|
+
#
|
456
|
+
#
|
457
|
+
def batch(&block)
|
458
|
+
instance_eval &block
|
459
|
+
end
|
460
|
+
|
461
|
+
# Supply a block to be called after every command. It's called
|
462
|
+
# with one argument: an instance of Rye::Rap.
|
463
|
+
#
|
464
|
+
# When this block is supplied, the command does not raise an
|
465
|
+
# exception when the exit code is greater than 0 (the typical
|
466
|
+
# behavior) so the block needs to check the Rye::Rap object to
|
467
|
+
# determine whether an exception should be raised.
|
468
|
+
def post_command_hook(&block)
|
469
|
+
@post_command_hook = block if block
|
470
|
+
@post_command_hook
|
471
|
+
end
|
472
|
+
|
473
|
+
|
430
474
|
private
|
431
475
|
|
432
476
|
def debug(msg="unknown debug msg"); @debug.puts msg if @debug; end
|
@@ -491,6 +535,19 @@ module Rye
|
|
491
535
|
info "COMMAND: #{cmd_clean}"
|
492
536
|
debug "Executing: %s" % cmd_clean
|
493
537
|
|
538
|
+
if @pre_command_hook.is_a?(Proc)
|
539
|
+
@pre_command_hook.call(cmd, args, opts[:user])
|
540
|
+
end
|
541
|
+
|
542
|
+
## NOTE: Do not raise a CommandNotFound exception in this method.
|
543
|
+
# We want it to be possible to define methods to a single instance
|
544
|
+
# of Rye::Box. i.e. def rbox.rm()...
|
545
|
+
# can? returns the methods in Rye::Cmd so it would incorrectly
|
546
|
+
# return false. We could use self.respond_to? but it's possible
|
547
|
+
# to get a name collision. I could write a work around but I think
|
548
|
+
# this is good enough for now.
|
549
|
+
## raise Rye::CommandNotFound unless self.can?(cmd)
|
550
|
+
|
494
551
|
stdout, stderr, ecode, esignal = net_ssh_exec!(cmd_clean)
|
495
552
|
|
496
553
|
rap = Rye::Rap.new(self)
|
@@ -500,11 +557,15 @@ module Rye
|
|
500
557
|
rap.exit_signal = esignal
|
501
558
|
rap.cmd = cmd
|
502
559
|
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
560
|
+
if @post_command_hook.is_a?(Proc)
|
561
|
+
@post_command_hook.call(rap)
|
562
|
+
else
|
563
|
+
# It seems a convention for various commands to return -1
|
564
|
+
# when something only mildly concerning happens. ls even
|
565
|
+
# returns -1 for apparently no reason sometimes. In any
|
566
|
+
# case, the real errors are the ones greater than zero
|
567
|
+
raise Rye::CommandError.new(rap) if ecode > 0
|
568
|
+
end
|
508
569
|
|
509
570
|
rap
|
510
571
|
end
|
@@ -594,7 +655,7 @@ module Rye
|
|
594
655
|
end
|
595
656
|
|
596
657
|
if @current_working_directory
|
597
|
-
info "CWD (#{@current_working_directory})
|
658
|
+
info "CWD (#{@current_working_directory})"
|
598
659
|
end
|
599
660
|
|
600
661
|
files = [files].flatten.compact || []
|
data/lib/rye/cmd.rb
CHANGED
@@ -23,7 +23,8 @@ module Rye;
|
|
23
23
|
# TODO: Clean this trite mess up!
|
24
24
|
#++
|
25
25
|
|
26
|
-
|
26
|
+
# NOTE: See Rye::Box for the implementation of cd
|
27
|
+
#def cd(*args); cmd('cd', args); end
|
27
28
|
def wc(*args); cmd('wc', args); end
|
28
29
|
def cp(*args); cmd("cp", args); end
|
29
30
|
def mv(*args); cmd("mv", args); end
|
data/rye.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
@spec = Gem::Specification.new do |s|
|
2
2
|
s.name = "rye"
|
3
3
|
s.rubyforge_project = "rye"
|
4
|
-
s.version = "0.6.
|
4
|
+
s.version = "0.6.4"
|
5
5
|
s.summary = "Rye: Safely run SSH commands on a bunch of machines at the same time (from Ruby)."
|
6
6
|
s.description = s.summary
|
7
7
|
s.author = "Delano Mandelbaum"
|