rye 0.7.5 → 0.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.5 (2009-06-14) #############################
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 NoBoxes < RuntimeError; end
63
- class NoHost < RuntimeError; end
64
- class NotConnected < RuntimeError; end
65
- class CommandNotFound < RuntimeError; end
66
- class NoPty < RuntimeError
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 < RuntimeError
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) %s" % [@rap.exit_code, @rap.stderr.join($/)]
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 > 0
699
+ raise Rye::CommandError.new(rap) if ecode != 0
689
700
 
690
701
  rescue Exception => ex
691
- raise ex unless @rye_exception_hook.has_key? ex.class
692
- ret = @rye_exception_hook[ex.class].call(ex)
693
- retry if ret == :retry
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
- channel.on_request("exit-status") do |ch, data|
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
- channel[:exit_code] = 0 if channel[:exit_code] == nil
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 = -1 unless 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
- self
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.5"
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.5
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-13 00:00:00 -04:00
12
+ date: 2009-06-19 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency