em-ssh 0.2.1 → 0.3.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -7,45 +7,50 @@ Em-ssh is not associated with the Jamis Buck's [net-ssh](http://net-ssh.github.c
7
7
 
8
8
  ##Synopsis
9
9
  EM.run do
10
- EM::Ssh.start(host, user, :password => password) do |ssh|
11
- # capture all stderr and stdout output from a remote process
12
- ssh.exec!('uname -a').tap {|r| puts "\nuname: #{r}"}
13
-
14
- # capture only stdout matching a particular pattern
15
- stdout = ""
16
- ssh.exec!("ls -l /home") do |channel, stream, data|
17
- stdout << data if stream == :stdout
18
- end
19
- puts "\n#{stdout}"
20
-
21
- # run multiple processes in parallel to completion
22
- ssh.exec('ping -c 1 www.google.com')
23
- ssh.exec('ping -c 1 www.yahoo.com')
24
- ssh.exec('ping -c 1 www.rakuten.co.jp')
25
-
26
- #open a new channel and configure a minimal set of callbacks, then wait for the channel to finishes (closees).
27
- channel = ssh.open_channel do |ch|
28
- ch.exec "/usr/local/bin/ruby /path/to/file.rb" do |ch, success|
29
- raise "could not execute command" unless success
30
-
31
- # "on_data" is called when the process writes something to stdout
32
- ch.on_data do |c, data|
33
- $stdout.print data
34
- end
35
-
36
- # "on_extended_data" is called when the process writes something to stderr
37
- ch.on_extended_data do |c, type, data|
38
- $stderr.print data
39
- end
40
-
41
- ch.on_close { puts "done!" }
42
- end
43
- end
44
-
45
- channel.wait
46
-
47
- ssh.close
48
- EM.stop
10
+ EM::Ssh.start(host, user, :password => password) do |connection|
11
+ connection.errback do |err|
12
+ $stderr.puts "#{err} (#{err.class})"
13
+ end
14
+ connection.callback do |ssh|
15
+ # capture all stderr and stdout output from a remote process
16
+ ssh.exec!('uname -a').tap {|r| puts "\nuname: #{r}"}
17
+
18
+ # capture only stdout matching a particular pattern
19
+ stdout = ""
20
+ ssh.exec!("ls -l /home") do |channel, stream, data|
21
+ stdout << data if stream == :stdout
22
+ end
23
+ puts "\n#{stdout}"
24
+
25
+ # run multiple processes in parallel to completion
26
+ ssh.exec('ping -c 1 www.google.com')
27
+ ssh.exec('ping -c 1 www.yahoo.com')
28
+ ssh.exec('ping -c 1 www.rakuten.co.jp')
29
+
30
+ #open a new channel and configure a minimal set of callbacks, then wait for the channel to finishes (closees).
31
+ channel = ssh.open_channel do |ch|
32
+ ch.exec "/usr/local/bin/ruby /path/to/file.rb" do |ch, success|
33
+ raise "could not execute command" unless success
34
+
35
+ # "on_data" is called when the process writes something to stdout
36
+ ch.on_data do |c, data|
37
+ $stdout.print data
38
+ end
39
+
40
+ # "on_extended_data" is called when the process writes something to stderr
41
+ ch.on_extended_data do |c, type, data|
42
+ $stderr.print data
43
+ end
44
+
45
+ ch.on_close { puts "done!" }
46
+ end
47
+ end
48
+
49
+ channel.wait
50
+
51
+ ssh.close
52
+ EM.stop
53
+ end
49
54
  end
50
55
  end
51
56
 
data/bin/em-ssh CHANGED
@@ -66,37 +66,45 @@ end
66
66
 
67
67
 
68
68
  EM.run do
69
- EM::Ssh.start(host, options[:user], options) do |connection|
70
- debug "**** connected: #{connection}"
71
- connection.open_channel do |channel|
72
- debug "**** channel: #{channel}"
73
- channel.request_pty(options[:pty] || {}) do |pty,suc|
74
- debug "***** pty: #{pty}; suc: #{suc}"
75
- pty.send_channel_request("shell") do |shell,success|
76
- raise ConnectionError, "Failed to create shell." unless success
77
- debug "***** shell: #{shell}"
78
- connected = true
79
-
80
- shell.on_data { |c,d| $stdout.print d }
81
- shell.on_extended_data { |c,data| $STDERR.print data }
82
- shell.on_eof do
83
- shell.close
84
- EM.stop
85
- end #
86
-
87
- trap("SIGINT") { shell.send_data("\C-c") }
88
- trap("SIGEXIT") do
89
- shell.close
90
- trap("SIGINT", "SIG_DFL")
91
- end #
92
-
93
- conn = EM.watch($stdin, CInput)
94
- conn.shell = shell
95
- conn.notify_readable = true
96
-
97
- end # |shell,success|
98
- end # |pty,suc|
99
- end # |channel|
69
+ EM::Ssh.start(host, options[:user], options) do |ssh|
70
+ ssh.errback do |err|
71
+ puts "#{err} (#{err.class})"
72
+ EM.stop
73
+ end
74
+
75
+ ssh.callback do |connection|
76
+ debug "**** connected: #{connection}"
77
+ connection.open_channel do |channel|
78
+ debug "**** channel: #{channel}"
79
+ channel.request_pty(options[:pty] || {}) do |pty,suc|
80
+ debug "***** pty: #{pty}; suc: #{suc}"
81
+ pty.send_channel_request("shell") do |shell,success|
82
+ raise ConnectionError, "Failed to create shell." unless success
83
+ debug "***** shell: #{shell}"
84
+ connected = true
85
+
86
+ shell.on_data { |c,d| $stdout.print d }
87
+ shell.on_extended_data { |c,data| $STDERR.print data }
88
+ shell.on_eof do
89
+ shell.close
90
+ EM.stop
91
+ end #
92
+
93
+ trap("SIGINT") { shell.send_data("\C-c") }
94
+ trap("SIGEXIT") do
95
+ shell.close
96
+ trap("SIGINT", "SIG_DFL")
97
+ end #
98
+
99
+ conn = EM.watch($stdin, CInput)
100
+ conn.shell = shell
101
+ conn.notify_readable = true
102
+
103
+ end # |shell,success|
104
+ end # |pty,suc|
105
+ end # |channel|
106
+ end
107
+
100
108
  end # |connection|
