Skip to content

Commit

Permalink
* FIXED: Raise Rye::NoPty exception when Net::SSH returns message
Browse files Browse the repository at this point in the history
  "Pseudo-terminal will not be allocated because stdin is not a terminal."
* FIXED: Rye::Box#disconnect would hang in some instances. Now waits 3 seconds.
* CHANGE: All exceptions now inherit from Rye::Error (Runtimerror)
* CHANGE: A NoPassword exception is raised when a password prompt returns nil.
  • Loading branch information
delano committed Jun 14, 2009
1 parent 758116d commit 8099fc2
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 21 deletions.
11 changes: 10 additions & 1 deletion CHANGES.txt
Expand Up @@ -7,7 +7,16 @@ TODO
* Add S3 support for Rye::Box.upload / download


#### 0.7.5 (2009-06-14) #############################
#### 0.7.6 (2009-06-14) #############################

* FIXED: Raise Rye::NoPty exception when Net::SSH returns message
"Pseudo-terminal will not be allocated because stdin is not a terminal."
* FIXED: Rye::Box#disconnect would hang in some instances. Now waits 3 seconds.
* CHANGE: All exceptions now inherit from Rye::Error (Runtimerror)
* CHANGE: A NoPassword exception is raised when a password prompt returns nil.


#### 0.7.5 (2009-06-13) #############################

* FIXED: Rye::Set methods were not accepting or passing blocks.
* ADDED: Rye::Set#user and Rye::Set#opts methods
Expand Down
17 changes: 11 additions & 6 deletions lib/rye.rb
Expand Up @@ -11,6 +11,7 @@
require 'openssl'
require 'tempfile'
require 'highline'
require 'timeout'

require 'storable'
require 'sysinfo'
Expand Down Expand Up @@ -59,14 +60,18 @@ def Rye.sysinfo; SYSINFO; end
# Accessor for an instance of SystemInfo
def sysinfo; SYSINFO; end

class NoBoxes < RuntimeError; end
class NoHost < RuntimeError; end
class NotConnected < RuntimeError; end
class CommandNotFound < RuntimeError; end
class NoPty < RuntimeError
class RyeError < RuntimeError; end
class NoBoxes < RyeError; end
class NoPassword < RyeError
def message; "Password prompt did not return a value"; end
end
class NoHost < RyeError; end
class NotConnected < RyeError; end
class CommandNotFound < RyeError; end
class NoPty < RyeError
def message; "Could not obtain pty (i.e. an interactive ssh session)"; end
end
class CommandError < RuntimeError
class CommandError < RyeError
attr_reader :rap
# * +rap+ a Rye::Rap object
def initialize(rap)
Expand Down
48 changes: 34 additions & 14 deletions lib/rye/box.rb
Expand Up @@ -194,17 +194,7 @@ def switch_user(newuser)
disconnect
connect
end


# Close the SSH session with +@rye_host+. This is called
# automatically at exit if the connection is open.
def disconnect
return unless @rye_ssh && !@rye_ssh.closed?
@rye_ssh.loop(0.1) { @rye_ssh.busy? }
debug "Closing connection to #{@rye_ssh.host}"
@rye_ssh.close
end



# Open an interactive SSH session. This only works if STDIN.tty?
# returns true. Otherwise it returns the SSH command that would
Expand Down Expand Up @@ -594,6 +584,22 @@ def connect(reconnect=true)
self
end

# Close the SSH session with +@rye_host+. This is called
# automatically at exit if the connection is open.
def disconnect
return unless @rye_ssh && !@rye_ssh.closed?
begin
Timeout::timeout(3) do
@rye_ssh.loop(0.3) { @rye_ssh.busy?; }
end
rescue Timeout::Error => ex
error "Disconnect timeout (was something still running?)"
end

debug "Closing connection to #{@rye_ssh.host}"
@rye_ssh.close
end


private

Expand Down Expand Up @@ -688,9 +694,14 @@ def run_command(*args)
raise Rye::CommandError.new(rap) if ecode > 0

rescue Exception => ex
raise ex unless @rye_exception_hook.has_key? ex.class
ret = @rye_exception_hook[ex.class].call(ex)
retry if ret == :retry
choice = nil
@rye_exception_hook.each_pair do |klass,act|
next unless ex.kind_of? klass
choice = @rye_exception_hook[klass].call(ex)
break
end
retry if choice == :retry
raise ex if choice.nil?
end

@rye_post_command_hook.call(rap) if @rye_post_command_hook.is_a?(Proc)
Expand Down Expand Up @@ -740,10 +751,18 @@ def net_ssh_exec!(command)
# Use sudo -K to kill the user's timestamp (ask for a password every time)
if data =~ /Password:/
ret = Annoy.get_user_input("Password: ", '*')
raise Rye::NoPassword if ret.nil?
channel.send_data "#{ret}\n"
else
channel[:stderr] << data
end

# If someone tries to open an interactive ssh session
# through a regular Rye::Box command, Net::SSH will
# return the following error and appear to hang. We
# catch it and raise the appropriate exception.
raise Rye::NoPty if data =~ /Pseudo-terminal will not/

end
channel.on_request("exit-status") do |ch, data|
# Anything greater than 0 is an error
Expand All @@ -753,6 +772,7 @@ def net_ssh_exec!(command)
# This should be the POSIX SIGNAL that ended the process
channel[:exit_signal] = data.read_long
end

end

channel = @rye_ssh.exec(command, &block)
Expand Down

0 comments on commit 8099fc2

Please sign in to comment.