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
@@ -1,310 +0,0 @@
|
|
1
|
-
module WorkflowRESTClient
|
2
|
-
def self.encode(url)
|
3
|
-
begin
|
4
|
-
URI.encode(url)
|
5
|
-
rescue
|
6
|
-
Log.warn $!.message
|
7
|
-
url
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.fix_hash(hash, fix_values = false)
|
12
|
-
fixed = {}
|
13
|
-
hash.each do |key, value|
|
14
|
-
fixed[key.to_sym] = case value
|
15
|
-
when TrueClass
|
16
|
-
value
|
17
|
-
when FalseClass
|
18
|
-
value
|
19
|
-
when Hash
|
20
|
-
fix_hash(value)
|
21
|
-
when (fix_values and String )
|
22
|
-
value.to_sym
|
23
|
-
when IO
|
24
|
-
value.read
|
25
|
-
when TSV::Dumper
|
26
|
-
value.stream
|
27
|
-
when Step
|
28
|
-
stream = get_stream(value)
|
29
|
-
stream || value.load
|
30
|
-
else
|
31
|
-
value
|
32
|
-
end
|
33
|
-
end
|
34
|
-
fixed
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.parse_exception(text)
|
38
|
-
klass, message = text.split " => "
|
39
|
-
begin
|
40
|
-
klass = Kernel.const_get klass
|
41
|
-
return klass.new message
|
42
|
-
rescue
|
43
|
-
message
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.capture_exception
|
48
|
-
begin
|
49
|
-
yield
|
50
|
-
rescue Exception => e
|
51
|
-
raise e unless e.respond_to? :response
|
52
|
-
begin
|
53
|
-
ne = parse_exception e.response.to_s
|
54
|
-
case ne
|
55
|
-
when String
|
56
|
-
raise e.class, ne
|
57
|
-
when Exception
|
58
|
-
raise ne
|
59
|
-
else
|
60
|
-
raise
|
61
|
-
end
|
62
|
-
rescue
|
63
|
-
raise e
|
64
|
-
end
|
65
|
-
raise $!
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.fix_params(params)
|
70
|
-
new_params = {}
|
71
|
-
params.each do |k,v|
|
72
|
-
if Array === v and v.empty?
|
73
|
-
new_params[k] = "EMPTY_ARRAY"
|
74
|
-
else
|
75
|
-
new_params[k] = v
|
76
|
-
end
|
77
|
-
end
|
78
|
-
new_params
|
79
|
-
end
|
80
|
-
|
81
|
-
def self.clean_url(url, params = {})
|
82
|
-
params = params.merge({ :_format => 'json', :update => 'clean' })
|
83
|
-
params = fix_params params
|
84
|
-
res = capture_exception do
|
85
|
-
Misc.insist(2, 0.5) do
|
86
|
-
Log.debug{ "RestClient clean: #{ url } - #{Misc.fingerprint params}" }
|
87
|
-
res = begin
|
88
|
-
RestClient.get(self.encode(url), :params => params)
|
89
|
-
rescue RestClient::NotFound
|
90
|
-
return nil
|
91
|
-
end
|
92
|
-
raise TryAgain if res.code == 202
|
93
|
-
res
|
94
|
-
end
|
95
|
-
end
|
96
|
-
res
|
97
|
-
end
|
98
|
-
|
99
|
-
def self.get_raw(url, params = {})
|
100
|
-
params = params.merge({ :_format => 'raw' })
|
101
|
-
params = fix_params params
|
102
|
-
res = capture_exception do
|
103
|
-
Misc.insist(2, 0.5) do
|
104
|
-
raise "No url" if url.nil?
|
105
|
-
Log.debug{ "RestClient get_raw: #{ url } - #{Misc.fingerprint params}" }
|
106
|
-
res = RestClient.get(self.encode(url), :params => params)
|
107
|
-
raise TryAgain if res.code == 202
|
108
|
-
res.to_s
|
109
|
-
end
|
110
|
-
end
|
111
|
-
res
|
112
|
-
end
|
113
|
-
|
114
|
-
def self.get_json(url, params = {})
|
115
|
-
Log.debug{ "RestClient get_json: #{ url } - #{Misc.fingerprint params }" }
|
116
|
-
params = params.merge({ :_format => 'json' })
|
117
|
-
params = fix_params params
|
118
|
-
|
119
|
-
res = capture_exception do
|
120
|
-
Misc.insist(2, 0.5) do
|
121
|
-
RestClient.get(self.encode(url), :params => params)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
begin
|
126
|
-
JSON.parse(res)
|
127
|
-
rescue
|
128
|
-
res
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def self.post_jobname(url, params = {})
|
133
|
-
Log.debug{ "RestClient post_jobname: #{ url } - #{Misc.fingerprint params}" }
|
134
|
-
params = params.merge({ :_format => 'jobname' })
|
135
|
-
params = fix_params params
|
136
|
-
|
137
|
-
WorkflowRESTClient.__prepare_inputs_for_restclient(params)
|
138
|
-
name = capture_exception do
|
139
|
-
RestClient.post(self.encode(url), params)
|
140
|
-
end
|
141
|
-
|
142
|
-
Log.debug{ "RestClient jobname returned for #{ url } - #{Misc.fingerprint params}: #{name}" }
|
143
|
-
|
144
|
-
name
|
145
|
-
end
|
146
|
-
|
147
|
-
def self.post_json(url, params = {})
|
148
|
-
if url =~ /_cache_type=:exec/
|
149
|
-
JSON.parse(Open.open(url, :nocache => true))
|
150
|
-
else
|
151
|
-
params = params.merge({ :_format => 'json' })
|
152
|
-
params = fix_params params
|
153
|
-
|
154
|
-
res = capture_exception do
|
155
|
-
RestClient.post(self.encode(url), params)
|
156
|
-
end
|
157
|
-
|
158
|
-
begin
|
159
|
-
JSON.parse(res)
|
160
|
-
rescue
|
161
|
-
res
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
def get
|
167
|
-
params ||= {}
|
168
|
-
params = params.merge(:_format => [:string, :boolean, :tsv, :annotations, :array].include?(result_type.to_sym) ? :raw : :json )
|
169
|
-
@cache_result ||= Persist.persist("REST persist", :binary, :file => cache_file + "." + Misc.obj2digest(params)) do
|
170
|
-
Misc.insist 3, rand(2) + 1 do
|
171
|
-
begin
|
172
|
-
init_job if url.nil?
|
173
|
-
@adaptor.get_raw(url, params)
|
174
|
-
rescue
|
175
|
-
Log.exception $!
|
176
|
-
raise $!
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
def load
|
183
|
-
params = {}
|
184
|
-
join unless done? or streaming?
|
185
|
-
raise get_exception if error? or aborted?
|
186
|
-
load_res get
|
187
|
-
end
|
188
|
-
|
189
|
-
def exec_job
|
190
|
-
res = _run_job(:exec)
|
191
|
-
load_res res, result_type == :array ? :json : result_type
|
192
|
-
end
|
193
|
-
|
194
|
-
def abort
|
195
|
-
return self if status == :done
|
196
|
-
@adaptor.get_json(@url + '?_update=abort') if @url and @name
|
197
|
-
self
|
198
|
-
end
|
199
|
-
|
200
|
-
def init_job(cache_type = nil, other_params = {})
|
201
|
-
cache_type = :asynchronous if cache_type.nil? and not @is_exec
|
202
|
-
cache_type = :exec if cache_type.nil?
|
203
|
-
@last_info_time = nil
|
204
|
-
@done = false
|
205
|
-
get_streams
|
206
|
-
@name ||= Persist.memory("RemoteSteps", :workflow => self, :task => task, :jobname => @name, :inputs => inputs, :cache_type => cache_type) do
|
207
|
-
Misc.insist do
|
208
|
-
@adaptor.post_jobname(File.join(base_url, task.to_s), inputs.merge(other_params).merge(:jobname => @name||@base_name, :_cache_type => cache_type))
|
209
|
-
end
|
210
|
-
end
|
211
|
-
if Open.remote? @name
|
212
|
-
@url = @name
|
213
|
-
@name = File.basename(@name)
|
214
|
-
else
|
215
|
-
@url = File.join(base_url, task.to_s, @name)
|
216
|
-
end
|
217
|
-
self
|
218
|
-
end
|
219
|
-
|
220
|
-
def recursive_clean
|
221
|
-
Log.warn "Not doing recursive cleans"
|
222
|
-
return
|
223
|
-
begin
|
224
|
-
_restart
|
225
|
-
params = {:_update => :recursive_clean}
|
226
|
-
@adaptor.get_raw(url, params)
|
227
|
-
rescue Exception
|
228
|
-
Log.exception $!
|
229
|
-
end
|
230
|
-
self
|
231
|
-
end
|
232
|
-
|
233
|
-
def _clean
|
234
|
-
begin
|
235
|
-
_restart
|
236
|
-
cache_files.each do |cache_file|
|
237
|
-
Open.rm cache_file
|
238
|
-
end
|
239
|
-
params = {:_update => :clean}
|
240
|
-
@adaptor.clean_url(url, params) if @url
|
241
|
-
rescue Exception
|
242
|
-
Log.exception $!
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
def clean
|
247
|
-
init_job
|
248
|
-
_clean
|
249
|
-
self
|
250
|
-
end
|
251
|
-
|
252
|
-
def stream_job(task_url, task_params, stream_input, cache_type = :exec)
|
253
|
-
require 'rbbt/util/misc/multipart_payload'
|
254
|
-
WorkflowRESTClient.capture_exception do
|
255
|
-
@streaming = true
|
256
|
-
|
257
|
-
Log.debug{ "RestClient stream #{Process.pid}: #{ task_url } #{stream_input} #{cache_type} - #{Misc.fingerprint task_params}" }
|
258
|
-
res = RbbtMutiplartPayload.issue task_url, task_params, stream_input, nil, nil, true
|
259
|
-
type = res.gets
|
260
|
-
|
261
|
-
out = case type.strip
|
262
|
-
when "LOCATION"
|
263
|
-
@url = res.gets
|
264
|
-
@url.sub!(/\?.*/,'')
|
265
|
-
join
|
266
|
-
WorkflowRESTClient.get_raw(@url)
|
267
|
-
@done = true
|
268
|
-
@streaming = false
|
269
|
-
when /STREAM: (.*)/
|
270
|
-
@url = $1.strip
|
271
|
-
res.callback = Proc.new do
|
272
|
-
Log.medium "Done streaming result from #{@url}"
|
273
|
-
@done = true
|
274
|
-
@streaming = false
|
275
|
-
end
|
276
|
-
res
|
277
|
-
when "BULK"
|
278
|
-
begin
|
279
|
-
res.read
|
280
|
-
ensure
|
281
|
-
@done = true
|
282
|
-
@streaming = false
|
283
|
-
end
|
284
|
-
else
|
285
|
-
raise "What? " + type
|
286
|
-
end
|
287
|
-
|
288
|
-
ConcurrentStream.setup(out, :filename => @url)
|
289
|
-
|
290
|
-
out
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
|
-
def _run_job(cache_type = :async)
|
295
|
-
get_streams
|
296
|
-
|
297
|
-
task_url = URI.encode(File.join(base_url, task.to_s))
|
298
|
-
@adaptor.__prepare_inputs_for_restclient(inputs)
|
299
|
-
task_params = inputs.merge(:_cache_type => cache_type, :jobname => base_name, :_format => [:string, :boolean, :tsv, :annotations].include?(result_type) ? :raw : :json)
|
300
|
-
|
301
|
-
if cache_type == :stream or cache_type == :exec and stream_input and inputs[stream_input]
|
302
|
-
io = self.stream_job(task_url, task_params, stream_input, cache_type)
|
303
|
-
return io
|
304
|
-
else
|
305
|
-
@adaptor.execute_job(base_url, task, task_params, cache_type)
|
306
|
-
end
|
307
|
-
|
308
|
-
end
|
309
|
-
|
310
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'rbbt/workflow/remote/ssh/driver'
|
2
|
-
|
3
|
-
module WorkflowSSHClient
|
4
|
-
def workflow_description
|
5
|
-
WorkflowSSHClient.get_raw(File.join(url, 'description'))
|
6
|
-
end
|
7
|
-
|
8
|
-
def documentation
|
9
|
-
@documention ||= IndiferentHash.setup(WorkflowSSHClient.get_json(File.join(url, "documentation")))
|
10
|
-
@documention
|
11
|
-
end
|
12
|
-
|
13
|
-
def task_info(task)
|
14
|
-
@task_info ||= IndiferentHash.setup({})
|
15
|
-
|
16
|
-
if @task_info[task].nil?
|
17
|
-
task_info = WorkflowSSHClient.get_json(File.join(@base_url, task.to_s))
|
18
|
-
task_info = WorkflowSSHClient.fix_hash(task_info)
|
19
|
-
|
20
|
-
task_info[:result_type] = task_info[:result_type].to_sym if task_info[:result_type]
|
21
|
-
task_info[:export] = task_info[:export].to_sym if task_info[:export]
|
22
|
-
task_info[:input_types] = WorkflowSSHClient.fix_hash(task_info[:input_types], true)
|
23
|
-
task_info[:inputs] = task_info[:inputs].collect{|input| input.to_sym }
|
24
|
-
|
25
|
-
@task_info[task] = IndiferentHash.setup(task_info)
|
26
|
-
end
|
27
|
-
|
28
|
-
IndiferentHash.setup(@task_info[task])
|
29
|
-
end
|
30
|
-
|
31
|
-
def tasks
|
32
|
-
@tasks ||= Hash.new do |hash,task_name|
|
33
|
-
info = @task_info[task_name]
|
34
|
-
task = Task.setup info do |*args|
|
35
|
-
raise "This is a remote task"
|
36
|
-
end
|
37
|
-
task.name = task_name.to_sym
|
38
|
-
hash[task_name] = task
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def load_tasks
|
43
|
-
@task_info.keys.each{|name| tasks[name]}
|
44
|
-
end
|
45
|
-
|
46
|
-
def task_dependencies
|
47
|
-
@task_dependencies ||= Hash.new do |hash,task|
|
48
|
-
hash[task] = if exported_tasks.include? task
|
49
|
-
WorkflowSSHClient.get_json(File.join(url, task.to_s, 'dependencies'))
|
50
|
-
else
|
51
|
-
[]
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def init_remote_tasks
|
57
|
-
@task_info = IndiferentHash.setup(WorkflowSSHClient.get_json(url))
|
58
|
-
@exec_exports = @stream_exports = @synchronous_exports = []
|
59
|
-
@asynchronous_exports = @task_info.keys
|
60
|
-
end
|
61
|
-
end
|
@@ -1,147 +0,0 @@
|
|
1
|
-
module SSHDriver
|
2
|
-
def self.run(server, script)
|
3
|
-
Log.debug "Run ssh script in #{server}:\n#{script}"
|
4
|
-
CMD.cmd("ssh '#{server}' 'shopt -s expand_aliases; bash -l -i -c \"ruby\"' ", :in => script, :log => true).read
|
5
|
-
end
|
6
|
-
|
7
|
-
#def self.run_log(server, script)
|
8
|
-
# Log.debug "Run and monitor ssh script in #{server}:\n#{script}"
|
9
|
-
# CMD.cmd("ssh '#{server}' 'shopt -s expand_aliases; bash -ic \"ruby\"' ", :in => script, :log => true)
|
10
|
-
#end
|
11
|
-
|
12
|
-
def self.parse_url(url)
|
13
|
-
m = url.match(/ssh:\/\/([^:]+):(.*)/)
|
14
|
-
server = m.captures[0]
|
15
|
-
path = m.captures[1]
|
16
|
-
[server, path]
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.path_script(path)
|
20
|
-
|
21
|
-
workflow, task, job, *rest = path.split("/")
|
22
|
-
|
23
|
-
script =<<-EOF
|
24
|
-
require 'rbbt/workflow'
|
25
|
-
wf = Workflow.require_workflow "#{workflow}"
|
26
|
-
EOF
|
27
|
-
|
28
|
-
case task
|
29
|
-
when nil
|
30
|
-
script +=<<-EOF
|
31
|
-
task_info = {}
|
32
|
-
wf.tasks.keys.each do |task|
|
33
|
-
task_info[task] = wf.task_info(task)
|
34
|
-
end
|
35
|
-
res = task_info
|
36
|
-
EOF
|
37
|
-
when 'documentation'
|
38
|
-
script +=<<-EOF
|
39
|
-
res = documentation = wf.documentation
|
40
|
-
EOF
|
41
|
-
else
|
42
|
-
if job.nil?
|
43
|
-
script +=<<-EOF
|
44
|
-
task = '#{task}'
|
45
|
-
res = task_info = wf.task_info(task)
|
46
|
-
EOF
|
47
|
-
else
|
48
|
-
case rest.first
|
49
|
-
when nil
|
50
|
-
script +=<<-EOF
|
51
|
-
task = '#{task}'
|
52
|
-
jobname = '#{job}'
|
53
|
-
res = job = wf.fast_load_id(File.join(task, jobname))
|
54
|
-
EOF
|
55
|
-
when "info"
|
56
|
-
script +=<<-EOF
|
57
|
-
task = '#{task}'
|
58
|
-
jobname = '#{job}'
|
59
|
-
job = wf.fast_load_id(File.join(task, jobname))
|
60
|
-
res = job_info = job.info
|
61
|
-
EOF
|
62
|
-
else
|
63
|
-
raise "Unkown path: #{[path, rest].inspect}"
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.job_script(inputs_id, jobname = nil)
|
70
|
-
script =<<-EOF
|
71
|
-
jobname = #{jobname.nil? ? 'nil' : "'#{jobname}'"}
|
72
|
-
path = File.join(ENV["HOME"], '.rbbt/tmp/tmp-ssh_job_inputs/#{inputs_id}')
|
73
|
-
job_inputs = Workflow.load_inputs(path, task_info[:inputs], task_info[:input_types])
|
74
|
-
job = wf.job(task, jobname, job_inputs)
|
75
|
-
EOF
|
76
|
-
script
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.get_json(url, params)
|
80
|
-
server, path = parse_url(url)
|
81
|
-
script = path_script(path)
|
82
|
-
|
83
|
-
script +=<<-EOF
|
84
|
-
STDOUT.write res.to_json
|
85
|
-
EOF
|
86
|
-
|
87
|
-
JSON.parse(self.run(server, script))
|
88
|
-
end
|
89
|
-
|
90
|
-
def self.get_raw(url, params)
|
91
|
-
server, path = parse_url(url)
|
92
|
-
script = path_script(path)
|
93
|
-
|
94
|
-
script +=<<-EOF
|
95
|
-
STDOUT.write res
|
96
|
-
EOF
|
97
|
-
|
98
|
-
self.run(server, script)
|
99
|
-
end
|
100
|
-
|
101
|
-
def self.post_job(url, inputs_id, jobname = nil)
|
102
|
-
server, path = parse_url(url)
|
103
|
-
|
104
|
-
script = path_script(path)
|
105
|
-
script += job_script(inputs_id, jobname)
|
106
|
-
script +=<<-EOF
|
107
|
-
job.init_info
|
108
|
-
STDOUT.write job.name
|
109
|
-
EOF
|
110
|
-
@name = self.run(server, script)
|
111
|
-
end
|
112
|
-
|
113
|
-
def self.run_job(url, input_id, jobname = nil)
|
114
|
-
server, path = parse_url(url)
|
115
|
-
|
116
|
-
script = path_script(path)
|
117
|
-
script += job_script(input_id, jobname)
|
118
|
-
script +=<<-EOF
|
119
|
-
job.produce
|
120
|
-
STDOUT.write job.path
|
121
|
-
EOF
|
122
|
-
self.run(server, script)
|
123
|
-
end
|
124
|
-
|
125
|
-
def self.run_slurm_job(url, input_id, jobname = nil)
|
126
|
-
server, path = parse_url(url)
|
127
|
-
|
128
|
-
script = path_script(path)
|
129
|
-
script += job_script(input_id, jobname)
|
130
|
-
script +=<<-EOF
|
131
|
-
job.produce
|
132
|
-
STDOUT.write job.path
|
133
|
-
EOF
|
134
|
-
self.run(server, script)
|
135
|
-
end
|
136
|
-
|
137
|
-
def self.clean(url, input_id, jobname = nil)
|
138
|
-
server, path = parse_url(url)
|
139
|
-
|
140
|
-
script = path_script(path)
|
141
|
-
script +=<<-EOF
|
142
|
-
job.clean
|
143
|
-
EOF
|
144
|
-
self.run(server, script)
|
145
|
-
end
|
146
|
-
|
147
|
-
end
|
@@ -1,193 +0,0 @@
|
|
1
|
-
module WorkflowSSHClient
|
2
|
-
attr_accessor :override_dependencies
|
3
|
-
|
4
|
-
def self.fix_hash(hash, fix_values = false)
|
5
|
-
fixed = {}
|
6
|
-
hash.each do |key, value|
|
7
|
-
fixed[key.to_sym] = case value
|
8
|
-
when TrueClass
|
9
|
-
value
|
10
|
-
when FalseClass
|
11
|
-
value
|
12
|
-
when Hash
|
13
|
-
fix_hash(value)
|
14
|
-
when (fix_values and String )
|
15
|
-
value.to_sym
|
16
|
-
when IO
|
17
|
-
value.read
|
18
|
-
when TSV::Dumper
|
19
|
-
value.stream
|
20
|
-
when Step
|
21
|
-
stream = get_stream(value)
|
22
|
-
stream || value.load
|
23
|
-
else
|
24
|
-
value
|
25
|
-
end
|
26
|
-
end
|
27
|
-
fixed
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.parse_exception(text)
|
31
|
-
klass, message = text.split " => "
|
32
|
-
begin
|
33
|
-
klass = Kernel.const_get klass
|
34
|
-
return klass.new message
|
35
|
-
rescue
|
36
|
-
message
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.capture_exception
|
41
|
-
begin
|
42
|
-
yield
|
43
|
-
rescue Exception => e
|
44
|
-
raise e unless e.respond_to? :response
|
45
|
-
begin
|
46
|
-
ne = parse_exception e.response.to_s
|
47
|
-
case ne
|
48
|
-
when String
|
49
|
-
raise e.class, ne
|
50
|
-
when Exception
|
51
|
-
raise ne
|
52
|
-
else
|
53
|
-
raise
|
54
|
-
end
|
55
|
-
rescue
|
56
|
-
raise e
|
57
|
-
end
|
58
|
-
raise $!
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.fix_params(params)
|
63
|
-
new_params = {}
|
64
|
-
params.each do |k,v|
|
65
|
-
if Array === v and v.empty?
|
66
|
-
new_params[k] = "EMPTY_ARRAY"
|
67
|
-
else
|
68
|
-
new_params[k] = v
|
69
|
-
end
|
70
|
-
end
|
71
|
-
new_params
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.get_json(url, params = {})
|
75
|
-
Log.debug{ "SSHClient get_json: #{ url } - #{Misc.fingerprint params }" }
|
76
|
-
params = params.merge({ :_format => 'json' })
|
77
|
-
params = fix_params params
|
78
|
-
|
79
|
-
res = capture_exception do
|
80
|
-
Misc.insist(2, 0.5) do
|
81
|
-
SSHDriver.get_json(url, :params => params)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
begin
|
86
|
-
JSON.parse(res)
|
87
|
-
rescue
|
88
|
-
res
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.upload_inputs(server, inputs, input_types, input_id)
|
93
|
-
TmpFile.with_file do |dir|
|
94
|
-
if Step.save_inputs(inputs, input_types, dir)
|
95
|
-
CMD.cmd("ssh '#{server}' mkdir -p .rbbt/tmp/tmp-ssh_job_inputs/; scp -r '#{dir}' #{server}:.rbbt/tmp/tmp-ssh_job_inputs/#{input_id}")
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
#{{{ RUN
|
101
|
-
|
102
|
-
|
103
|
-
def init_job(cache_type = nil, other_params = {})
|
104
|
-
cache_type = :asynchronous if cache_type.nil? and not @is_exec
|
105
|
-
cache_type = :exec if cache_type.nil?
|
106
|
-
@last_info_time = nil
|
107
|
-
@done = false
|
108
|
-
@server, @server_path = SSHDriver.parse_url base_url
|
109
|
-
@input_id ||= "inputs-" << rand(100000).to_s
|
110
|
-
@input_types = task_info(task)[:input_types]
|
111
|
-
|
112
|
-
if override_dependencies
|
113
|
-
|
114
|
-
if override_dependencies && override_dependencies.any?
|
115
|
-
override_dependencies.each do |od|
|
116
|
-
name, _sep, value = od.partition("=")
|
117
|
-
inputs[name] = value
|
118
|
-
end
|
119
|
-
end
|
120
|
-
iii inputs
|
121
|
-
|
122
|
-
WorkflowSSHClient.upload_inputs(@server, inputs, @input_types, @input_id)
|
123
|
-
else
|
124
|
-
WorkflowSSHClient.upload_inputs(@server, inputs, @input_types, @input_id)
|
125
|
-
end
|
126
|
-
|
127
|
-
@name ||= Persist.memory("RemoteSteps", :workflow => self, :task => task, :jobname => @name, :inputs => inputs, :cache_type => cache_type) do
|
128
|
-
Misc.insist do
|
129
|
-
input_types = {}
|
130
|
-
SSHDriver.post_job(File.join(base_url, task.to_s), @input_id, @base_name)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
if Open.remote? @name
|
134
|
-
@url = @name
|
135
|
-
@name = File.basename(@name)
|
136
|
-
else
|
137
|
-
@url = File.join(base_url, task.to_s, @name)
|
138
|
-
end
|
139
|
-
self
|
140
|
-
end
|
141
|
-
|
142
|
-
def path
|
143
|
-
@server, @server_path = SSHDriver.parse_url @base_url
|
144
|
-
"ssh://" + @server + ":" + @remote_path
|
145
|
-
end
|
146
|
-
|
147
|
-
def produce(*args)
|
148
|
-
input_types = {}
|
149
|
-
init_job
|
150
|
-
@remote_path = SSHDriver.run_job(File.join(base_url, task.to_s), @input_id, @base_name)
|
151
|
-
while ! done?
|
152
|
-
sleep 1
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
def load
|
157
|
-
load_res Open.open(path)
|
158
|
-
end
|
159
|
-
|
160
|
-
def run(*args)
|
161
|
-
produce(*args)
|
162
|
-
self.load unless args.first
|
163
|
-
end
|
164
|
-
|
165
|
-
def clean
|
166
|
-
init_job
|
167
|
-
SSHDriver.clean(@url, @input_id, @base_name) if done?
|
168
|
-
_restart
|
169
|
-
end
|
170
|
-
|
171
|
-
def self.relay(workflow, task, jobname, inputs, server, options = {})
|
172
|
-
options = Misc.add_defaults options, :search_path => 'user'
|
173
|
-
search_path = options[:search_path]
|
174
|
-
|
175
|
-
job = workflow.job(task, jobname, inputs)
|
176
|
-
|
177
|
-
job.dependencies.each do |dep|
|
178
|
-
dep.produce
|
179
|
-
end
|
180
|
-
|
181
|
-
override_dependencies = job.dependencies.collect{|dep| [dep.workflow.to_s, dep.task_name.to_s] * "#" << "=" << Rbbt.identify(dep.path)}
|
182
|
-
|
183
|
-
job.dependencies.each do |dep|
|
184
|
-
Step.migrate(dep.path, search_path, :target => server)
|
185
|
-
end
|
186
|
-
|
187
|
-
remote = WorkflowRemoteClient.new("ssh://#{server}:#{workflow.to_s}", "#{workflow.to_s}")
|
188
|
-
rjob = remote.job(task, jobname, {})
|
189
|
-
rjob.override_dependencies = override_dependencies
|
190
|
-
rjob.run
|
191
|
-
end
|
192
|
-
|
193
|
-
end
|