rye 0.7.5 → 0.7.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +14 -1
- data/lib/rye.rb +12 -7
- data/lib/rye/box.rb +75 -33
- data/lib/rye/rap.rb +2 -3
- data/rye.gemspec +1 -1
- metadata +2 -2
data/CHANGES.txt
CHANGED
@@ -7,7 +7,20 @@ TODO
|
|
7
7
|
* Add S3 support for Rye::Box.upload / download
|
8
8
|
|
9
9
|
|
10
|
-
#### 0.7.
|
10
|
+
#### 0.7.6 (2009-06-19) #############################
|
11
|
+
|
12
|
+
* FIXED: Raise Rye::NoPty exception when Net::SSH returns message
|
13
|
+
"Pseudo-terminal will not be allocated because stdin is not a terminal."
|
14
|
+
* FIXED: Rye::Box#disconnect would hang in some instances. Now waits 3 seconds.
|
15
|
+
* FIXED: Bug in net_ssh_exec which was causing it to not return an exit code
|
16
|
+
* CHANGE: All exceptions now inherit from Rye::Error (Runtimerror)
|
17
|
+
* CHANGE: A NoPassword exception is raised when a password prompt returns nil.
|
18
|
+
* CHANGE: pre_command_hook block arguments have changed:
|
19
|
+
NEW: complete command, user, host, nickname
|
20
|
+
OLD: command, args, user, host, nickname
|
21
|
+
|
22
|
+
|
23
|
+
#### 0.7.5 (2009-06-13) #############################
|
11
24
|
|
12
25
|
* FIXED: Rye::Set methods were not accepting or passing blocks.
|
13
26
|
* ADDED: Rye::Set#user and Rye::Set#opts methods
|
data/lib/rye.rb
CHANGED
@@ -11,6 +11,7 @@ require 'net/scp'
|
|
11
11
|
require 'openssl'
|
12
12
|
require 'tempfile'
|
13
13
|
require 'highline'
|
14
|
+
require 'timeout'
|
14
15
|
|
15
16
|
require 'storable'
|
16
17
|
require 'sysinfo'
|
@@ -59,21 +60,25 @@ module Rye
|
|
59
60
|
# Accessor for an instance of SystemInfo
|
60
61
|
def sysinfo; SYSINFO; end
|
61
62
|
|
62
|
-
class
|
63
|
-
class
|
64
|
-
class
|
65
|
-
|
66
|
-
|
63
|
+
class RyeError < RuntimeError; end
|
64
|
+
class NoBoxes < RyeError; end
|
65
|
+
class NoPassword < RyeError
|
66
|
+
def message; "Password prompt did not return a value"; end
|
67
|
+
end
|
68
|
+
class NoHost < RyeError; end
|
69
|
+
class NotConnected < RyeError; end
|
70
|
+
class CommandNotFound < RyeError; end
|
71
|
+
class NoPty < RyeError
|
67
72
|
def message; "Could not obtain pty (i.e. an interactive ssh session)"; end
|
68
73
|
end
|
69
|
-
class CommandError <
|
74
|
+
class CommandError < RyeError
|
70
75
|
attr_reader :rap
|
71
76
|
# * +rap+ a Rye::Rap object
|
72
77
|
def initialize(rap)
|
73
78
|
@rap = rap
|
74
79
|
end
|
75
80
|
def message
|
76
|
-
"(code: %s)
|
81
|
+
"%s (code: %s)" % [@rap.stderr.join($/), @rap.exit_code]
|
77
82
|
end
|
78
83
|
def stderr; @rap.stderr if @rap; end
|
79
84
|
def stdout; @rap.stdout if @rap; end
|
data/lib/rye/box.rb
CHANGED
@@ -194,17 +194,7 @@ module Rye
|
|
194
194
|
disconnect
|
195
195
|
connect
|
196
196
|
end
|
197
|
-
|
198
|
-
|
199
|
-
# Close the SSH session with +@rye_host+. This is called
|
200
|
-
# automatically at exit if the connection is open.
|
201
|
-
def disconnect
|
202
|
-
return unless @rye_ssh && !@rye_ssh.closed?
|
203
|
-
@rye_ssh.loop(0.1) { @rye_ssh.busy? }
|
204
|
-
debug "Closing connection to #{@rye_ssh.host}"
|
205
|
-
@rye_ssh.close
|
206
|
-
end
|
207
|
-
|
197
|
+
|
208
198
|
|
209
199
|
# Open an interactive SSH session. This only works if STDIN.tty?
|
210
200
|
# returns true. Otherwise it returns the SSH command that would
|
@@ -594,6 +584,22 @@ module Rye
|
|
594
584
|
self
|
595
585
|
end
|
596
586
|
|
587
|
+
# Close the SSH session with +@rye_host+. This is called
|
588
|
+
# automatically at exit if the connection is open.
|
589
|
+
def disconnect
|
590
|
+
return unless @rye_ssh && !@rye_ssh.closed?
|
591
|
+
begin
|
592
|
+
Timeout::timeout(3) do
|
593
|
+
@rye_ssh.loop(0.3) { @rye_ssh.busy?; }
|
594
|
+
end
|
595
|
+
rescue Timeout::Error => ex
|
596
|
+
error "Disconnect timeout (was something still running?)"
|
597
|
+
end
|
598
|
+
|
599
|
+
debug "Closing connection to #{@rye_ssh.host}"
|
600
|
+
@rye_ssh.close
|
601
|
+
end
|
602
|
+
|
597
603
|
|
598
604
|
private
|
599
605
|
|
@@ -655,12 +661,6 @@ module Rye
|
|
655
661
|
cmd_clean = [cwd, cmd_clean].join(' && ')
|
656
662
|
end
|
657
663
|
|
658
|
-
info "COMMAND: #{cmd_clean}"
|
659
|
-
debug "Executing: %s" % cmd_clean
|
660
|
-
|
661
|
-
if @rye_pre_command_hook.is_a?(Proc)
|
662
|
-
@rye_pre_command_hook.call(cmd, args, user, host, nickname)
|
663
|
-
end
|
664
664
|
|
665
665
|
## NOTE: Do not raise a CommandNotFound exception in this method.
|
666
666
|
# We want it to be possible to define methods to a single instance
|
@@ -672,6 +672,13 @@ module Rye
|
|
672
672
|
## raise Rye::CommandNotFound unless self.can?(cmd)
|
673
673
|
|
674
674
|
begin
|
675
|
+
info "COMMAND: #{cmd_clean}"
|
676
|
+
debug "Executing: %s" % cmd_clean
|
677
|
+
|
678
|
+
if @rye_pre_command_hook.is_a?(Proc)
|
679
|
+
@rye_pre_command_hook.call(cmd_clean, user, host, nickname)
|
680
|
+
end
|
681
|
+
|
675
682
|
stdout, stderr, ecode, esignal = net_ssh_exec!(cmd_clean)
|
676
683
|
|
677
684
|
rap = Rye::Rap.new(self)
|
@@ -681,16 +688,30 @@ module Rye
|
|
681
688
|
rap.exit_signal = esignal
|
682
689
|
rap.cmd = cmd
|
683
690
|
|
691
|
+
#info "stdout: #{rap.stdout}"
|
692
|
+
#info "stderr: #{rap.stderr}"
|
693
|
+
#info "exit_code: #{rap.exit_code}"
|
694
|
+
|
684
695
|
# It seems a convention for various commands to return -1
|
685
696
|
# when something only mildly concerning happens. ls even
|
686
697
|
# returns -1 for apparently no reason sometimes. In any
|
687
698
|
# case, the real errors are the ones greater than zero
|
688
|
-
raise Rye::CommandError.new(rap) if ecode
|
699
|
+
raise Rye::CommandError.new(rap) if ecode != 0
|
689
700
|
|
690
701
|
rescue Exception => ex
|
691
|
-
|
692
|
-
|
693
|
-
|
702
|
+
choice = nil
|
703
|
+
@rye_exception_hook.each_pair do |klass,act|
|
704
|
+
next unless ex.kind_of? klass
|
705
|
+
choice = @rye_exception_hook[klass].call(ex)
|
706
|
+
break
|
707
|
+
end
|
708
|
+
if choice == :retry
|
709
|
+
retry
|
710
|
+
elsif choice == :skip
|
711
|
+
# do nothing
|
712
|
+
else
|
713
|
+
raise ex
|
714
|
+
end
|
694
715
|
end
|
695
716
|
|
696
717
|
@rye_post_command_hook.call(rap) if @rye_post_command_hook.is_a?(Proc)
|
@@ -729,42 +750,63 @@ module Rye
|
|
729
750
|
# http://www.ruby-forum.com/topic/169997
|
730
751
|
#
|
731
752
|
def net_ssh_exec!(command)
|
732
|
-
|
753
|
+
|
733
754
|
block ||= Proc.new do |channel, type, data|
|
755
|
+
|
734
756
|
channel[:stdout] ||= ""
|
735
757
|
channel[:stderr] ||= ""
|
736
|
-
channel[:exit_code] ||= 0
|
737
758
|
channel[:stdout] << data if type == :stdout
|
759
|
+
|
738
760
|
if type == :stderr
|
739
761
|
# NOTE: Use sudo to test this since it prompts for a passwords.
|
740
762
|
# Use sudo -K to kill the user's timestamp (ask for a password every time)
|
741
763
|
if data =~ /Password:/
|
742
764
|
ret = Annoy.get_user_input("Password: ", '*')
|
765
|
+
raise Rye::NoPassword if ret.nil?
|
743
766
|
channel.send_data "#{ret}\n"
|
744
767
|
else
|
745
768
|
channel[:stderr] << data
|
746
769
|
end
|
770
|
+
|
771
|
+
# If someone tries to open an interactive ssh session
|
772
|
+
# through a regular Rye::Box command, Net::SSH will
|
773
|
+
# return the following error and appear to hang. We
|
774
|
+
# catch it and raise the appropriate exception.
|
775
|
+
raise Rye::NoPty if data =~ /Pseudo-terminal will not/
|
776
|
+
|
747
777
|
end
|
748
|
-
|
749
|
-
# Anything greater than 0 is an error
|
750
|
-
channel[:exit_code] = data.read_long
|
751
|
-
end
|
752
|
-
channel.on_request("exit-signal") do |ch, data|
|
753
|
-
# This should be the POSIX SIGNAL that ended the process
|
754
|
-
channel[:exit_signal] = data.read_long
|
755
|
-
end
|
778
|
+
|
756
779
|
end
|
757
780
|
|
758
781
|
channel = @rye_ssh.exec(command, &block)
|
759
782
|
|
783
|
+
channel.on_request("exit-status") do |ch, data|
|
784
|
+
# Anything greater than 0 is an error
|
785
|
+
channel[:exit_code] = data.read_long
|
786
|
+
end
|
787
|
+
channel.on_request("exit-signal") do |ch, data|
|
788
|
+
# This should be the POSIX SIGNAL that ended the process
|
789
|
+
channel[:exit_signal] = data.read_long
|
790
|
+
end
|
791
|
+
|
760
792
|
channel.wait # block until we get a response
|
761
793
|
channel.request_pty do |ch, success|
|
762
794
|
raise Rye::NoPty if !success
|
763
795
|
end
|
764
796
|
|
765
|
-
|
797
|
+
## I'm getting weird behavior with exit codes. Sometimes
|
798
|
+
## a command which usually returns an exit code will not
|
799
|
+
## return one the next time it's run. The following crap
|
800
|
+
## was from the debugging.
|
801
|
+
##Kernel.sleep 5
|
802
|
+
###channel.close
|
803
|
+
#channel.eof!
|
804
|
+
##p [:active, channel.active?]
|
805
|
+
##p [:closing, channel.closing?]
|
806
|
+
##p [:eof, channel.eof?]
|
807
|
+
|
808
|
+
channel[:exit_code] ||= 0
|
766
809
|
channel[:exit_code] &&= channel[:exit_code].to_i
|
767
|
-
|
768
810
|
channel[:stderr].gsub!(/bash: line \d+:\s+/, '') if channel[:stderr]
|
769
811
|
|
770
812
|
[channel[:stdout], channel[:stderr], channel[:exit_code], channel[:exit_signal]]
|
data/lib/rye/rap.rb
CHANGED
@@ -76,13 +76,12 @@ module Rye;
|
|
76
76
|
# it's just an exit code returned by Net::SSH.
|
77
77
|
# Returns the exit code as an Integer.
|
78
78
|
def add_exit_code(code)
|
79
|
-
code =
|
79
|
+
code = 0 if code.nil?
|
80
80
|
if code.is_a?(Process::Status)
|
81
81
|
@exit_code, @pid = code.exitstatus.to_i, code.pid
|
82
82
|
else
|
83
83
|
@exit_code = code.to_i
|
84
84
|
end
|
85
|
-
@exit_code
|
86
85
|
end
|
87
86
|
def code; @exit_code; end
|
88
87
|
|
@@ -91,7 +90,7 @@ module Rye;
|
|
91
90
|
def to_s
|
92
91
|
return self.first if self.size == 1
|
93
92
|
return "" if self.size == 0
|
94
|
-
|
93
|
+
super
|
95
94
|
end
|
96
95
|
|
97
96
|
# Output STDOUT content to (remote) +path+
|
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.7.
|
4
|
+
s.version = "0.7.6"
|
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"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rye
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delano Mandelbaum
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-06-
|
12
|
+
date: 2009-06-19 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|