remote-dcl 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,
|