em-ssh 0.5.1 → 0.6.0
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/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
|