em-ssh 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -0
- data/bin/em-ssh-shell +15 -6
- data/lib/em-ssh/connection/channel/interactive.rb +1 -1
- data/lib/em-ssh/connection.rb +5 -1
- data/lib/em-ssh/shell.rb +12 -4
- data/lib/em-ssh/version.rb +1 -1
- data/lib/em-ssh.rb +61 -0
- metadata +2 -2
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
0.6.0
|
2
|
+
- Disconnect error codes are converted to Ruby exceptions and raised
|
3
|
+
- ChannelOpen error codes are converted to Ruby exceptions and raised
|
4
|
+
- Shell#split will detect ChannelOpen errors and raise an Exception
|
5
|
+
|
1
6
|
0.5.1
|
2
7
|
- [#21](https://github.com/simulacre/em-ssh/pull/22) - Fix em-ssh throws exception when no logger is defined [@mandre](https://github.com/mandre)
|
3
8
|
- [#20](https://github.com/simulacre/em-ssh/pull/20) - Fix Interactive timeout wasn't set if parameter not fed [@freakhill](https://github.com/freakhill)
|
data/bin/em-ssh-shell
CHANGED
@@ -62,20 +62,29 @@ EM.run do
|
|
62
62
|
|
63
63
|
shell.callback do
|
64
64
|
commands.clone.each do |command|
|
65
|
+
|
65
66
|
mys = shell.split
|
67
|
+
mys.errback do |err|
|
68
|
+
$stderr.puts "subshell error: #{err} (#{err.class})"
|
69
|
+
mys.close
|
70
|
+
end
|
71
|
+
|
66
72
|
mys.on(:closed) do
|
67
73
|
commands.delete(command)
|
68
74
|
EM.stop if commands.empty?
|
69
75
|
end
|
70
76
|
|
71
77
|
puts("waiting for: #{waitstr.inspect}")
|
72
|
-
mys.
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
78
|
+
mys.callback do
|
79
|
+
mys.expect(waitstr) do
|
80
|
+
puts "sending #{command.inspect} and waiting for #{waitstr.inspect}"
|
81
|
+
mys.expect(waitstr, command) do |result|
|
82
|
+
puts "#{mys} result: '#{result}'"
|
83
|
+
mys.close
|
84
|
+
end
|
77
85
|
end
|
78
|
-
end
|
86
|
+
end
|
87
|
+
|
79
88
|
end
|
80
89
|
end
|
81
90
|
end
|
@@ -129,7 +129,7 @@ module EventMachine
|
|
129
129
|
|
130
130
|
timeout_proc = proc do
|
131
131
|
data_callback && data_callback.cancel
|
132
|
-
f.resume(TimeoutError.new("#{
|
132
|
+
f.resume(TimeoutError.new("#{@host}: inactivity timeout (#{opts[:timeout]}) while waiting for #{strregex.inspect}; received: #{buffer.inspect}; waited total: #{Time.new - started}"))
|
133
133
|
end
|
134
134
|
|
135
135
|
data_callback = on(:data) do
|
data/lib/em-ssh/connection.rb
CHANGED
@@ -128,7 +128,10 @@ module EventMachine
|
|
128
128
|
instance_variable_set(iv, nil)
|
129
129
|
end
|
130
130
|
|
131
|
-
|
131
|
+
if failed_timeout
|
132
|
+
fail(@disconnect ? EM::Ssh::Disconnect.from_packet(@disconnect) : NegotiationTimeout.new(@host))
|
133
|
+
|
134
|
+
end
|
132
135
|
end
|
133
136
|
|
134
137
|
def receive_data(data)
|
@@ -289,6 +292,7 @@ module EventMachine
|
|
289
292
|
while (packet = @socket.poll_next_packet)
|
290
293
|
case packet.type
|
291
294
|
when DISCONNECT
|
295
|
+
@disconnect = packet
|
292
296
|
close_connection
|
293
297
|
when IGNORE
|
294
298
|
debug("IGNORE packet received: #{packet[:data].inspect}")
|
data/lib/em-ssh/shell.rb
CHANGED
@@ -87,8 +87,12 @@ module EventMachine
|
|
87
87
|
# TODO make all methods other than #callback and #errback inaccessible until connected? == true
|
88
88
|
yield self if block_given?
|
89
89
|
Fiber.new {
|
90
|
-
|
91
|
-
|
90
|
+
begin
|
91
|
+
open
|
92
|
+
succeed(self) if connected? && !closed?
|
93
|
+
rescue => e
|
94
|
+
fail(e)
|
95
|
+
end
|
92
96
|
}.resume
|
93
97
|
end
|
94
98
|
|
@@ -155,6 +159,7 @@ module EventMachine
|
|
155
159
|
Fiber.new { yield(self) if block_given? }.resume
|
156
160
|
f.resume(self)
|
157
161
|
end
|
162
|
+
@on_open_err = proc { |e| f.resume(e) }
|
158
163
|
open!
|
159
164
|
return Fiber.yield.tap { |r| raise r if r.is_a?(Exception) }
|
160
165
|
end
|
@@ -166,7 +171,7 @@ module EventMachine
|
|
166
171
|
@opening = true
|
167
172
|
begin
|
168
173
|
connect
|
169
|
-
session.open_channel do |channel|
|
174
|
+
chan = session.open_channel do |channel|
|
170
175
|
debug "**** channel open: #{channel}"
|
171
176
|
channel.request_pty(options[:pty] || {}) do |pty,suc|
|
172
177
|
debug "***** pty open: #{pty}; suc: #{suc}"
|
@@ -186,6 +191,9 @@ module EventMachine
|
|
186
191
|
end # |shell,success|
|
187
192
|
end # |pty,suc|
|
188
193
|
end # |channel|
|
194
|
+
chan.on_open_failed do |chan, code, desc|
|
195
|
+
@on_open_err && @on_open_err[ChannelOpenFailed.from_code(code, desc)]
|
196
|
+
end
|
189
197
|
rescue => e
|
190
198
|
@opening = false
|
191
199
|
raise ConnectionError.new("failed to create shell for #{host}: #{e} (#{e.class})")
|
@@ -236,7 +244,7 @@ module EventMachine
|
|
236
244
|
fire(:split, child)
|
237
245
|
if block_given?
|
238
246
|
# requires that the caller be in a Fiber
|
239
|
-
child.open
|
247
|
+
child.open
|
240
248
|
yield(child).tap { child.close }
|
241
249
|
else
|
242
250
|
child
|
data/lib/em-ssh/version.rb
CHANGED
data/lib/em-ssh.rb
CHANGED
@@ -28,6 +28,67 @@ module EventMachine
|
|
28
28
|
class ConnectionTerminated < SshError; end
|
29
29
|
# The server failed to negotiate an ssh protocol version
|
30
30
|
class NegotiationTimeout < ConnectionFailed; end
|
31
|
+
class Disconnect < SshError
|
32
|
+
class HostNotAllowedToConnect < Disconnect; end
|
33
|
+
class ProtocolError < Disconnect; end
|
34
|
+
class KeyExchangeFailed < Disconnect; end
|
35
|
+
class Reserved < Disconnect; end
|
36
|
+
class MacError < Disconnect; end
|
37
|
+
class CompressionError < Disconnect; end
|
38
|
+
class ServiceNotAvailable < Disconnect; end
|
39
|
+
class ProtocolVersionNotSupported < Disconnect; end
|
40
|
+
class HostKeyNotVerifiable < Disconnect; end
|
41
|
+
class ConnectionLost < Disconnect; end
|
42
|
+
class ByApplication < Disconnect; end
|
43
|
+
class TooManyConnections < Disconnect; end
|
44
|
+
class AuthCancelledByUser < Disconnect; end
|
45
|
+
class NoMoreAuthMethodsAvailable < Disconnect; end
|
46
|
+
class IllegalUserName < Disconnect; end
|
47
|
+
|
48
|
+
CODES = [
|
49
|
+
Disconnect,
|
50
|
+
HostNotAllowedToConnect,
|
51
|
+
ProtocolError,
|
52
|
+
KeyExchangeFailed,
|
53
|
+
Reserved,
|
54
|
+
MacError,
|
55
|
+
CompressionError,
|
56
|
+
ServiceNotAvailable,
|
57
|
+
ProtocolVersionNotSupported,
|
58
|
+
HostKeyNotVerifiable,
|
59
|
+
ConnectionLost,
|
60
|
+
ByApplication,
|
61
|
+
TooManyConnections,
|
62
|
+
AuthCancelledByUser,
|
63
|
+
NoMoreAuthMethodsAvailable,
|
64
|
+
IllegalUserName,
|
65
|
+
]
|
66
|
+
class << self
|
67
|
+
def from_packet(packet)
|
68
|
+
(CODES[packet[:reason_code]] || Disconnect).new(packet[:description])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end # class::Disconnect < SshError
|
72
|
+
|
73
|
+
class ChannelOpenFailed < Net::SSH::ChannelOpenFailed
|
74
|
+
include Error
|
75
|
+
class AdministrativelyProhibited < ChannelOpenFailed; end
|
76
|
+
class ConnectFailed < ChannelOpenFailed; end
|
77
|
+
class UnknownChannelType < ChannelOpenFailed; end
|
78
|
+
class ResourceShortage < ChannelOpenFailed; end
|
79
|
+
CODES = [
|
80
|
+
ChannelOpenFailed,
|
81
|
+
AdministrativelyProhibited,
|
82
|
+
ConnectFailed,
|
83
|
+
UnknownChannelType,
|
84
|
+
ResourceShortage
|
85
|
+
]
|
86
|
+
class << self
|
87
|
+
def from_code(code, desc)
|
88
|
+
(CODES[code] || ChannelOpenFailed).new(code, desc)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
31
92
|
|
32
93
|
|
33
94
|
class << self
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: em-ssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-06-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|