101
109
  end # EM.start
102
110
 
data/lib/em-ssh.rb CHANGED
@@ -50,8 +50,8 @@ module EventMachine
50
50
  # channel.request_pty(options[:pty] || {}) do |pty,suc|
51
51
  def connect(host, user, opts = {}, &blk)
52
52
  logger.debug("#{self}.connect(#{host}, #{user}, #{opts})")
53
- options = { :host => host, :user => user, :port => DEFAULT_PORT, :callback => blk }.merge(opts)
54
- EM.connect(options[:host], options[:port], Connection, options)
53
+ options = { :host => host, :user => user, :port => DEFAULT_PORT }.merge(opts)
54
+ EM.connect(options[:host], options[:port], Connection, options, &blk)
55
55
  end
56
56
  alias :start :connect
57
57
  end # << self
@@ -5,6 +5,7 @@ module EventMachine
5
5
  # itself into Net::SSH so that the EventMachine reactor loop can take the place of the Net::SSH event loop.
6
6
  # Most of the methods here are only for compatibility with Net::SSH
7
7
  class Connection < EventMachine::Connection
8
+ include EM::Deferrable
8
9
  include Log
9
10
 
10
11
  # Allows other objects to register callbacks with events that occur on a Ssh instance
@@ -127,11 +128,26 @@ module EventMachine
127
128
  @timeout = options[:timeout] || TIMEOUT
128
129
 
129
130
  begin
130
- on(:connected, &options[:callback]) if options[:callback]
131
- @nocon = on(:closed) { raise ConnectionFailed, @host }
132
- @contimeout = EM::Timer.new(@timeout) { raise ConnectionTimeout, @host }
131
+ on(:connected) do |session|
132
+ succeed(session, @host)
133
+ end
134
+ on(:error) do |e|
135
+ fail(e)
136
+ close_connection
137
+ end
138
+ @nocon = on(:closed) do
139
+ fail(SshError.new(@host))
140
+ close_connection
141
+ end
142
+ @contimeout = EM::Timer.new(@timeout) do
143
+ fail(ConnectionTimeout.new(@host))
144
+ close_connection
145
+ end
133
146
 
134
- @error_callback = lambda { |code| raise SshError.new(code) }
147
+ @error_callback = lambda do |code|
148
+ fail(SshError.new(code))
149
+ close_connection
150
+ end
135
151
 
136
152
  @host_key_verifier = select_host_key_verifier(options[:paranoid])
137
153
  @server_version = ServerVersion.new(self)
@@ -149,7 +165,6 @@ module EventMachine
149
165
  fire(:connected, Session.new(self, options))
150
166
  else
151
167
  fire(:error, Net::SSH::AuthenticationFailed.new(user))
152
- close_connection
153
168
  end # auth.authenticate("ssh-connection", user, options[:password])
154
169
  end.resume # Fiber
155
170
  end # :algo_init
@@ -157,7 +172,7 @@ module EventMachine
157
172
 
158
173
  rescue Exception => e
159
174
  log.fatal("caught an error during initialization: #{e}\n #{e.backtrace.join("\n ")}")
160
- Process.exit
175
+ fail(e)
161
176
  end # begin
162
177
  self
163
178
  end # initialize(options = {})
@@ -273,7 +288,12 @@ module EventMachine
273
288
  when :very then
274
289
  Net::SSH::Verifiers::Strict.new
275
290
  else
276
- paranoid.respond_to?(:verify) ? paranoid : (raise ArgumentError.new("argument to :paranoid is not valid: #{paranoid.inspect}"))
291
+ if paranoid.respond_to?(:verify)
292
+ paranoid
293
+ else
294
+ fail(@host, ArgumentError.new("argument to :paranoid is not valid: #{paranoid.inspect}"))
295
+ close_connection
296
+ end # paranoid.respond_to?(:verify)
277
297
  end # paranoid
