remote-dcl 0.2.0 → 0.3.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/README.rdoc +13 -7
- data/bin/remote-dcl +115 -49
- data/lib/remote-dcl/version.rb +1 -1
- data/remote-dcl.gemspec +3 -0
- metadata +32 -4
data/README.rdoc
CHANGED
@@ -5,22 +5,22 @@
|
|
5
5
|
Remote-DCL is a Ruby script to execute a script at a remote server.
|
6
6
|
DCL calles in the script creates PNG images at the remote,
|
7
7
|
and send them to local and then display the images.
|
8
|
-
It
|
8
|
+
It avoids X connection between the local and the remote,
|
9
9
|
so could reduce execution time.
|
10
10
|
|
11
11
|
|
12
12
|
== Requires
|
13
13
|
* At remote server
|
14
|
-
*
|
14
|
+
* Ruby (http://www.ruby-lang.org/)
|
15
15
|
* Ruby libraries which are required in your script (including DCL)
|
16
16
|
* stdbuf command
|
17
17
|
* ssh server
|
18
18
|
* Xvfb
|
19
19
|
xvfb-run command (optional)
|
20
20
|
* At local
|
21
|
-
*
|
22
|
-
*
|
23
|
-
* ssh
|
21
|
+
* Ruby (http://www.ruby-lang.org/)
|
22
|
+
* Ruby/GTK2, Ruby/GdkPixbuf2 (http://ruby-gnome2.sourceforge.jp/ja/)
|
23
|
+
* Net::SSH (http://net-ssh.rubyforge.org/)
|
24
24
|
|
25
25
|
|
26
26
|
== Install / Download
|
@@ -45,7 +45,7 @@ Note: xvfb-run command lounch Xvfb server internally, and the lounching is occue
|
|
45
45
|
It takes some seconds, so lounching Xvfb server by your self reduces execution time of remote-dcl.
|
46
46
|
|
47
47
|
==== At local
|
48
|
-
% remote-dcl [--display=] [--dir=] [--remote] server_name script_name [args]
|
48
|
+
% remote-dcl [--display=] [--dir=] [--user=] [--password=] [--remote] server_name script_name [args]
|
49
49
|
* server_name:
|
50
50
|
server name at which the script is execued
|
51
51
|
* script_name:
|
@@ -56,9 +56,15 @@ It takes some seconds, so lounching Xvfb server by your self reduces execution t
|
|
56
56
|
* dir (optional):
|
57
57
|
directory name of the remote server at which the script is executed
|
58
58
|
If this is ommited, the script is executed at the home directory.
|
59
|
+
* user (optional)
|
60
|
+
user name of remote server for ssh connection.
|
61
|
+
User name can be specified by username@server_name format as server_name
|
62
|
+
* password (optional)
|
63
|
+
password of user for ssh connection
|
64
|
+
If this is ommited, password is asked in prompt.
|
59
65
|
* remote (optional):
|
60
66
|
If --remote option is set, the script should be at the remote server,
|
61
|
-
|
67
|
+
otherwise at local.
|
62
68
|
|
63
69
|
=== User Interface
|
64
70
|
Actions with key and mouse events are the followings:
|
data/bin/remote-dcl
CHANGED
@@ -13,14 +13,16 @@ usage if ARGV.index("--help") || ARGV.index("-h")
|
|
13
13
|
opts = {
|
14
14
|
"display" => nil,
|
15
15
|
"dir" => nil,
|
16
|
-
"
|
16
|
+
"user" => nil,
|
17
|
+
"password" => nil,
|
18
|
+
"remote" => false,
|
17
19
|
}
|
18
20
|
opts.keys.each do |name|
|
19
21
|
ARGV.dup.each do |opt|
|
20
22
|
next unless /\A--#{name}/ =~ opt
|
21
23
|
val = $' && $'[1..-1]
|
22
24
|
case name
|
23
|
-
when "display", "dir"
|
25
|
+
when "display", "dir", "user", "password"
|
24
26
|
opts[name] = val
|
25
27
|
when "remote"
|
26
28
|
opts[name] = true
|
@@ -146,23 +148,35 @@ Process.wait(pid)
|
|
146
148
|
EOC
|
147
149
|
|
148
150
|
|
149
|
-
def
|
151
|
+
def escape_ruby(str) # escape special charactors
|
152
|
+
str.gsub!(/\$/, '\$')
|
153
|
+
end
|
154
|
+
def escape(str) # escape semi-colon and back-slash
|
150
155
|
str.gsub!("\\"){"\\\\"}
|
151
156
|
str.gsub!(/"/,'\"')
|
152
157
|
end
|
153
158
|
|
154
159
|
escape remote_code
|
160
|
+
escape_ruby remote_code
|
155
161
|
#cmd = "ruby -e \"#{remote_code}\""
|
156
162
|
cmd = "stdbuf -i0 -o0 -e0 ruby -e \"#{remote_code}\" #{ARGV.join(' ')}"
|
157
163
|
|
158
164
|
class Viewer
|
159
|
-
|
165
|
+
@@exist = false
|
166
|
+
def initialize(channel)
|
167
|
+
if @@exist
|
168
|
+
raise "already exist an instance"
|
169
|
+
end
|
170
|
+
@@exist = true
|
171
|
+
@wait = false # true when a frame was rendered and waiting user's action
|
172
|
+
@skip = false
|
173
|
+
|
174
|
+
Gtk.init
|
160
175
|
@window = Gtk::Window.new
|
161
176
|
@window.realize
|
162
177
|
@drawable = @window.window
|
163
178
|
@gc = Gdk::GC.new(@drawable)
|
164
179
|
@pixbuf = nil
|
165
|
-
@wait = true
|
166
180
|
@window.add_events(Gdk::Event::BUTTON_RELEASE_MASK)
|
167
181
|
@window.signal_connect("expose_event") do |w,e|
|
168
182
|
expose
|
@@ -177,46 +191,53 @@ class Viewer
|
|
177
191
|
when "Return", "space", "n"
|
178
192
|
next_fig
|
179
193
|
when "s"
|
180
|
-
|
181
|
-
|
194
|
+
unless @skip
|
195
|
+
print "skip waiting\n"
|
196
|
+
@channel.send_data("s\n")
|
197
|
+
@skip = true
|
198
|
+
end
|
182
199
|
when "q"
|
183
|
-
quit
|
200
|
+
quit!
|
184
201
|
end
|
185
202
|
true
|
186
203
|
end
|
187
204
|
@window.signal_connect("delete_event") do
|
188
|
-
quit
|
205
|
+
quit!
|
189
206
|
false
|
190
207
|
end
|
191
|
-
@
|
208
|
+
@channel = channel
|
192
209
|
end
|
193
210
|
def eof=(boolean)
|
194
|
-
@eof =
|
211
|
+
@eof = boolean
|
195
212
|
end
|
196
213
|
def eof
|
197
214
|
return @eof if @eof
|
198
|
-
@eof =
|
215
|
+
@eof = !@channel.active?
|
199
216
|
end
|
200
217
|
def next_fig
|
201
218
|
if eof
|
202
|
-
quit
|
219
|
+
quit!
|
203
220
|
elsif @wait
|
204
221
|
# print "next\n"
|
205
|
-
@
|
206
|
-
@io.flush
|
222
|
+
@channel.send_data "n\n"
|
207
223
|
@wait = false
|
208
224
|
end
|
209
225
|
end
|
210
226
|
def quit
|
227
|
+
quit! unless @wait
|
228
|
+
end
|
229
|
+
def quit!
|
211
230
|
unless @quit
|
212
231
|
# print "quit\n"
|
213
232
|
begin
|
214
|
-
|
215
|
-
|
233
|
+
unless eof
|
234
|
+
@channel.send_data "q\n"
|
235
|
+
end
|
216
236
|
rescue
|
217
237
|
end
|
218
|
-
|
238
|
+
@channel.eof! unless @channel.eof?
|
219
239
|
@quit = true
|
240
|
+
Gtk.main_quit
|
220
241
|
end
|
221
242
|
end
|
222
243
|
def expose
|
@@ -240,47 +261,92 @@ class Viewer
|
|
240
261
|
end
|
241
262
|
|
242
263
|
|
243
|
-
|
244
|
-
cmd = "cd #{opts["dir"]} ; " + cmd if opts["dir"]
|
264
|
+
|
245
265
|
if opts["display"]
|
246
266
|
cmd = "DISPLAY=#{opts["display"]} #{cmd}"
|
247
267
|
else
|
248
|
-
cmd = "xvfb-run sh -c \"#{cmd} 2> /dev/null\""
|
249
268
|
escape cmd
|
269
|
+
cmd = "xvfb-run sh -c \"#{cmd} 2> /dev/null\""
|
250
270
|
end
|
251
|
-
cmd = "
|
271
|
+
cmd = "cd #{opts["dir"]} ; " + cmd if opts["dir"]
|
252
272
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
273
|
+
|
274
|
+
begin
|
275
|
+
require "rubygems"
|
276
|
+
rescue LoadError
|
277
|
+
end
|
278
|
+
require "gtk2"
|
279
|
+
require "base64"
|
280
|
+
require "net/ssh"
|
281
|
+
include Net::SSH::Prompt
|
282
|
+
module Net::SSH::Authentication::Methods
|
283
|
+
class Password
|
284
|
+
alias :__authenticate :authenticate
|
285
|
+
def authenticate(next_service, username, password=nil)
|
286
|
+
password ||= prompt("input #{username}'s password:", false)
|
287
|
+
__authenticate(next_service, username, password)
|
288
|
+
end
|
257
289
|
end
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
290
|
+
end
|
291
|
+
|
292
|
+
if opts["user"]
|
293
|
+
user = opts["user"]
|
294
|
+
elsif /\A([^@]+)@([^@]+)\Z/ =~ host
|
295
|
+
user = $1
|
296
|
+
host = $2
|
297
|
+
else
|
298
|
+
user = ENV["USER"]
|
299
|
+
end
|
300
|
+
|
301
|
+
|
302
|
+
ssh_opts = Hash.new
|
303
|
+
ssh_opts[:password] = opts["password"] if opts["password"]
|
304
|
+
Net::SSH.start(host, user, ssh_opts) do |ssh|
|
305
|
+
ssh.open_channel do |channel|
|
306
|
+
channel.exec(cmd) do |ch, success|
|
307
|
+
unless success
|
308
|
+
Gtk.main_quit
|
309
|
+
abort "could not execute command"
|
310
|
+
end
|
311
|
+
|
312
|
+
channel[:data] = ""
|
313
|
+
channel.on_data do |ch, data|
|
314
|
+
channel[:data] << data
|
315
|
+
while channel[:data] =~ /\n\n/
|
316
|
+
str = $`
|
317
|
+
channel[:data] = $'
|
318
|
+
png = Base64.decode64(str)
|
319
|
+
@viewer.render(png)
|
320
|
+
end
|
278
321
|
end
|
322
|
+
# channel.on_process do |ch|
|
323
|
+
# end
|
324
|
+
channel.on_extended_data do |ch, type, data|
|
325
|
+
print data
|
326
|
+
end
|
327
|
+
channel.on_eof do |ch|
|
328
|
+
@viewer.eof = true
|
329
|
+
end
|
330
|
+
channel.on_close do |ch|
|
331
|
+
@viewer.eof = true
|
332
|
+
end
|
333
|
+
channel.on_request("exit-status") do |ch, data|
|
334
|
+
@viewer.quit! unless data.read_long == 0
|
335
|
+
end
|
336
|
+
|
279
337
|
end
|
280
|
-
|
281
|
-
viewer
|
338
|
+
|
339
|
+
@viewer = Viewer.new(channel)
|
340
|
+
end
|
341
|
+
|
342
|
+
begin
|
343
|
+
t = Thread.new {
|
344
|
+
Thread.pass
|
345
|
+
Gtk.main
|
346
|
+
}
|
347
|
+
ssh.loop(1)
|
282
348
|
ensure
|
283
|
-
|
349
|
+
@viewer.quit
|
284
350
|
end
|
285
351
|
t.join
|
286
352
|
end
|
data/lib/remote-dcl/version.rb
CHANGED
data/remote-dcl.gemspec
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remote-dcl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 3
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Seiya Nishizawa
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-01-
|
18
|
+
date: 2012-01-25 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: gtk2
|
@@ -31,6 +31,34 @@ dependencies:
|
|
31
31
|
version: "0"
|
32
32
|
type: :runtime
|
33
33
|
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: highline
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: net-ssh
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
34
62
|
description: |-
|
35
63
|
Remote-DCL is a Ruby script to execute a script at a remote server.
|
36
64
|
DCL calles in the script creates PNG images at the remote,
|