rbbt-util 5.38.0 → 5.39.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rbbt/annotations.rb +2 -0
- data/lib/rbbt/persist.rb +2 -2
- data/lib/rbbt/resource.rb +12 -3
- data/lib/rbbt/tsv/excel.rb +5 -1
- data/lib/rbbt/tsv/parser.rb +2 -2
- data/lib/rbbt/tsv/util.rb +4 -0
- data/lib/rbbt/util/cmd.rb +8 -4
- data/lib/rbbt/util/concurrency/processes.rb +1 -1
- data/lib/rbbt/util/migrate.rb +1 -2
- data/lib/rbbt/util/misc/development.rb +0 -2
- data/lib/rbbt/util/misc/format.rb +3 -0
- data/lib/rbbt/util/misc/indiferent_hash.rb +9 -6
- data/lib/rbbt/util/misc/inspect.rb +23 -8
- data/lib/rbbt/util/misc/options.rb +1 -1
- data/lib/rbbt/util/misc/pipes.rb +3 -3
- data/lib/rbbt/util/open.rb +6 -1
- data/lib/rbbt/util/ssh.rb +46 -4
- data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +7 -7
- data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +4 -3
- data/lib/rbbt/workflow/remote_workflow/remote_step.rb +1 -0
- data/lib/rbbt/workflow/step/dependencies.rb +9 -9
- data/lib/rbbt/workflow/step/info.rb +1 -1
- data/lib/rbbt/workflow/step/save_load_inputs.rb +4 -5
- data/lib/rbbt/workflow/step.rb +9 -4
- data/lib/rbbt/workflow/usage.rb +1 -1
- data/lib/rbbt/workflow/util/trace.rb +2 -1
- data/lib/rbbt/workflow.rb +4 -3
- data/share/rbbt_commands/resource/claims +57 -0
- data/share/rbbt_commands/resource/find +1 -1
- data/share/rbbt_commands/resource/glob +1 -1
- data/share/rbbt_commands/workflow/task +58 -11
- data/test/rbbt/test_resource.rb +7 -2
- data/test/rbbt/test_tsv.rb +16 -1
- data/test/rbbt/tsv/parallel/test_traverse.rb +2 -2
- data/test/rbbt/tsv/test_accessor.rb +21 -4
- data/test/rbbt/tsv/test_parser.rb +28 -0
- data/test/rbbt/tsv/test_util.rb +14 -0
- data/test/rbbt/util/misc/test_indiferent_hash.rb +14 -0
- data/test/rbbt/util/test_cmd.rb +7 -1
- data/test/rbbt/util/test_migrate.rb +2 -2
- data/test/rbbt/util/test_open.rb +3 -3
- data/test/rbbt/util/test_ssh.rb +10 -0
- metadata +99 -94
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12c5401cf3ecb8495ba5c21d0f3d3f35c741c1c335ffa0d3a7d3ee498f6daae8
|
4
|
+
data.tar.gz: 344f30b6651a272f5e9665d3ec6383b4a1d62ba7c64c7889af5cfc573b2285ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e8305e1f3e74eeff9e5892592bc66bfc9aac3baa505503942b266c3de996408a9210fcfaa2f6073800fc763bf3cdf5b8f39a50a920696402657d2928a9add8f
|
7
|
+
data.tar.gz: 511c72833b4a8ef747e574376d44a3b4799f96f6a922301d3f405df1cd7aac79a2d2de388075aaab4fc3ef6962ee66ded3de8684227912399f41f7ad00006148
|
data/lib/rbbt/annotations.rb
CHANGED
data/lib/rbbt/persist.rb
CHANGED
@@ -115,7 +115,7 @@ module Persist
|
|
115
115
|
begin
|
116
116
|
case (type || :marshal).to_sym
|
117
117
|
when :path
|
118
|
-
path
|
118
|
+
Path.setup(Open.read(path).strip)
|
119
119
|
when :nil
|
120
120
|
nil
|
121
121
|
when :boolean
|
@@ -172,7 +172,7 @@ module Persist
|
|
172
172
|
|
173
173
|
case (type || :marshal).to_sym
|
174
174
|
when :path
|
175
|
-
|
175
|
+
Open.write(path, content)
|
176
176
|
when :nil
|
177
177
|
nil
|
178
178
|
when :boolean
|
data/lib/rbbt/resource.rb
CHANGED
@@ -350,13 +350,15 @@ url='#{url}'
|
|
350
350
|
end
|
351
351
|
|
352
352
|
def identify(path)
|
353
|
+
return path unless path.start_with?("/")
|
353
354
|
path = File.expand_path(path)
|
354
355
|
path += "/" if File.directory?(path)
|
355
356
|
resource ||= Rbbt
|
356
|
-
locations = (Path::STANDARD_SEARCH + resource.search_order + resource.search_paths.keys)
|
357
|
+
locations = (Path::STANDARD_SEARCH + resource.search_order + resource.search_paths.keys).uniq
|
357
358
|
locations -= [:current, "current"]
|
358
359
|
locations << :current
|
359
360
|
search_paths = IndiferentHash.setup(resource.search_paths)
|
361
|
+
choices = []
|
360
362
|
locations.uniq.each do |name|
|
361
363
|
pattern = search_paths[name]
|
362
364
|
pattern = resource.search_paths[pattern] while Symbol === pattern
|
@@ -370,12 +372,19 @@ url='#{url}'
|
|
370
372
|
"(?:/(?<REST>.*))?/?$"
|
371
373
|
if m = path.match(regexp)
|
372
374
|
if ! m.named_captures.include?("PKGDIR") || m["PKGDIR"] == resource.pkgdir
|
373
|
-
|
375
|
+
unlocated = ([m["TOPLEVEL"],m["SUBPATH"],m["REST"]] * "/")
|
376
|
+
unlocated.gsub!(/\/+/,'/')
|
377
|
+
if self.subdir && ! self.subdir.empty?
|
378
|
+
subdir = self.subdir
|
379
|
+
subdir += "/" unless subdir.end_with?("/")
|
380
|
+
unlocated[subdir] = ""
|
381
|
+
end
|
382
|
+
choices << self.annotate(unlocated)
|
374
383
|
end
|
375
384
|
end
|
376
385
|
end
|
377
386
|
end
|
378
|
-
|
387
|
+
choices.sort_by{|s| s.length }.first
|
379
388
|
end
|
380
389
|
end
|
381
390
|
|
data/lib/rbbt/tsv/excel.rb
CHANGED
@@ -154,7 +154,11 @@ module TSV
|
|
154
154
|
sheet1 = book.create_worksheet
|
155
155
|
sheet1.name = sheet if sheet
|
156
156
|
|
157
|
-
|
157
|
+
if fields
|
158
|
+
sheet1.row(0).concat fields if fields
|
159
|
+
else
|
160
|
+
sheet1.row(0).concat ["No field info"]
|
161
|
+
end
|
158
162
|
|
159
163
|
rows.each_with_index do |cells,i|
|
160
164
|
sheet1.row(i+1).concat cells
|
data/lib/rbbt/tsv/parser.rb
CHANGED
@@ -130,12 +130,12 @@ module TSV
|
|
130
130
|
keys = parts[key_position].split(@sep2, -1)
|
131
131
|
values = case
|
132
132
|
when field_positions.nil?
|
133
|
-
|
133
|
+
parts.tap{|o| o.delete_at key_position}
|
134
134
|
when field_positions.empty?
|
135
135
|
[]
|
136
136
|
else
|
137
137
|
parts.values_at *field_positions
|
138
|
-
end.collect{|value| (value.nil? || value.empty?) ? [] : value.split(@sep2, -1) }
|
138
|
+
end.collect{|value| (value.nil? || value.empty?) ? [""] : value.split(@sep2, -1) }
|
139
139
|
[keys, values]
|
140
140
|
end
|
141
141
|
|
data/lib/rbbt/tsv/util.rb
CHANGED
data/lib/rbbt/util/cmd.rb
CHANGED
@@ -22,13 +22,17 @@ module CMD
|
|
22
22
|
return tool.to_s unless TOOLS[tool]
|
23
23
|
|
24
24
|
@@init_cmd_tool ||= IndiferentHash.setup({})
|
25
|
+
|
26
|
+
claim, test, block, cmd = TOOLS[tool]
|
27
|
+
cmd = tool.to_s if cmd.nil?
|
28
|
+
|
25
29
|
if !@@init_cmd_tool[tool]
|
26
|
-
|
30
|
+
|
27
31
|
begin
|
28
32
|
if test
|
29
33
|
CMD.cmd(test + " ")
|
30
34
|
else
|
31
|
-
CMD.cmd("#{
|
35
|
+
CMD.cmd("#{cmd} --help")
|
32
36
|
end
|
33
37
|
rescue
|
34
38
|
if claim
|
@@ -41,7 +45,7 @@ module CMD
|
|
41
45
|
version = nil
|
42
46
|
["--version", "-version", "--help", ""].each do |f|
|
43
47
|
begin
|
44
|
-
version_txt += CMD.cmd("#{
|
48
|
+
version_txt += CMD.cmd("#{cmd} #{f} 2>&1", :nofail => true).read
|
45
49
|
version = Misc.scan_version_text(version_txt, tool)
|
46
50
|
break if version
|
47
51
|
rescue
|
@@ -54,7 +58,7 @@ module CMD
|
|
54
58
|
return cmd if cmd
|
55
59
|
end
|
56
60
|
|
57
|
-
|
61
|
+
cmd
|
58
62
|
end
|
59
63
|
|
60
64
|
def self.versions
|
data/lib/rbbt/util/migrate.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Rbbt
|
2
2
|
|
3
|
-
prepare_for_execution(job)
|
4
3
|
def self.migrate_source_paths(path, resource = Rbbt, source = nil)
|
5
4
|
if source
|
6
5
|
lpath, *paths = Misc.ssh_run(source, <<-EOF).split("\n")
|
@@ -60,7 +59,7 @@ puts resource[path].find(search_path)
|
|
60
59
|
test_str = options[:test] ? '-nv' : ''
|
61
60
|
|
62
61
|
real_paths.each do |source_path|
|
63
|
-
Log.
|
62
|
+
Log.low "Migrating #{source_path} #{options[:files].length} files to #{target} - #{Misc.fingerprint(options[:files])}}" if options[:files]
|
64
63
|
if File.directory?(source_path) || source_path.end_with?("/")
|
65
64
|
source_path += "/" unless source_path.end_with? '/'
|
66
65
|
target += "/" unless target.end_with? '/'
|
@@ -27,6 +27,9 @@ module Misc
|
|
27
27
|
|
28
28
|
def self.format_paragraph(text, size = 80, indent = 0, offset = 0)
|
29
29
|
i = 0
|
30
|
+
offset = 0 if offset.nil?
|
31
|
+
indent = 0 if indent.nil?
|
32
|
+
size = 80 if size.nil?
|
30
33
|
size = size + offset + indent
|
31
34
|
re = /((?:\n\s*\n\s*)|(?:\n\s*(?=\*)))/
|
32
35
|
text.split(re).collect do |paragraph|
|
@@ -22,18 +22,21 @@ module IndiferentHash
|
|
22
22
|
@_default ||= self.default or self.default_proc
|
23
23
|
end
|
24
24
|
|
25
|
-
def [](key)
|
26
|
-
res = super(key)
|
25
|
+
def [](key, *args)
|
26
|
+
res = super(key, *args)
|
27
|
+
res = IndiferentHash.setup(res) if Hash === res
|
27
28
|
return res unless res.nil? or (_default? and not keys.include? key)
|
28
29
|
|
29
30
|
case key
|
30
31
|
when Symbol, Module
|
31
|
-
super(key.to_s)
|
32
|
+
res = super(key.to_s, *args)
|
32
33
|
when String
|
33
|
-
super(key.to_sym)
|
34
|
-
else
|
35
|
-
res
|
34
|
+
res = super(key.to_sym, *args)
|
36
35
|
end
|
36
|
+
|
37
|
+
res = IndiferentHash.setup(res) if Hash === res
|
38
|
+
|
39
|
+
res
|
37
40
|
end
|
38
41
|
|
39
42
|
def values_at(*key_list)
|
@@ -275,7 +275,6 @@ module Misc
|
|
275
275
|
|
276
276
|
|
277
277
|
def self.step_file?(path)
|
278
|
-
return true if defined?(Step) && Step === path.resource
|
279
278
|
return false unless path =~ /\.files(?:\/|$)/
|
280
279
|
parts = path.split("/")
|
281
280
|
job = parts.select{|p| p =~ /\.files$/}.first
|
@@ -283,9 +282,19 @@ module Misc
|
|
283
282
|
i = parts.index job
|
284
283
|
begin
|
285
284
|
workflow, task = parts.values_at i - 2, i - 1
|
286
|
-
|
285
|
+
_loaded = false
|
286
|
+
begin
|
287
|
+
Kernel.const_get(workflow)
|
288
|
+
rescue
|
289
|
+
if ! _loaded
|
290
|
+
Workflow.require_workflow workflow
|
291
|
+
_loaded = true
|
292
|
+
retry
|
293
|
+
end
|
294
|
+
raise $!
|
295
|
+
end
|
287
296
|
#return Kernel.const_get(workflow).tasks.include? task.to_sym
|
288
|
-
return
|
297
|
+
return parts[i-2..-1] * "/"
|
289
298
|
rescue
|
290
299
|
Log.exception $!
|
291
300
|
end
|
@@ -293,6 +302,8 @@ module Misc
|
|
293
302
|
false
|
294
303
|
end
|
295
304
|
|
305
|
+
RBBT_IDENTIFY_PATH = ENV["RBBT_IDENTIFY_PATH"] != 'false'
|
306
|
+
|
296
307
|
def self.obj2str(obj)
|
297
308
|
_obj = obj
|
298
309
|
obj = Annotated.purge(obj) if Annotated === obj
|
@@ -310,18 +321,21 @@ module Misc
|
|
310
321
|
'false'
|
311
322
|
when Hash
|
312
323
|
"{"<< obj.collect{|k,v| obj2str(k) + '=>' << obj2str(v)}*"," << "}"
|
313
|
-
when (defined?(Path)
|
324
|
+
when (defined?(Path) && Path)
|
314
325
|
if defined?(Step) && Open.exists?(Step.info_file(obj))
|
315
326
|
obj2str(Workflow.load_step(obj))
|
316
|
-
elsif step_file?(obj)
|
317
|
-
"Step file: " +
|
327
|
+
elsif step_file_path = step_file?(obj)
|
328
|
+
"Step file: " + step_file_path
|
318
329
|
else
|
319
330
|
if obj.exists?
|
331
|
+
obj = (obj.resource || Rbbt).identify obj if RBBT_IDENTIFY_PATH
|
320
332
|
if obj.directory?
|
321
333
|
files = obj.glob("**/*")
|
322
|
-
"directory: #{Misc.fingerprint(files)}"
|
323
|
-
|
334
|
+
"directory: #{Misc.fingerprint(files.collect{|f| Misc.path_relative_to(obj.find, f)}.sort)}"
|
335
|
+
elsif obj.located?
|
324
336
|
"file: " << Open.realpath(obj) << "--" << mtime_str(obj)
|
337
|
+
else
|
338
|
+
"path: " << obj
|
325
339
|
end
|
326
340
|
else
|
327
341
|
obj + " (file missing)"
|
@@ -441,6 +455,7 @@ module Misc
|
|
441
455
|
end
|
442
456
|
|
443
457
|
def self.scan_version_text(text, cmd = nil)
|
458
|
+
text = Misc.fixutf8 text
|
444
459
|
cmd = "NOCMDGIVE" if cmd.nil? || cmd.empty?
|
445
460
|
text.split("\n").each do |line|
|
446
461
|
next unless line =~ /\W#{cmd}\W/i
|
data/lib/rbbt/util/misc/pipes.rb
CHANGED
@@ -318,9 +318,9 @@ module Misc
|
|
318
318
|
Open.mkdir dir unless Open.exists?(dir)
|
319
319
|
into_path, into = into, Open.open(into, :mode => 'w')
|
320
320
|
end
|
321
|
-
into.sync = true if IO === into
|
321
|
+
#into.sync = true if IO === into
|
322
322
|
into_close = false unless into.respond_to? :close
|
323
|
-
io.sync = true
|
323
|
+
#io.sync = true
|
324
324
|
|
325
325
|
begin
|
326
326
|
while c = io.readpartial(BLOCK_SIZE)
|
@@ -402,7 +402,7 @@ module Misc
|
|
402
402
|
when (IO === content or StringIO === content or File === content)
|
403
403
|
|
404
404
|
Open.write(tmp_path) do |f|
|
405
|
-
f.sync = true
|
405
|
+
#f.sync = true
|
406
406
|
while block = content.read(BLOCK_SIZE)
|
407
407
|
f.write block
|
408
408
|
end
|
data/lib/rbbt/util/open.rb
CHANGED
@@ -240,7 +240,6 @@ module Open
|
|
240
240
|
end
|
241
241
|
|
242
242
|
def self.find_repo_dir(file)
|
243
|
-
return nil
|
244
243
|
self.repository_dirs.each do |dir|
|
245
244
|
dir = dir + '/' unless dir.chars[-1] == "/"
|
246
245
|
|
@@ -531,16 +530,22 @@ module Open
|
|
531
530
|
|
532
531
|
def self.gzip?(file)
|
533
532
|
file = file.find if Path === file
|
533
|
+
file = file.filename if File === file
|
534
|
+
return false unless String === file
|
534
535
|
!! (file =~ /\.gz$/)
|
535
536
|
end
|
536
537
|
|
537
538
|
def self.bgzip?(file)
|
538
539
|
file = file.find if Path === file
|
540
|
+
file = file.filename if File === file
|
541
|
+
return false unless String === file
|
539
542
|
!! (file =~ /\.bgz$/)
|
540
543
|
end
|
541
544
|
|
542
545
|
def self.zip?(file)
|
543
546
|
file = file.find if Path === file
|
547
|
+
file = file.filename if File === file
|
548
|
+
return false unless String === file
|
544
549
|
!! (file =~ /\.zip$/)
|
545
550
|
end
|
546
551
|
|
data/lib/rbbt/util/ssh.rb
CHANGED
@@ -9,7 +9,7 @@ class SSHLine
|
|
9
9
|
@ssh = Net::SSH.start(@host, @user)
|
10
10
|
|
11
11
|
@ch = @ssh.open_channel do |ch|
|
12
|
-
ch.exec 'bash'
|
12
|
+
ch.exec 'bash -l'
|
13
13
|
end
|
14
14
|
|
15
15
|
@ch.on_data do |_,data|
|
@@ -37,7 +37,7 @@ class SSHLine
|
|
37
37
|
@complete_output = true
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
40
|
+
def run(command)
|
41
41
|
send_cmd(command)
|
42
42
|
@ssh.loop{ ! @complete_output}
|
43
43
|
if @exit_status.to_i == 0
|
@@ -51,6 +51,7 @@ class SSHLine
|
|
51
51
|
@output = ""
|
52
52
|
@complete_output = false
|
53
53
|
cmd = "ruby -e \"#{script.gsub('"','\\"')}\"\n"
|
54
|
+
Log.debug "Running ruby on #{@host}:\n#{ script }"
|
54
55
|
@ch.send_data(cmd)
|
55
56
|
@ch.send_data("echo DONECMD: $?\n")
|
56
57
|
@ssh.loop{ !@complete_output }
|
@@ -61,16 +62,57 @@ class SSHLine
|
|
61
62
|
end
|
62
63
|
end
|
63
64
|
|
65
|
+
def rbbt(script)
|
66
|
+
rbbt_script =<<-EOF
|
67
|
+
require 'rbbt-util'
|
68
|
+
require 'rbbt/workflow'
|
69
|
+
|
70
|
+
res = begin
|
71
|
+
old_stdout = STDOUT.dup; STDOUT.reopen(STDERR)
|
72
|
+
#{script}
|
73
|
+
ensure
|
74
|
+
STDOUT.reopen(old_stdout)
|
75
|
+
end
|
76
|
+
|
77
|
+
puts Marshal.dump(res)
|
78
|
+
EOF
|
79
|
+
|
80
|
+
m = ruby(rbbt_script)
|
81
|
+
Marshal.load m
|
82
|
+
end
|
83
|
+
|
84
|
+
def workflow(workflow, script)
|
85
|
+
preamble =<<-EOF
|
86
|
+
wf = Workflow.require_workflow('#{workflow}')
|
87
|
+
EOF
|
88
|
+
|
89
|
+
rbbt(preamble + "\n" + script)
|
90
|
+
end
|
91
|
+
|
64
92
|
@connections = {}
|
65
93
|
def self.open(host, user = nil)
|
66
94
|
@connections[[host, user]] ||= SSHLine.new host, user
|
67
95
|
end
|
68
96
|
|
69
|
-
def self.run(server, cmd)
|
70
|
-
|
97
|
+
def self.run(server, cmd, options = nil)
|
98
|
+
cmd = cmd * " " if Array === cmd
|
99
|
+
cmd += " " + CMD.process_cmd_options(options) if options
|
100
|
+
open(server).run(cmd)
|
71
101
|
end
|
72
102
|
|
73
103
|
def self.ruby(server, script)
|
74
104
|
open(server).ruby(script)
|
75
105
|
end
|
106
|
+
|
107
|
+
def self.rbbt(server, script)
|
108
|
+
open(server).rbbt(script)
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.workflow(server, workflow, script)
|
112
|
+
open(server).workflow(workflow, script)
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.command(server, command, argv = [], options = nil)
|
116
|
+
run(server, [command] + argv, options)
|
117
|
+
end
|
76
118
|
end
|
@@ -99,7 +99,7 @@ STDOUT.write res.to_json
|
|
99
99
|
JSON.parse(json)
|
100
100
|
end
|
101
101
|
|
102
|
-
def self.get_raw(url, params)
|
102
|
+
def self.get_raw(url, params = {})
|
103
103
|
server, path = parse_url(url)
|
104
104
|
script = path_script(path)
|
105
105
|
|
@@ -224,7 +224,7 @@ job.clean
|
|
224
224
|
def self.upload_dependencies(job_list, server, search_path = 'user', produce_dependencies = false)
|
225
225
|
server, path = parse_url(server) if server =~ /^ssh:\/\//
|
226
226
|
|
227
|
-
job_list = [
|
227
|
+
job_list = [job_list] unless Array === job_list
|
228
228
|
|
229
229
|
all_deps = {}
|
230
230
|
if produce_dependencies
|
@@ -242,7 +242,6 @@ job.clean
|
|
242
242
|
all_deps[dep] << job
|
243
243
|
end
|
244
244
|
end
|
245
|
-
iif all_deps
|
246
245
|
|
247
246
|
missing_deps = []
|
248
247
|
all_deps.each do |dep,jobs|
|
@@ -250,11 +249,11 @@ job.clean
|
|
250
249
|
Log.medium "Producing #{dep.workflow}:#{dep.short_path} dependency for #{Misc.fingerprint jobs}"
|
251
250
|
dep.run(true)
|
252
251
|
missing_deps << dep
|
253
|
-
end
|
252
|
+
end if produce_dependencies
|
254
253
|
Step.wait_for_jobs missing_deps
|
255
254
|
|
256
|
-
migrate_dependencies = all_deps.keys.select{|d| d.done? }.collect{|d| d.path }
|
257
|
-
Log.
|
255
|
+
migrate_dependencies = all_deps.keys.collect{|d| [d] + d.rec_dependencies + d.input_dependencies }.flatten.select{|d| d.done? }.collect{|d| d.path }
|
256
|
+
Log.low "Migrating #{migrate_dependencies.length} dependencies from #{Misc.fingerprint job_list} to #{ server }"
|
258
257
|
Step.migrate(migrate_dependencies, search_path, :target => server) if migrate_dependencies.any?
|
259
258
|
end
|
260
259
|
|
@@ -312,7 +311,7 @@ job.clean
|
|
312
311
|
|
313
312
|
workflow_name = job.workflow.to_s
|
314
313
|
remote_workflow = RemoteWorkflow.new("ssh://#{server}:#{workflow_name}", "#{workflow_name}")
|
315
|
-
inputs = job.recursive_inputs.to_hash.slice(*job.real_inputs.map{|i| i.to_s})
|
314
|
+
inputs = IndiferentHash.setup(job.recursive_inputs.to_hash).slice(*job.real_inputs.map{|i| i.to_s})
|
316
315
|
Log.medium "Relaying dependency #{job.workflow}:#{job.short_path} to #{server} (#{inputs.keys * ", "})"
|
317
316
|
|
318
317
|
rjob = remote_workflow.job(job.task_name.to_s, job.clean_name, inputs)
|
@@ -331,6 +330,7 @@ job.clean
|
|
331
330
|
if options[:migrate]
|
332
331
|
rjobs_job.each do |rjob,job|
|
333
332
|
rjob.produce
|
333
|
+
iif [:migrate, job]
|
334
334
|
Step.migrate(Rbbt.identify(job.path), 'user', :source => server)
|
335
335
|
end
|
336
336
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class RemoteStep
|
2
2
|
module SSH
|
3
|
-
attr_accessor :override_dependencies, :run_type, :slurm_options
|
3
|
+
attr_accessor :override_dependencies, :run_type, :slurm_options, :produce_dependencies
|
4
4
|
|
5
5
|
def init_job(cache_type = nil, other_params = {})
|
6
6
|
return self if @url
|
@@ -52,11 +52,12 @@ class RemoteStep
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def _run
|
55
|
-
RemoteWorkflow::SSH.upload_dependencies(self, @server)
|
55
|
+
RemoteWorkflow::SSH.upload_dependencies(self, @server, 'user', @produce_dependencies)
|
56
56
|
RemoteWorkflow::SSH.run_job(File.join(base_url, task.to_s), @input_id, @base_name)
|
57
57
|
end
|
58
58
|
|
59
59
|
def _run_slurm
|
60
|
+
RemoteWorkflow::SSH.upload_dependencies(self, @server, 'user', @produce_dependencies)
|
60
61
|
RemoteWorkflow::SSH.run_slurm_job(File.join(base_url, task.to_s), @input_id, @base_name, @slurm_options || {})
|
61
62
|
end
|
62
63
|
|
@@ -115,7 +116,7 @@ class RemoteStep
|
|
115
116
|
select{|i| Step === i || (defined?(RemoteStep) && RemoteStep === i) } +
|
116
117
|
inputs.values.flatten.
|
117
118
|
select{|dep| Path === dep && Step === dep.resource }.
|
118
|
-
select{|dep| ! dep.resource.started? }. # Ignore input_deps already started
|
119
|
+
#select{|dep| ! dep.resource.started? }. # Ignore input_deps already started
|
119
120
|
collect{|dep| dep.resource }
|
120
121
|
end
|
121
122
|
end
|
@@ -107,7 +107,7 @@ class Step
|
|
107
107
|
canfail = ComputeDependency === job && job.canfail?
|
108
108
|
end
|
109
109
|
|
110
|
-
raise_dependency_error(job) if job.error? and not canfail
|
110
|
+
Step.raise_dependency_error(job) if job.error? and not canfail
|
111
111
|
end
|
112
112
|
|
113
113
|
def self.raise_dependency_error(job)
|
@@ -145,11 +145,11 @@ class Step
|
|
145
145
|
end
|
146
146
|
|
147
147
|
def input_dependencies
|
148
|
-
@input_dependencies ||= recursive_inputs.flatten.
|
148
|
+
@input_dependencies ||= recursive_inputs(true).flatten.
|
149
149
|
select{|i| Step === i || (defined?(RemoteStep) && RemoteStep === i) } +
|
150
|
-
recursive_inputs.flatten.
|
150
|
+
recursive_inputs(true).flatten.
|
151
151
|
select{|dep| Path === dep && Step === dep.resource }.
|
152
|
-
select{|dep| ! dep.resource.started? }. # Ignore input_deps already started
|
152
|
+
#select{|dep| ! dep.resource.started? }. # Ignore input_deps already started
|
153
153
|
collect{|dep| dep.resource }
|
154
154
|
end
|
155
155
|
|
@@ -193,7 +193,7 @@ class Step
|
|
193
193
|
|
194
194
|
if dependency.error?
|
195
195
|
log_dependency_exec(dependency, :error)
|
196
|
-
raise_dependency_error dependency
|
196
|
+
Step.raise_dependency_error dependency
|
197
197
|
end
|
198
198
|
|
199
199
|
if dependency.streaming?
|
@@ -382,7 +382,7 @@ class Step
|
|
382
382
|
|
383
383
|
def run_dependencies
|
384
384
|
|
385
|
-
rec_dependencies = self.rec_dependencies(true) + input_dependencies
|
385
|
+
rec_dependencies = self.rec_dependencies(true) + input_dependencies.reject{|d| d.started? }
|
386
386
|
|
387
387
|
return if rec_dependencies.empty?
|
388
388
|
|
@@ -402,7 +402,7 @@ class Step
|
|
402
402
|
seen_paths << step.path
|
403
403
|
|
404
404
|
begin
|
405
|
-
Step.prepare_for_execution(step) unless step == self
|
405
|
+
Step.prepare_for_execution(step) unless step == self
|
406
406
|
rescue DependencyError, DependencyRbbtException
|
407
407
|
raise $! unless canfail_paths.include? step.path
|
408
408
|
end
|
@@ -423,6 +423,7 @@ class Step
|
|
423
423
|
|
424
424
|
produced = []
|
425
425
|
(dependencies + input_dependencies).each do |dep|
|
426
|
+
next if dep.started?
|
426
427
|
next unless ComputeDependency === dep
|
427
428
|
if dep.compute == :produce
|
428
429
|
dep.produce
|
@@ -580,7 +581,6 @@ class Step
|
|
580
581
|
#but dependencies are absent, meanining that the file could have been dropped
|
581
582
|
#in
|
582
583
|
def rec_dependencies(connected = false, seen = [])
|
583
|
-
|
584
584
|
# A step result with no info_file means that it was manually
|
585
585
|
# placed. In that case, do not consider its dependencies
|
586
586
|
return [] if ! (defined? WorkflowRemoteClient && WorkflowRemoteClient::RemoteStep === self) && ! Open.exists?(self.info_file) && Open.exists?(self.path.to_s)
|
@@ -598,7 +598,7 @@ class Step
|
|
598
598
|
#next if self.done? && Open.exists?(info_file) && info[:dependencies] && info[:dependencies].select{|task,name,path| path == step.path }.empty?
|
599
599
|
next if archived_deps.include? step.path
|
600
600
|
next if seen.include? step
|
601
|
-
next if
|
601
|
+
next if step.done? && connected && ! step.updatable?
|
602
602
|
|
603
603
|
r = step.rec_dependencies(connected, new_dependencies)
|
604
604
|
new_dependencies.concat r
|
@@ -49,9 +49,9 @@ module Workflow
|
|
49
49
|
when :nofile
|
50
50
|
inputs[input.to_sym] = Open.realpath(file)
|
51
51
|
when :path_array
|
52
|
-
inputs[input.to_sym] = Open.read(file).strip.split("\n")
|
52
|
+
inputs[input.to_sym] = Open.read(file).strip.split("\n").collect{|p| Path.setup(p) }
|
53
53
|
when :path
|
54
|
-
inputs[input.to_sym] = Open.read(file).strip.split("\n").first
|
54
|
+
inputs[input.to_sym] = Path.setup(Open.read(file).strip.split("\n").first)
|
55
55
|
when :io
|
56
56
|
inputs[input.to_sym] = Open.open(Open.realpath(file))
|
57
57
|
when :io_array
|
@@ -156,7 +156,7 @@ class Step
|
|
156
156
|
path = path + '.as_path'
|
157
157
|
end
|
158
158
|
when String
|
159
|
-
if Misc.is_filename?(value,
|
159
|
+
if Misc.is_filename?(value, true)
|
160
160
|
value = value.dup
|
161
161
|
value.extend Path
|
162
162
|
return save_input(name, value, type, dir)
|
@@ -175,7 +175,7 @@ class Step
|
|
175
175
|
path = path + '.as_path_array'
|
176
176
|
end
|
177
177
|
when String
|
178
|
-
if Misc.is_filename?(value.first,
|
178
|
+
if Misc.is_filename?(value.first, true)
|
179
179
|
path = path + '.as_path_array'
|
180
180
|
end
|
181
181
|
when IO
|
@@ -251,5 +251,4 @@ class Step
|
|
251
251
|
|
252
252
|
inputs.keys
|
253
253
|
end
|
254
|
-
|
255
254
|
end
|