scout-gear 10.7.3 → 10.7.5
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/.gitmodules +0 -4
- data/.vimproject +3 -14
- data/Rakefile +1 -4
- data/VERSION +1 -1
- data/bin/scout +15 -2
- data/lib/scout/association/index.rb +1 -1
- data/lib/scout/association.rb +5 -2
- data/lib/scout/entity/identifiers.rb +5 -2
- data/lib/scout/entity/property.rb +2 -3
- data/lib/scout/knowledge_base/entity.rb +12 -3
- data/lib/scout/knowledge_base/registry.rb +3 -1
- data/lib/scout/persist/engine/tokyocabinet.rb +85 -77
- data/lib/scout/persist/tsv/adapter/base.rb +8 -22
- data/lib/scout/tsv/change_id/translate.rb +8 -2
- data/lib/scout/tsv/open.rb +2 -0
- data/lib/scout/tsv/parser.rb +10 -0
- data/lib/scout/tsv/transformer.rb +12 -0
- data/lib/scout/tsv/util/process.rb +2 -2
- data/lib/scout/workflow/definition.rb +6 -2
- data/lib/scout/workflow/deployment/trace.rb +1 -1
- data/lib/scout/workflow/entity.rb +99 -0
- data/lib/scout/workflow/export.rb +66 -0
- data/lib/scout/workflow/step/dependencies.rb +3 -6
- data/lib/scout/workflow/step/file.rb +3 -3
- data/lib/scout/workflow/step/info.rb +12 -2
- data/lib/scout/workflow/step/provenance.rb +1 -2
- data/lib/scout/workflow/step/status.rb +1 -0
- data/lib/scout/workflow/step.rb +5 -3
- data/lib/scout/workflow/task/info.rb +99 -0
- data/lib/scout/workflow/task/inputs.rb +2 -1
- data/lib/scout/workflow/task.rb +1 -0
- data/lib/scout/workflow.rb +4 -2
- data/lib/scout-gear.rb +5 -1
- data/scout-gear.gemspec +10 -19
- data/scout_commands/doc +3 -3
- data/scout_commands/workflow/task +7 -2
- data/test/scout/knowledge_base/test_list.rb +4 -4
- data/test/scout/knowledge_base/test_registry.rb +19 -0
- data/test/scout/persist/test_tsv.rb +1 -0
- data/test/scout/test_association.rb +15 -0
- data/test/scout/test_tsv.rb +15 -0
- data/test/scout/tsv/test_parser.rb +4 -0
- data/test/scout/tsv/test_transformer.rb +13 -0
- data/test/scout/workflow/step/test_info.rb +11 -0
- data/test/scout/workflow/task/test_dependencies.rb +7 -7
- data/test/scout/workflow/task/test_info.rb +22 -0
- data/test/scout/workflow/test_definition.rb +2 -2
- data/test/scout/workflow/test_entity.rb +58 -0
- data/test/scout/workflow/test_step.rb +1 -1
- metadata +10 -61
- data/lib/scout/offsite/exceptions.rb +0 -9
- data/lib/scout/offsite/ssh.rb +0 -175
- data/lib/scout/offsite/step.rb +0 -100
- data/lib/scout/offsite/sync.rb +0 -55
- data/lib/scout/offsite.rb +0 -3
- data/scout_commands/offsite +0 -30
- data/test/scout/offsite/test_ssh.rb +0 -15
- data/test/scout/offsite/test_step.rb +0 -32
- data/test/scout/offsite/test_sync.rb +0 -36
- data/test/scout/offsite/test_task.rb +0 -0
- data/test/scout/test_offsite.rb +0 -0
@@ -61,5 +61,20 @@ class TestAssociation < Test::Unit::TestCase
|
|
61
61
|
database = Association.database(datadir_test.person.brothers, source: "Older=~Older (Alias)=>Name", persist: true)
|
62
62
|
assert database.respond_to?(:persistence_path)
|
63
63
|
end
|
64
|
+
|
65
|
+
def test_extra_options
|
66
|
+
file=<<-EOF
|
67
|
+
#: :extra_option=:test
|
68
|
+
#Key,Value
|
69
|
+
k,v
|
70
|
+
EOF
|
71
|
+
|
72
|
+
TmpFile.with_path(file.gsub(',', "\t")) do |f|
|
73
|
+
assert_nothing_raised do
|
74
|
+
Association.open(f, target: "Value", source: "Key")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
64
79
|
end
|
65
80
|
|
data/test/scout/test_tsv.rb
CHANGED
@@ -427,4 +427,19 @@ row2 A B Id3
|
|
427
427
|
assert_equal %w(a aa aaa), tsv["row1"]
|
428
428
|
end
|
429
429
|
end
|
430
|
+
|
431
|
+
def test_number_key
|
432
|
+
content =<<-EOF
|
433
|
+
#Id ValueA ValueB OtherID
|
434
|
+
1 a|aa|aaa b Id1|Id2
|
435
|
+
2 A B Id3
|
436
|
+
EOF
|
437
|
+
|
438
|
+
TmpFile.with_file(content) do |filename|
|
439
|
+
tsv = TSV.open(filename, :sep => /\s+/, field: "ValueB")
|
440
|
+
assert_equal "b", tsv["1"]
|
441
|
+
end
|
442
|
+
|
443
|
+
|
444
|
+
end
|
430
445
|
end
|
@@ -153,4 +153,17 @@ row2 A2 B2
|
|
153
153
|
tsv = TSV.open(content)
|
154
154
|
assert_equal %w(A1), tsv.to_double["row1"]["ValueA"]
|
155
155
|
end
|
156
|
+
|
157
|
+
def test_head
|
158
|
+
content =<<-EOF
|
159
|
+
#: :sep=" "
|
160
|
+
#ID ValueA ValueB
|
161
|
+
row1 A1 B1
|
162
|
+
row2 A2 B2
|
163
|
+
row3 A3 B3
|
164
|
+
EOF
|
165
|
+
|
166
|
+
tsv = TSV.open(content)
|
167
|
+
assert_equal ["row1", "row2"], tsv.head(2).keys
|
168
|
+
end
|
156
169
|
end
|
@@ -3,6 +3,17 @@ require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1
|
|
3
3
|
require 'scout/workflow'
|
4
4
|
|
5
5
|
class TestStepInfo < Test::Unit::TestCase
|
6
|
+
def test_benchmark
|
7
|
+
i = {a:1, b: [1,2], c: "String"}
|
8
|
+
times = 100000
|
9
|
+
Misc.benchmark(times) do
|
10
|
+
Marshal.dump(i)
|
11
|
+
end
|
12
|
+
Misc.benchmark(times) do
|
13
|
+
i.to_json
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
6
17
|
def test_dependency
|
7
18
|
TmpFile.with_file do |tmpdir|
|
8
19
|
Path.setup(tmpdir)
|
@@ -120,7 +120,7 @@ class TestTaskDependencies < Test::Unit::TestCase
|
|
120
120
|
job = wf.job(:my_sum, :input1 => 2, :input2 => 3)
|
121
121
|
assert_equal 5, job.run
|
122
122
|
|
123
|
-
TmpFile.with_file(4) do |file|
|
123
|
+
TmpFile.with_file("4") do |file|
|
124
124
|
job = wf.job(:my_sum, :input1 => 2, :input2 => 3, "TaskInputs#step2"=> file)
|
125
125
|
assert_equal 6, job.run
|
126
126
|
assert_not_equal Task::DEFAULT_NAME, job.name
|
@@ -238,7 +238,7 @@ class TestTaskDependencies < Test::Unit::TestCase
|
|
238
238
|
input :input1, :string
|
239
239
|
task :step1 => :string do |i| i end
|
240
240
|
|
241
|
-
dep :step1, :input1 => 1 do |id,options|
|
241
|
+
dep :step1, :input1 => "1" do |id,options|
|
242
242
|
{:inputs => options}
|
243
243
|
end
|
244
244
|
task :step2 => :string do |i| step(:step1).load end
|
@@ -271,7 +271,7 @@ class TestTaskDependencies < Test::Unit::TestCase
|
|
271
271
|
input :input1, :string
|
272
272
|
task :step1 => :string do |i| i end
|
273
273
|
|
274
|
-
dep :step1, :input1 => 1 do |id,options|
|
274
|
+
dep :step1, :input1 => "1" do |id,options|
|
275
275
|
[{:inputs => options}]
|
276
276
|
end
|
277
277
|
input :input2, :string
|
@@ -289,7 +289,7 @@ class TestTaskDependencies < Test::Unit::TestCase
|
|
289
289
|
input :input1, :string
|
290
290
|
task :step1 => :string do |i| i end
|
291
291
|
|
292
|
-
dep :step1, :input1 => 1
|
292
|
+
dep :step1, :input1 => "1"
|
293
293
|
input :input2, :string
|
294
294
|
task :step2 => :string do |i| step(:step1).load end
|
295
295
|
end
|
@@ -304,9 +304,9 @@ class TestTaskDependencies < Test::Unit::TestCase
|
|
304
304
|
wf = Workflow.annonymous_workflow "TaskInputs" do
|
305
305
|
input :input1, :integer, "", 1
|
306
306
|
input :input2, :integer, "", 0
|
307
|
-
task :step1 => :string do |i1,i2| i1 + i2 end
|
307
|
+
task :step1 => :string do |i1,i2| (i1 + i2).to_s end
|
308
308
|
|
309
|
-
dep :step1, :input2 => 1
|
309
|
+
dep :step1, :input2 => "1"
|
310
310
|
task :step2 => :string do |i| step(:step1).load end
|
311
311
|
|
312
312
|
dep :step2
|
@@ -334,7 +334,7 @@ class TestTaskDependencies < Test::Unit::TestCase
|
|
334
334
|
if i1 < 0
|
335
335
|
raise ScoutException
|
336
336
|
else
|
337
|
-
i1
|
337
|
+
i1.to_s
|
338
338
|
end
|
339
339
|
end
|
340
340
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
|
2
|
+
require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
|
3
|
+
|
4
|
+
require 'scout/workflow'
|
5
|
+
class TestWorkflowInfo < Test::Unit::TestCase
|
6
|
+
def test_task_info
|
7
|
+
m = Module.new do
|
8
|
+
extend Workflow
|
9
|
+
self.name = "TestWF"
|
10
|
+
|
11
|
+
input :option1
|
12
|
+
task :step1 do end
|
13
|
+
|
14
|
+
dep :step1
|
15
|
+
input :option2
|
16
|
+
task :step2 do end
|
17
|
+
end
|
18
|
+
info = m.task_info :step2
|
19
|
+
assert_equal "TestWF/step2", info[:id]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -64,7 +64,7 @@ class TestWorkflowDefinition < Test::Unit::TestCase
|
|
64
64
|
refute Open.exist?(dep_path)
|
65
65
|
Scout::Config::CACHE.replace old_cache
|
66
66
|
assert_include job.archived_info, dep_path
|
67
|
-
assert_equal :done, job.archived_info[dep_path][:status]
|
67
|
+
assert_equal :done, job.archived_info[dep_path][:status].to_sym
|
68
68
|
end
|
69
69
|
|
70
70
|
def test_task_alias_remove_dep_partial
|
@@ -95,7 +95,7 @@ class TestWorkflowDefinition < Test::Unit::TestCase
|
|
95
95
|
assert call_name.done?
|
96
96
|
Scout::Config::CACHE.replace old_cache
|
97
97
|
assert_include job.archived_info, call_name.path
|
98
|
-
assert_equal :done, job.archived_info[call_name.path][:status]
|
98
|
+
assert_equal :done, job.archived_info[call_name.path][:status].to_sym
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.expand_path(__FILE__).sub(%r(/test/.*), '/test/test_helper.rb')
|
2
|
+
require File.expand_path(__FILE__).sub(%r(.*/test/), '').sub(/test_(.*)\.rb/,'\1')
|
3
|
+
|
4
|
+
class TestWorkflowEntity < Test::Unit::TestCase
|
5
|
+
def get_EWF
|
6
|
+
@m ||= Module.new do
|
7
|
+
extend EntityWorkflow
|
8
|
+
|
9
|
+
self.name = 'TestEWF'
|
10
|
+
|
11
|
+
property :introduction do
|
12
|
+
"Mi name is #{self}"
|
13
|
+
end
|
14
|
+
|
15
|
+
entity_job hi: :string do
|
16
|
+
"Hi. #{entity.introduction}"
|
17
|
+
end
|
18
|
+
|
19
|
+
list_job group_hi: :string do
|
20
|
+
"Here is the group: " + entity_list.hi * "; "
|
21
|
+
end
|
22
|
+
|
23
|
+
list_job bye: :array do
|
24
|
+
entity_list.collect do |e|
|
25
|
+
"Bye from #{e}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_property_job
|
32
|
+
ewf = get_EWF
|
33
|
+
|
34
|
+
e = ewf.setup("Miki")
|
35
|
+
|
36
|
+
assert_equal "Mi name is Miki", e.introduction
|
37
|
+
assert_equal "Hi. Mi name is Miki", e.hi
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_list
|
41
|
+
ewf = get_EWF
|
42
|
+
|
43
|
+
l = ewf.setup(["Miki", "Clei"])
|
44
|
+
|
45
|
+
assert_equal 2, l.hi.length
|
46
|
+
|
47
|
+
assert_include l.group_hi, "group: "
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_multiple
|
51
|
+
ewf = get_EWF
|
52
|
+
|
53
|
+
l = ewf.setup(["Miki", "Clei"])
|
54
|
+
|
55
|
+
assert_equal 2, l.bye.length
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -387,7 +387,7 @@ class TestWorkflowStep < Test::Unit::TestCase
|
|
387
387
|
step1.fork(false, sem)
|
388
388
|
step2.fork(false, sem)
|
389
389
|
sleep 1
|
390
|
-
assert((step1.status == :queue) || (step2.status == :queue))
|
390
|
+
assert((step1.status.to_sym == :queue) || (step2.status.to_sym == :queue))
|
391
391
|
step1.join
|
392
392
|
step2.join
|
393
393
|
assert_equal "done2", step2.run
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scout-gear
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 10.7.
|
4
|
+
version: 10.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Vazquez
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date: 2025-
|
10
|
+
date: 2025-03-19 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: scout-essentials
|
@@ -66,34 +65,6 @@ dependencies:
|
|
66
65
|
- - ">="
|
67
66
|
- !ruby/object:Gem::Version
|
68
67
|
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rdoc
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '3.12'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '3.12'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: bundler
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '1.0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '1.0'
|
97
68
|
- !ruby/object:Gem::Dependency
|
98
69
|
name: juwelier
|
99
70
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,22 +79,8 @@ dependencies:
|
|
108
79
|
- - "~>"
|
109
80
|
- !ruby/object:Gem::Version
|
110
81
|
version: 2.1.0
|
111
|
-
|
112
|
-
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
125
|
-
description: Temporary files, logs, path, resources, persistence, workflows, TSV,
|
126
|
-
etc.
|
82
|
+
description: 'Scout gear: workflow, TSVs, persistence, entities, associations, and
|
83
|
+
knowledge_bases.'
|
127
84
|
email: mikisvaz@gmail.com
|
128
85
|
executables:
|
129
86
|
- scout
|
@@ -163,11 +120,6 @@ files:
|
|
163
120
|
- lib/scout/knowledge_base/query.rb
|
164
121
|
- lib/scout/knowledge_base/registry.rb
|
165
122
|
- lib/scout/knowledge_base/traverse.rb
|
166
|
-
- lib/scout/offsite.rb
|
167
|
-
- lib/scout/offsite/exceptions.rb
|
168
|
-
- lib/scout/offsite/ssh.rb
|
169
|
-
- lib/scout/offsite/step.rb
|
170
|
-
- lib/scout/offsite/sync.rb
|
171
123
|
- lib/scout/persist/engine.rb
|
172
124
|
- lib/scout/persist/engine/fix_width_table.rb
|
173
125
|
- lib/scout/persist/engine/packed_index.rb
|
@@ -217,7 +169,9 @@ files:
|
|
217
169
|
- lib/scout/workflow/deployment/orchestrator.rb
|
218
170
|
- lib/scout/workflow/deployment/trace.rb
|
219
171
|
- lib/scout/workflow/documentation.rb
|
172
|
+
- lib/scout/workflow/entity.rb
|
220
173
|
- lib/scout/workflow/exceptions.rb
|
174
|
+
- lib/scout/workflow/export.rb
|
221
175
|
- lib/scout/workflow/path.rb
|
222
176
|
- lib/scout/workflow/step.rb
|
223
177
|
- lib/scout/workflow/step/archive.rb
|
@@ -233,6 +187,7 @@ files:
|
|
233
187
|
- lib/scout/workflow/step/status.rb
|
234
188
|
- lib/scout/workflow/task.rb
|
235
189
|
- lib/scout/workflow/task/dependencies.rb
|
190
|
+
- lib/scout/workflow/task/info.rb
|
236
191
|
- lib/scout/workflow/task/inputs.rb
|
237
192
|
- lib/scout/workflow/usage.rb
|
238
193
|
- lib/scout/workflow/util.rb
|
@@ -252,7 +207,6 @@ files:
|
|
252
207
|
- scout_commands/kb/show
|
253
208
|
- scout_commands/kb/traverse
|
254
209
|
- scout_commands/log
|
255
|
-
- scout_commands/offsite
|
256
210
|
- scout_commands/rbbt
|
257
211
|
- scout_commands/resource/produce
|
258
212
|
- scout_commands/template
|
@@ -287,10 +241,6 @@ files:
|
|
287
241
|
- test/scout/knowledge_base/test_query.rb
|
288
242
|
- test/scout/knowledge_base/test_registry.rb
|
289
243
|
- test/scout/knowledge_base/test_traverse.rb
|
290
|
-
- test/scout/offsite/test_ssh.rb
|
291
|
-
- test/scout/offsite/test_step.rb
|
292
|
-
- test/scout/offsite/test_sync.rb
|
293
|
-
- test/scout/offsite/test_task.rb
|
294
244
|
- test/scout/persist/engine/test_fix_width_table.rb
|
295
245
|
- test/scout/persist/engine/test_packed_index.rb
|
296
246
|
- test/scout/persist/engine/test_sharder.rb
|
@@ -308,7 +258,6 @@ files:
|
|
308
258
|
- test/scout/test_association.rb
|
309
259
|
- test/scout/test_entity.rb
|
310
260
|
- test/scout/test_knowledge_base.rb
|
311
|
-
- test/scout/test_offsite.rb
|
312
261
|
- test/scout/test_semaphore.rb
|
313
262
|
- test/scout/test_tsv.rb
|
314
263
|
- test/scout/test_work_queue.rb
|
@@ -347,9 +296,11 @@ files:
|
|
347
296
|
- test/scout/workflow/step/test_provenance.rb
|
348
297
|
- test/scout/workflow/step/test_status.rb
|
349
298
|
- test/scout/workflow/task/test_dependencies.rb
|
299
|
+
- test/scout/workflow/task/test_info.rb
|
350
300
|
- test/scout/workflow/task/test_inputs.rb
|
351
301
|
- test/scout/workflow/test_definition.rb
|
352
302
|
- test/scout/workflow/test_documentation.rb
|
303
|
+
- test/scout/workflow/test_entity.rb
|
353
304
|
- test/scout/workflow/test_path.rb
|
354
305
|
- test/scout/workflow/test_step.rb
|
355
306
|
- test/scout/workflow/test_task.rb
|
@@ -362,7 +313,6 @@ homepage: http://github.com/mikisvaz/scout-gear
|
|
362
313
|
licenses:
|
363
314
|
- MIT
|
364
315
|
metadata: {}
|
365
|
-
post_install_message:
|
366
316
|
rdoc_options: []
|
367
317
|
require_paths:
|
368
318
|
- lib
|
@@ -377,8 +327,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
377
327
|
- !ruby/object:Gem::Version
|
378
328
|
version: '0'
|
379
329
|
requirements: []
|
380
|
-
rubygems_version: 3.5
|
381
|
-
signing_key:
|
330
|
+
rubygems_version: 3.6.5
|
382
331
|
specification_version: 4
|
383
332
|
summary: basic gear for scouts
|
384
333
|
test_files: []
|
data/lib/scout/offsite/ssh.rb
DELETED
@@ -1,175 +0,0 @@
|
|
1
|
-
require 'net/ssh'
|
2
|
-
require_relative 'exceptions'
|
3
|
-
|
4
|
-
class SSHLine
|
5
|
-
class << self
|
6
|
-
attr_accessor :default_server
|
7
|
-
def default_server
|
8
|
-
@@default_server ||= begin
|
9
|
-
ENV["SCOUT_OFFSITE"] || ENV["SCOUT_SERVER"] || 'localhost'
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def initialize(host = :default, user = nil)
|
15
|
-
host = SSHLine.default_server if host.nil? || host == :default
|
16
|
-
@host = host
|
17
|
-
@user = user
|
18
|
-
|
19
|
-
@ssh = Net::SSH.start(@host, @user)
|
20
|
-
|
21
|
-
@ch = @ssh.open_channel do |ch|
|
22
|
-
ch.exec 'bash -l'
|
23
|
-
end
|
24
|
-
|
25
|
-
@ch.send_data("[[ -f ~/.scout/environment ]] && source ~/.scout/environment\n")
|
26
|
-
@ch.send_data("[[ -f ~/.rbbt/environment ]] && source ~/.rbbt/environment\n")
|
27
|
-
|
28
|
-
@ch.on_data do |_,data|
|
29
|
-
if m = data.match(/DONECMD: (\d+)\n/)
|
30
|
-
@exit_status = m[1].to_i
|
31
|
-
@output << data.sub(m[0],'')
|
32
|
-
serve_output
|
33
|
-
else
|
34
|
-
@output << data
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
@ch.on_extended_data do |_,c,err|
|
39
|
-
STDERR.write err
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
def self.reach?(server = SSHLine.default_server)
|
45
|
-
Persist.memory(server, :key => "Reach server") do
|
46
|
-
begin
|
47
|
-
CMD.cmd("ssh #{server} bash -l -c \"scout\"")
|
48
|
-
true
|
49
|
-
rescue Exception
|
50
|
-
false
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def send_cmd(command)
|
56
|
-
@output = ""
|
57
|
-
@complete_output = false
|
58
|
-
@ch.send_data(command+"\necho DONECMD: $?\n")
|
59
|
-
end
|
60
|
-
|
61
|
-
def serve_output
|
62
|
-
@complete_output = true
|
63
|
-
end
|
64
|
-
|
65
|
-
def run(command)
|
66
|
-
send_cmd(command)
|
67
|
-
@ssh.loop{ ! @complete_output}
|
68
|
-
if @exit_status.to_i == 0
|
69
|
-
return @output
|
70
|
-
else
|
71
|
-
raise SSHProcessFailed.new @host, command
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def ruby(script)
|
76
|
-
@output = ""
|
77
|
-
@complete_output = false
|
78
|
-
cmd = "ruby -e \"#{script.gsub('"','\\"')}\"\n"
|
79
|
-
Log.debug "Running ruby on #{@host}:\n#{ script }"
|
80
|
-
@ch.send_data(cmd)
|
81
|
-
@ch.send_data("echo DONECMD: $?\n")
|
82
|
-
@ssh.loop{ !@complete_output }
|
83
|
-
if @exit_status.to_i == 0
|
84
|
-
return @output
|
85
|
-
else
|
86
|
-
raise SSHProcessFailed.new @host, "Ruby script:\n#{script}"
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def scout(script)
|
91
|
-
scout_script =<<-EOF
|
92
|
-
require 'scout'
|
93
|
-
SSHLine.run_local do
|
94
|
-
#{script.strip}
|
95
|
-
end
|
96
|
-
EOF
|
97
|
-
|
98
|
-
m = ruby(scout_script)
|
99
|
-
Marshal.load m
|
100
|
-
end
|
101
|
-
|
102
|
-
def workflow(workflow, script)
|
103
|
-
preamble =<<-EOF
|
104
|
-
wf = Workflow.require_workflow('#{workflow}')
|
105
|
-
EOF
|
106
|
-
|
107
|
-
scout(preamble + "\n" + script)
|
108
|
-
end
|
109
|
-
|
110
|
-
class Mock < SSHLine
|
111
|
-
def initialize
|
112
|
-
end
|
113
|
-
|
114
|
-
def run(command)
|
115
|
-
CMD.cmd(command)
|
116
|
-
end
|
117
|
-
|
118
|
-
def ruby(script)
|
119
|
-
cmd = "ruby -e \"#{script.gsub('"','\\"')}\"\n"
|
120
|
-
CMD.cmd(cmd)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
@connections = {}
|
125
|
-
def self.open(host, user = nil)
|
126
|
-
@connections[[host, user]] ||=
|
127
|
-
begin
|
128
|
-
if host == 'localhost'
|
129
|
-
SSHLine::Mock.new
|
130
|
-
else
|
131
|
-
SSHLine.new host, user
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def self.run(server, cmd, options = nil)
|
137
|
-
cmd = cmd * " " if Array === cmd
|
138
|
-
cmd += " " + CMD.process_cmd_options(options) if options
|
139
|
-
open(server).run(cmd)
|
140
|
-
end
|
141
|
-
|
142
|
-
def self.ruby(server, script)
|
143
|
-
open(server).ruby(script)
|
144
|
-
end
|
145
|
-
|
146
|
-
def self.scout(server, script)
|
147
|
-
open(server).scout(script)
|
148
|
-
end
|
149
|
-
|
150
|
-
def self.workflow(server, workflow, script)
|
151
|
-
open(server).workflow(workflow, script)
|
152
|
-
end
|
153
|
-
|
154
|
-
def self.command(server, command, argv = [], options = nil)
|
155
|
-
command = "scout #{command}" unless command && command.include?('scout')
|
156
|
-
argv_str = (argv - ["--"]).collect{|v| '"' + v.to_s + '"' } * " "
|
157
|
-
command = "#{command} #{argv_str}"
|
158
|
-
Log.debug "Offsite #{server} running: #{command}"
|
159
|
-
run(server, command, options)
|
160
|
-
end
|
161
|
-
|
162
|
-
def self.mkdir(server, path)
|
163
|
-
self.run server, "mkdir -p '#{path}'"
|
164
|
-
end
|
165
|
-
|
166
|
-
def self.run_local(&block)
|
167
|
-
res = begin
|
168
|
-
old_stdout = STDOUT.dup; STDOUT.reopen(STDERR)
|
169
|
-
block.call
|
170
|
-
ensure
|
171
|
-
STDOUT.reopen(old_stdout)
|
172
|
-
end
|
173
|
-
puts Marshal.dump(res)
|
174
|
-
end
|
175
|
-
end
|
data/lib/scout/offsite/step.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
require_relative '../workflow/step'
|
2
|
-
require_relative 'ssh'
|
3
|
-
require_relative 'sync'
|
4
|
-
|
5
|
-
module OffsiteStep
|
6
|
-
|
7
|
-
extend Annotation
|
8
|
-
annotation :server, :workflow_name, :clean_id, :slurm
|
9
|
-
|
10
|
-
def inputs_directory
|
11
|
-
@inputs_directory ||= begin
|
12
|
-
if provided_inputs && provided_inputs.any?
|
13
|
-
file = ".scout/tmp/step_inputs/#{workflow}/#{task_name}/#{name}"
|
14
|
-
TmpFile.with_path do |inputs_dir|
|
15
|
-
save_inputs(inputs_dir)
|
16
|
-
SSHLine.rsync(inputs_dir, file, target: server, directory: true)
|
17
|
-
end
|
18
|
-
file
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def workflow_name
|
24
|
-
@workflow_name || workflow.to_s
|
25
|
-
end
|
26
|
-
|
27
|
-
def offsite_job_ssh(script)
|
28
|
-
parts = []
|
29
|
-
parts << <<~EOF.strip
|
30
|
-
wf = Workflow.require_workflow "#{workflow_name}";
|
31
|
-
EOF
|
32
|
-
|
33
|
-
if inputs_directory
|
34
|
-
parts << <<~EOF.strip
|
35
|
-
job = wf.job(:#{task_name}, "#{clean_name}", :load_inputs => "#{inputs_directory}");
|
36
|
-
EOF
|
37
|
-
else
|
38
|
-
parts << <<~EOF.strip
|
39
|
-
job = wf.job(:#{task_name}, "#{clean_name}");
|
40
|
-
EOF
|
41
|
-
end
|
42
|
-
|
43
|
-
parts << script
|
44
|
-
|
45
|
-
|
46
|
-
SSHLine.scout server, parts * "\n"
|
47
|
-
end
|
48
|
-
|
49
|
-
def offsite_path
|
50
|
-
@path = offsite_job_ssh <<~EOF
|
51
|
-
job.path.identify
|
52
|
-
EOF
|
53
|
-
end
|
54
|
-
|
55
|
-
def info
|
56
|
-
info = @info ||= offsite_job_ssh <<~EOF
|
57
|
-
info = Open.exists?(job.info_file) ? job.info : {}
|
58
|
-
info[:running] = true if job.running?
|
59
|
-
info
|
60
|
-
EOF
|
61
|
-
|
62
|
-
@info = nil unless %w(done aborted error).include?(info[:status].to_s)
|
63
|
-
|
64
|
-
info
|
65
|
-
end
|
66
|
-
|
67
|
-
def done?
|
68
|
-
status == :done
|
69
|
-
end
|
70
|
-
|
71
|
-
def orchestrate_slurm
|
72
|
-
bundle_files = offsite_job_ssh <<~EOF
|
73
|
-
require 'rbbt/hpc'
|
74
|
-
HPC::BATCH_MODULE = HPC.batch_system "SLURM"
|
75
|
-
HPC::BATCH_MODULE.orchestrate_job(job, {})
|
76
|
-
job.join
|
77
|
-
job.bundle_files
|
78
|
-
EOF
|
79
|
-
SSHLine.sync(bundle_files, source: server)
|
80
|
-
self.load
|
81
|
-
end
|
82
|
-
|
83
|
-
|
84
|
-
def exec
|
85
|
-
bundle_files = offsite_job_ssh <<~EOF
|
86
|
-
job.run
|
87
|
-
job.bundle_files
|
88
|
-
EOF
|
89
|
-
SSHLine.sync(bundle_files, source: server)
|
90
|
-
self.load
|
91
|
-
end
|
92
|
-
|
93
|
-
def run
|
94
|
-
if slurm
|
95
|
-
orchestrate_slurm
|
96
|
-
else
|
97
|
-
exec
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|