rbbt-util 5.26.157 → 5.26.158
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.
- checksums.yaml +4 -4
- data/lib/rbbt/util/misc/development.rb +7 -0
- data/lib/rbbt/workflow/remote_workflow/driver/rest.rb +230 -0
- data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +237 -0
- data/lib/rbbt/workflow/remote_workflow/driver.rb +75 -0
- data/lib/rbbt/workflow/remote_workflow/remote_step/rest.rb +148 -0
- data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +73 -0
- data/lib/rbbt/workflow/remote_workflow/remote_step.rb +329 -0
- data/lib/rbbt/workflow/{remote/client.rb → remote_workflow.rb} +9 -16
- data/lib/rbbt/workflow/util/archive.rb +2 -3
- data/lib/rbbt/workflow.rb +4 -4
- data/share/rbbt_commands/workflow/remote/add +28 -2
- data/share/rbbt_commands/workflow/task +4 -3
- data/test/rbbt/workflow/test_remote_workflow.rb +86 -0
- data/test/test_helper.rb +26 -23
- metadata +11 -14
- data/lib/rbbt/rest/client/adaptor.rb +0 -67
- data/lib/rbbt/rest/client/get.rb +0 -166
- data/lib/rbbt/rest/client/run.rb +0 -133
- data/lib/rbbt/rest/client/step.rb +0 -397
- data/lib/rbbt/rest/client.rb +0 -58
- data/lib/rbbt/workflow/remote/remote_step.rb +0 -324
- data/lib/rbbt/workflow/remote/rest/adaptor.rb +0 -161
- data/lib/rbbt/workflow/remote/rest/get.rb +0 -310
- data/lib/rbbt/workflow/remote/ssh/adaptor.rb +0 -61
- data/lib/rbbt/workflow/remote/ssh/driver.rb +0 -147
- data/lib/rbbt/workflow/remote/ssh/get.rb +0 -193
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d372a2cf6d424504011197b2b99f84319e79522a5817d3e54d13f61370622b5a
|
4
|
+
data.tar.gz: e8914f26719c718b2885394034a688ec4280aaf59a2dca2bad7e4dabfa744b85
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b5bbe62b81fdc7fb024b724d4c6c020839b54cb290d9ffe296f0d9841a233d951c44e0687faefc744cc04884672c10ea5d14ad0b32de9bdacfa152db54e4fbe
|
7
|
+
data.tar.gz: 99019bcc2bcedcf1205228277f41324d37731806f608f508a3f8772681c9eb0820e4f860430a1c0b4721f42f199fdf8d2876c8f5e19deac6b2792eb31e234c58
|
@@ -415,4 +415,11 @@ def self.add_libdir(dir=nil)
|
|
415
415
|
CMD.cmd("unzip '#{zip_file}' -d '#{dir}'")
|
416
416
|
end
|
417
417
|
end
|
418
|
+
|
419
|
+
|
420
|
+
def self.ssh_run(server, script)
|
421
|
+
Log.debug "Run ssh script in #{server}:\n#{script}"
|
422
|
+
CMD.cmd("ssh '#{server}' 'shopt -s expand_aliases; bash -l -c \"ruby\"' ", :in => script, :log => true).read
|
423
|
+
end
|
424
|
+
|
418
425
|
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
class RemoteWorkflow
|
3
|
+
module REST
|
4
|
+
|
5
|
+
def self.__prepare_inputs_for_restclient(inputs)
|
6
|
+
inputs.each do |k,v|
|
7
|
+
if v.respond_to? :path and not v.respond_to? :original_filename
|
8
|
+
class << v
|
9
|
+
def original_filename
|
10
|
+
File.expand_path(path)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
if Array === v and v.empty?
|
16
|
+
inputs[k] = "EMPTY_ARRAY"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.encode(url)
|
22
|
+
begin
|
23
|
+
URI.encode(url)
|
24
|
+
rescue
|
25
|
+
Log.warn $!.message
|
26
|
+
url
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.clean_url(url, params = {})
|
31
|
+
params = params.merge({ :_format => 'json', :update => 'clean' })
|
32
|
+
params = fix_params params
|
33
|
+
res = RemoteWorkflow.capture_exception do
|
34
|
+
Misc.insist(2, 0.5) do
|
35
|
+
Log.debug{ "RestClient clean: #{ url } - #{Misc.fingerprint params}" }
|
36
|
+
res = begin
|
37
|
+
RestClient.get(self.encode(url), :params => params)
|
38
|
+
rescue RestClient::NotFound
|
39
|
+
return nil
|
40
|
+
end
|
41
|
+
raise TryAgain if res.code == 202
|
42
|
+
res
|
43
|
+
end
|
44
|
+
end
|
45
|
+
res
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.get_raw(url, params = {})
|
49
|
+
params = params.merge({ :_format => 'raw' })
|
50
|
+
params = fix_params params
|
51
|
+
res = RemoteWorkflow.capture_exception do
|
52
|
+
Misc.insist(2, 0.5) do
|
53
|
+
raise "No url" if url.nil?
|
54
|
+
Log.debug{ "RestClient get_raw: #{ url } - #{Misc.fingerprint params}" }
|
55
|
+
res = RestClient.get(self.encode(url), :params => params)
|
56
|
+
raise TryAgain if res.code == 202
|
57
|
+
res.to_s
|
58
|
+
end
|
59
|
+
end
|
60
|
+
res
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.get_json(url, params = {})
|
64
|
+
Log.debug{ "RestClient get_json: #{ url } - #{Misc.fingerprint params }" }
|
65
|
+
params = params.merge({ :_format => 'json' })
|
66
|
+
params = RemoteWorkflow.fix_params params
|
67
|
+
|
68
|
+
res = RemoteWorkflow.capture_exception do
|
69
|
+
Misc.insist(2, 0.5) do
|
70
|
+
RestClient.get(self.encode(url), :params => params)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
begin
|
75
|
+
JSON.parse(res)
|
76
|
+
rescue
|
77
|
+
res
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.post_jobname(url, params = {})
|
82
|
+
Log.debug{ "RestClient post_jobname: #{ url } - #{Misc.fingerprint params}" }
|
83
|
+
params = params.merge({ :_format => 'jobname' })
|
84
|
+
params = RemoteWorkflow.fix_params params
|
85
|
+
|
86
|
+
WorkflowRESTClient.__prepare_inputs_for_restclient(params)
|
87
|
+
name = RemoteWorkflow.capture_exception do
|
88
|
+
RestClient.post(self.encode(url), params)
|
89
|
+
end
|
90
|
+
|
91
|
+
Log.debug{ "RestClient jobname returned for #{ url } - #{Misc.fingerprint params}: #{name}" }
|
92
|
+
|
93
|
+
name
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.post_json(url, params = {})
|
97
|
+
if url =~ /_cache_type=:exec/
|
98
|
+
JSON.parse(Open.open(url, :nocache => true))
|
99
|
+
else
|
100
|
+
params = params.merge({ :_format => 'json' })
|
101
|
+
params = fix_params params
|
102
|
+
|
103
|
+
res = RemoteWorkflow.capture_exception do
|
104
|
+
RestClient.post(self.encode(url), params)
|
105
|
+
end
|
106
|
+
|
107
|
+
begin
|
108
|
+
JSON.parse(res)
|
109
|
+
rescue
|
110
|
+
res
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.task_info(url, task)
|
116
|
+
@@task_info ||= {}
|
117
|
+
|
118
|
+
key = [url, task] * "#"
|
119
|
+
@@task_info[key] ||= begin
|
120
|
+
task_info = RemoteWorkflow::REST.get_json(File.join(url, task.to_s, 'info'))
|
121
|
+
task_info = RemoteWorkflow.fix_hash(task_info)
|
122
|
+
|
123
|
+
task_info[:result_type] = task_info[:result_type].to_sym
|
124
|
+
task_info[:export] = task_info[:export].to_sym
|
125
|
+
task_info[:input_types] = RemoteWorkflow.fix_hash(task_info[:input_types], true)
|
126
|
+
task_info[:inputs] = task_info[:inputs].collect{|input| input.to_sym }
|
127
|
+
|
128
|
+
task_info
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.execute_job(base_url, task, task_params, cache_type)
|
133
|
+
RemoteWorkflow.capture_exception do
|
134
|
+
task_url = URI.encode(File.join(base_url, task.to_s))
|
135
|
+
|
136
|
+
sout, sin = Misc.pipe
|
137
|
+
|
138
|
+
post_thread = Thread.new(Thread.current) do |parent|
|
139
|
+
bl = lambda do |rok|
|
140
|
+
if Net::HTTPOK === rok
|
141
|
+
_url = rok["RBBT-STREAMING-JOB-URL"]
|
142
|
+
@url = File.join(task_url, File.basename(_url)) if _url
|
143
|
+
rok.read_body do |c,_a, _b|
|
144
|
+
sin.write c
|
145
|
+
end
|
146
|
+
sin.close
|
147
|
+
else
|
148
|
+
err = StringIO.new
|
149
|
+
rok.read_body do |c,_a, _b|
|
150
|
+
err.write c
|
151
|
+
end
|
152
|
+
text = begin
|
153
|
+
reader = Zlib::GzipReader.new(err)
|
154
|
+
reader.read
|
155
|
+
rescue
|
156
|
+
err.rewind
|
157
|
+
err.read
|
158
|
+
end
|
159
|
+
ne = @adaptor.parse_exception text
|
160
|
+
case ne
|
161
|
+
when String
|
162
|
+
parent.raise e.class, ne
|
163
|
+
when Exception
|
164
|
+
parent.raise ne
|
165
|
+
else
|
166
|
+
parent.raise "Error in RestClient: " << rok.message
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
task_params.each do |k,v|
|
172
|
+
task_params[k] = v.read if IO === v
|
173
|
+
end
|
174
|
+
|
175
|
+
Log.debug{ "RestClient execute: #{ task_url } - #{Misc.fingerprint task_params}" }
|
176
|
+
RestClient::Request.execute(:method => :post, :url => task_url, :payload => task_params, :block_response => bl)
|
177
|
+
end
|
178
|
+
|
179
|
+
# It seems like now response body are now decoded by Net::HTTP after 2.1
|
180
|
+
# https://github.com/rest-client/rest-client/blob/cf3e5a115bcdb8f3344aeac0e45b44d67fac1a42/history.md
|
181
|
+
decode = Gem.loaded_specs["rest-client"].version < Gem::Version.create('2.1')
|
182
|
+
if decode
|
183
|
+
reader = Zlib::GzipReader.new(sout)
|
184
|
+
res_io = Misc.open_pipe do |sin|
|
185
|
+
while c = reader.read(Misc::BLOCK_SIZE)
|
186
|
+
sin.write c
|
187
|
+
end
|
188
|
+
sin.close
|
189
|
+
@done = true
|
190
|
+
end
|
191
|
+
ConcurrentStream.setup(res_io, :threads => [post_thread]) do
|
192
|
+
@done = true
|
193
|
+
@streaming = false
|
194
|
+
end
|
195
|
+
else
|
196
|
+
ConcurrentStream.setup(sout, :threads => [post_thread]) do
|
197
|
+
@done = true
|
198
|
+
@streaming = false
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def tasks
|
206
|
+
@tasks ||= Hash.new do |hash,task_name|
|
207
|
+
info = task_info(task_name)
|
208
|
+
task = Task.setup info do |*args|
|
209
|
+
raise "This is a remote task"
|
210
|
+
end
|
211
|
+
task.name = task_name.to_sym
|
212
|
+
hash[task_name] = task
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
def task_info(task)
|
218
|
+
RemoteWorkflow::REST.task_info(url, task)
|
219
|
+
end
|
220
|
+
|
221
|
+
def init_remote_tasks
|
222
|
+
task_exports = RemoteWorkflow::REST.get_json(url)
|
223
|
+
@asynchronous_exports = (task_exports["asynchronous"] || []).collect{|task| task.to_sym }
|
224
|
+
@synchronous_exports = (task_exports["synchronous"] || []).collect{|task| task.to_sym }
|
225
|
+
@exec_exports = (task_exports["exec"] || []).collect{|task| task.to_sym }
|
226
|
+
@stream_exports = (task_exports["stream"] || []).collect{|task| task.to_sym }
|
227
|
+
@can_stream = task_exports["can_stream"]
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,237 @@
|
|
1
|
+
class RemoteWorkflow
|
2
|
+
module SSH
|
3
|
+
#def self.run(server, script)
|
4
|
+
# Log.debug "Run ssh script in #{server}:\n#{script}"
|
5
|
+
# CMD.cmd("ssh '#{server}' 'shopt -s expand_aliases; bash -l -i -c \"ruby\"' ", :in => script, :log => true).read
|
6
|
+
#end
|
7
|
+
|
8
|
+
#def self.run_log(server, script)
|
9
|
+
# Log.debug "Run and monitor ssh script in #{server}:\n#{script}"
|
10
|
+
# CMD.cmd("ssh '#{server}' 'shopt -s expand_aliases; bash -ic \"ruby\"' ", :in => script, :log => true)
|
11
|
+
#end
|
12
|
+
|
13
|
+
def self.parse_url(url)
|
14
|
+
m = url.match(/ssh:\/\/([^:]+):(.*)/)
|
15
|
+
server = m.captures[0]
|
16
|
+
path = m.captures[1]
|
17
|
+
[server, path]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.path_script(path)
|
21
|
+
|
22
|
+
workflow, task, job, *rest = path.split("/")
|
23
|
+
|
24
|
+
script =<<-EOF
|
25
|
+
require 'rbbt/workflow'
|
26
|
+
wf = Workflow.require_workflow "#{workflow}"
|
27
|
+
EOF
|
28
|
+
|
29
|
+
case task
|
30
|
+
when nil
|
31
|
+
script +=<<-EOF
|
32
|
+
task_info = {}
|
33
|
+
wf.tasks.keys.each do |task|
|
34
|
+
task_info[task] = wf.task_info(task)
|
35
|
+
end
|
36
|
+
res = task_info
|
37
|
+
EOF
|
38
|
+
when 'documentation'
|
39
|
+
script +=<<-EOF
|
40
|
+
res = documentation = wf.documentation
|
41
|
+
EOF
|
42
|
+
else
|
43
|
+
if job.nil?
|
44
|
+
script +=<<-EOF
|
45
|
+
task = '#{task}'
|
46
|
+
res = task_info = wf.task_info(task)
|
47
|
+
EOF
|
48
|
+
else
|
49
|
+
case rest.first
|
50
|
+
when nil
|
51
|
+
script +=<<-EOF
|
52
|
+
task = '#{task}'
|
53
|
+
jobname = '#{job}'
|
54
|
+
res = job = wf.fast_load_id(File.join(task, jobname))
|
55
|
+
EOF
|
56
|
+
when "info"
|
57
|
+
script +=<<-EOF
|
58
|
+
task = '#{task}'
|
59
|
+
jobname = '#{job}'
|
60
|
+
job = wf.fast_load_id(File.join(task, jobname))
|
61
|
+
res = job_info = job.info
|
62
|
+
EOF
|
63
|
+
else
|
64
|
+
raise "Unkown path: #{[path, rest].inspect}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.job_script(inputs_id, jobname = nil)
|
71
|
+
script =<<-EOF
|
72
|
+
jobname = #{jobname.nil? ? 'nil' : "'#{jobname}'"}
|
73
|
+
path = File.join(ENV["HOME"], '.rbbt/tmp/tmp-ssh_job_inputs/#{inputs_id}')
|
74
|
+
job_inputs = Workflow.load_inputs(path, task_info[:inputs], task_info[:input_types])
|
75
|
+
job = wf.job(task, jobname, job_inputs)
|
76
|
+
EOF
|
77
|
+
script
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.get_json(url, params = {})
|
81
|
+
server, path = parse_url(url)
|
82
|
+
script = path_script(path)
|
83
|
+
|
84
|
+
script +=<<-EOF
|
85
|
+
STDOUT.write res.to_json
|
86
|
+
EOF
|
87
|
+
|
88
|
+
JSON.parse(Misc.ssh_run(server, script))
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.get_raw(url, params)
|
92
|
+
server, path = parse_url(url)
|
93
|
+
script = path_script(path)
|
94
|
+
|
95
|
+
script +=<<-EOF
|
96
|
+
STDOUT.write res
|
97
|
+
EOF
|
98
|
+
|
99
|
+
Misc.ssh_run(server, script)
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.post_job(url, inputs_id, jobname = nil)
|
103
|
+
server, path = parse_url(url)
|
104
|
+
|
105
|
+
script = path_script(path)
|
106
|
+
script += job_script(inputs_id, jobname)
|
107
|
+
script +=<<-EOF
|
108
|
+
job.init_info
|
109
|
+
STDOUT.write job.name
|
110
|
+
EOF
|
111
|
+
@name = Misc.ssh_run(server, script)
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.run_job(url, input_id, jobname = nil)
|
115
|
+
server, path = parse_url(url)
|
116
|
+
|
117
|
+
script = path_script(path)
|
118
|
+
script += job_script(input_id, jobname)
|
119
|
+
script +=<<-EOF
|
120
|
+
job.produce
|
121
|
+
STDOUT.write job.path
|
122
|
+
EOF
|
123
|
+
Misc.ssh_run(server, script)
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.run_slurm_job(url, input_id, jobname = nil)
|
127
|
+
server, path = parse_url(url)
|
128
|
+
|
129
|
+
script = path_script(path)
|
130
|
+
script += job_script(input_id, jobname)
|
131
|
+
script +=<<-EOF
|
132
|
+
job.produce
|
133
|
+
STDOUT.write job.path
|
134
|
+
EOF
|
135
|
+
Misc.ssh_run(server, script)
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.clean(url, input_id, jobname = nil)
|
139
|
+
server, path = parse_url(url)
|
140
|
+
|
141
|
+
script = path_script(path)
|
142
|
+
script +=<<-EOF
|
143
|
+
job.clean
|
144
|
+
EOF
|
145
|
+
Misc.ssh_run(server, script)
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.upload_inputs(server, inputs, input_types, input_id)
|
149
|
+
TmpFile.with_file do |dir|
|
150
|
+
if Step.save_inputs(inputs, input_types, dir)
|
151
|
+
CMD.cmd("ssh '#{server}' mkdir -p .rbbt/tmp/tmp-ssh_job_inputs/; scp -r '#{dir}' #{server}:.rbbt/tmp/tmp-ssh_job_inputs/#{input_id}")
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def self.relay(workflow, task, jobname, inputs, server, options = {})
|
157
|
+
options = Misc.add_defaults options, :search_path => 'user'
|
158
|
+
search_path = options[:search_path]
|
159
|
+
|
160
|
+
job = workflow.job(task, jobname, inputs)
|
161
|
+
|
162
|
+
job.dependencies.each do |dep|
|
163
|
+
dep.produce
|
164
|
+
end
|
165
|
+
|
166
|
+
override_dependencies = job.dependencies.collect{|dep| [dep.workflow.to_s, dep.task_name.to_s] * "#" << "=" << Rbbt.identify(dep.path)}
|
167
|
+
|
168
|
+
job.dependencies.each do |dep|
|
169
|
+
Step.migrate(dep.path, search_path, :target => server)
|
170
|
+
end
|
171
|
+
|
172
|
+
remote = RemoteWorkflow.new("ssh://#{server}:#{workflow.to_s}", "#{workflow.to_s}")
|
173
|
+
rjob = remote.job(task, jobname, {})
|
174
|
+
rjob.override_dependencies = override_dependencies
|
175
|
+
rjob.run
|
176
|
+
end
|
177
|
+
|
178
|
+
def workflow_description
|
179
|
+
RemoteWorkflow::SSH.get_raw(File.join(url, 'description'))
|
180
|
+
end
|
181
|
+
|
182
|
+
def documentation
|
183
|
+
@documention ||= IndiferentHash.setup(RemoteWorkflow::SSH.get_json(File.join(url, "documentation")))
|
184
|
+
@documention
|
185
|
+
end
|
186
|
+
|
187
|
+
def task_info(task)
|
188
|
+
@task_info ||= IndiferentHash.setup({})
|
189
|
+
|
190
|
+
if @task_info[task].nil?
|
191
|
+
task_info = RemoteWorkflow::SSH.get_json(File.join(@base_url, task.to_s))
|
192
|
+
task_info = RemoteWorkflow::SSH.fix_hash(task_info)
|
193
|
+
|
194
|
+
task_info[:result_type] = task_info[:result_type].to_sym if task_info[:result_type]
|
195
|
+
task_info[:export] = task_info[:export].to_sym if task_info[:export]
|
196
|
+
task_info[:input_types] = RemoteWorkflow::SSH.fix_hash(task_info[:input_types], true)
|
197
|
+
task_info[:inputs] = task_info[:inputs].collect{|input| input.to_sym }
|
198
|
+
|
199
|
+
@task_info[task] = IndiferentHash.setup(task_info)
|
200
|
+
end
|
201
|
+
|
202
|
+
IndiferentHash.setup(@task_info[task])
|
203
|
+
end
|
204
|
+
|
205
|
+
def tasks
|
206
|
+
@tasks ||= Hash.new do |hash,task_name|
|
207
|
+
raise Workflow::TaskNotFoundException, "Task #{task_name} not found in workflow #{self.to_s}" unless @task_info.include?(task_name)
|
208
|
+
info = @task_info[task_name]
|
209
|
+
task = Task.setup info do |*args|
|
210
|
+
raise "This is a remote task"
|
211
|
+
end
|
212
|
+
task.name = task_name.to_sym
|
213
|
+
hash[task_name] = task
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def load_tasks
|
218
|
+
@task_info.keys.each{|name| tasks[name]}
|
219
|
+
end
|
220
|
+
|
221
|
+
def task_dependencies
|
222
|
+
@task_dependencies ||= Hash.new do |hash,task|
|
223
|
+
hash[task] = if exported_tasks.include? task
|
224
|
+
RemoteWorkflow::SSH.get_json(File.join(url, task.to_s, 'dependencies'))
|
225
|
+
else
|
226
|
+
[]
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def init_remote_tasks
|
232
|
+
@task_info = IndiferentHash.setup(RemoteWorkflow::SSH.get_json(url))
|
233
|
+
@exec_exports = @stream_exports = @synchronous_exports = []
|
234
|
+
@asynchronous_exports = @task_info.keys
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'rbbt/workflow/remote_workflow/driver/rest'
|
2
|
+
require 'rbbt/workflow/remote_workflow/driver/ssh'
|
3
|
+
|
4
|
+
class RemoteWorkflow
|
5
|
+
def self.fix_hash(hash, fix_values = false)
|
6
|
+
fixed = {}
|
7
|
+
hash.each do |key, value|
|
8
|
+
fixed[key.to_sym] = case value
|
9
|
+
when TrueClass
|
10
|
+
value
|
11
|
+
when FalseClass
|
12
|
+
value
|
13
|
+
when Hash
|
14
|
+
fix_hash(value)
|
15
|
+
when (fix_values and String )
|
16
|
+
value.to_sym
|
17
|
+
when IO
|
18
|
+
value.read
|
19
|
+
when TSV::Dumper
|
20
|
+
value.stream
|
21
|
+
when Step
|
22
|
+
stream = get_stream(value)
|
23
|
+
stream || value.load
|
24
|
+
else
|
25
|
+
value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
fixed
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.parse_exception(text)
|
32
|
+
klass, message = text.split " => "
|
33
|
+
begin
|
34
|
+
klass = Kernel.const_get klass
|
35
|
+
return klass.new message
|
36
|
+
rescue
|
37
|
+
message
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.capture_exception
|
42
|
+
begin
|
43
|
+
yield
|
44
|
+
rescue Exception => e
|
45
|
+
raise e unless e.respond_to? :response
|
46
|
+
begin
|
47
|
+
ne = parse_exception e.response.to_s
|
48
|
+
case ne
|
49
|
+
when String
|
50
|
+
raise e.class, ne
|
51
|
+
when Exception
|
52
|
+
raise ne
|
53
|
+
else
|
54
|
+
raise
|
55
|
+
end
|
56
|
+
rescue
|
57
|
+
raise e
|
58
|
+
end
|
59
|
+
raise $!
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.fix_params(params)
|
64
|
+
new_params = {}
|
65
|
+
params.each do |k,v|
|
66
|
+
if Array === v and v.empty?
|
67
|
+
new_params[k] = "EMPTY_ARRAY"
|
68
|
+
else
|
69
|
+
new_params[k] = v
|
70
|
+
end
|
71
|
+
end
|
72
|
+
new_params
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|