278
298
  end # select_host_key_verifier(paranoid)
279
299
  end # class::Connection < EventMachine::Connection
@@ -61,7 +61,9 @@ module EventMachine
61
61
  @packet_length = @packet.read_long
62
62
  end
63
63
  need = @packet_length + 4 - server.block_size
64
- raise SshError, "padding error, need #{need} block #{server.block_size}" if need % server.block_size != 0
64
+ if need % server.block_size != 0
65
+ @connection.fire(:error, SshError.new("padding error, need #{need} block #{server.block_size}"))
66
+ end
65
67
 
66
68
  return nil if available < need + server.hmac.mac_length
67
69
 
@@ -82,7 +84,10 @@ module EventMachine
82
84
  padding = @packet.read(padding_length) if padding_length > 0
83
85
 
84
86
  my_computed_hmac = server.hmac.digest([server.sequence_number, @packet.content].pack("NA*"))
85
- raise Net::SSH::Exception, "corrupted mac detected" if real_hmac != my_computed_hmac
87
+ if real_hmac != my_computed_hmac
88
+ @connection.fire(:error, Net::SSH::Exception.new("corrupted mac detected"))
89
+ return
90
+ end
86
91
 
87
92
  # try to decompress the payload, in case compression is active
88
93
  payload = server.decompress(payload)
@@ -23,7 +23,9 @@ module EventMachine
23
23
  if @version[-1] == "\n"
24
24
  @version.chomp!
25
25
  log.debug("server version: #{@version}")
26
- raise SshError.new("incompatible SSH version `#{@version}'") unless @version.match(/^SSH-(1\.99|2\.0)-/)
26
+ unless @version.match(/^SSH-(1\.99|2\.0)-/)
27
+ return connection.fire(:error, SshError.new("incompatible SSH version `#{@version}'"))
28
+ end
27
29
  log.debug("local version: #{Net::SSH::Transport::ServerVersion::PROTO_VERSION}")
28
30
  connection.send_data("#{Net::SSH::Transport::ServerVersion::PROTO_VERSION}\r\n")
29
31
  cb.cancel
@@ -34,7 +34,10 @@ module EventMachine
34
34
 
35
35
  def register_callbacks
36
36
  transport.on(:packet) do |packet|
37
- raise SshError, "unexpected response #{packet.type} (#{packet.inspect})" unless MAP.key?(packet.type)
37
+ unless MAP.key?(packet.type)
38
+ transport.fire(:error, SshError.new("unexpected response #{packet.type} (#{packet.inspect})"))
39
+ return
40
+ end
38
41
  send(MAP[packet.type], packet)
39
42
  end # |packet|
40
43
 
data/lib/em-ssh/shell.rb CHANGED
@@ -236,11 +236,15 @@ module EventMachine
236
236
  return if connected?
237
237
  trace = caller
238
238
  f = Fiber.current
239
- con = ::EM::Ssh.start(host, user, connect_opts) { |connection| f.resume(@connection = connection) }
240
- con.on(:error) do |e|
241
- e.set_backtrace(trace + Array(e.backtrace))
242
- fire(:error, e)
243
- f.resume(e)
239
+ ::EM::Ssh.start(host, user, connect_opts) do |connection|
240
+ connection.callback do |ssh|
241
+ f.resume(@connection = ssh)
242
+ end # ssh
243
+ connection.errback do |e|
244
+ e.set_backtrace(trace + Array(e.backtrace))
245
+ fire(:error, e)
246
+ f.resume(e)
247
+ end # err
244
248
  end
245
249
  return Fiber.yield
246
250
  end
@@ -1,5 +1,5 @@
1
1
  module EventMachine
2
2
  class Ssh
3
- VERSION='0.2.1'
3
+ VERSION='0.3.0.pre0'
4
4
  end # class::Ssh
5
5
  end # module::EventMachine
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-ssh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
5
- prerelease:
4
+ version: 0.3.0.pre0
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Caleb Crane
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-02 00:00:00.000000000Z
12
+ date: 2012-05-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
16
- requirement: &70209705582020 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70209705582020
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: net-ssh
27
- requirement: &70209705581560 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: '0'
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *70209705581560
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: ruby-termios
38
- requirement: &70209705581140 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ! '>='
@@ -43,10 +53,15 @@ dependencies:
43
53
  version: '0'
44
54
  type: :development
45
55
  prerelease: false
46
- version_requirements: *70209705581140
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: highline
49
- requirement: &70209705580720 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ! '>='
@@ -54,7 +69,12 @@ dependencies:
54
69
  version: '0'
55
70
  type: :development
56
71
  prerelease: false
57
- version_requirements: *70209705580720
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
58
78
  description: ''
59
79
  email:
60
80
  - em-ssh@simulacre.org
@@ -98,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
118
  version: 1.3.6
99
119
  requirements: []
100
120
  rubyforge_project:
101
- rubygems_version: 1.8.10
121
+ rubygems_version: 1.8.21
102
122
  signing_key:
103
123
  specification_version: 3
104
124
  summary: An EventMachine compatible net-ssh