scout-gear 10.7.4 → 10.7.6

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +0 -4
  3. data/.vimproject +9 -14
  4. data/Rakefile +1 -4
  5. data/VERSION +1 -1
  6. data/lib/scout/association/index.rb +3 -3
  7. data/lib/scout/entity/identifiers.rb +5 -2
  8. data/lib/scout/entity/property.rb +1 -1
  9. data/lib/scout/knowledge_base/description.rb +108 -0
  10. data/lib/scout/knowledge_base/entity.rb +6 -1
  11. data/lib/scout/knowledge_base/registry.rb +43 -15
  12. data/lib/scout/knowledge_base.rb +3 -2
  13. data/lib/scout/tsv/change_id/translate.rb +9 -2
  14. data/lib/scout/tsv/open.rb +10 -0
  15. data/lib/scout/tsv/parser.rb +14 -3
  16. data/lib/scout/workflow/deployment/orchestrator.rb +9 -1
  17. data/lib/scout/workflow/deployment/queue.rb +26 -0
  18. data/lib/scout/workflow/entity.rb +99 -0
  19. data/lib/scout/workflow/export.rb +72 -0
  20. data/lib/scout/workflow/persist.rb +6 -0
  21. data/lib/scout/workflow/step/file.rb +3 -3
  22. data/lib/scout/workflow/step/info.rb +6 -0
  23. data/lib/scout/workflow/step/inputs.rb +11 -1
  24. data/lib/scout/workflow/step/provenance.rb +1 -2
  25. data/lib/scout/workflow/step/status.rb +1 -0
  26. data/lib/scout/workflow/step.rb +5 -3
  27. data/lib/scout/workflow/task/inputs.rb +2 -1
  28. data/lib/scout/workflow/task.rb +2 -1
  29. data/lib/scout/workflow.rb +11 -3
  30. data/lib/scout-gear.rb +5 -1
  31. data/scout-gear.gemspec +14 -18
  32. data/scout_commands/kb/config +3 -0
  33. data/scout_commands/kb/list +1 -0
  34. data/scout_commands/kb/query +2 -1
  35. data/scout_commands/kb/register +3 -1
  36. data/scout_commands/kb/show +4 -2
  37. data/scout_commands/workflow/cmd +116 -0
  38. data/scout_commands/workflow/process +82 -0
  39. data/scout_commands/workflow/task +15 -3
  40. data/test/data/person/README.md +17 -0
  41. data/test/scout/knowledge_base/test_description.rb +59 -0
  42. data/test/scout/workflow/task/test_dependencies.rb +7 -7
  43. data/test/scout/workflow/test_definition.rb +2 -2
  44. data/test/scout/workflow/test_entity.rb +58 -0
  45. data/test/scout/workflow/test_step.rb +1 -1
  46. metadata +14 -57
  47. data/lib/scout/offsite/exceptions.rb +0 -9
  48. data/lib/scout/offsite/ssh.rb +0 -175
  49. data/lib/scout/offsite/step.rb +0 -100
  50. data/lib/scout/offsite/sync.rb +0 -55
  51. data/lib/scout/offsite.rb +0 -3
  52. data/scout_commands/offsite +0 -30
  53. data/test/scout/offsite/test_ssh.rb +0 -15
  54. data/test/scout/offsite/test_step.rb +0 -32
  55. data/test/scout/offsite/test_sync.rb +0 -36
  56. data/test/scout/offsite/test_task.rb +0 -0
  57. data/test/scout/test_offsite.rb +0 -0
@@ -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
@@ -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
@@ -1,55 +0,0 @@
1
- class SSHLine
2
- def self.locate(server, paths, map: :user)
3
- SSHLine.scout server, <<-EOF
4
- map = :#{map}
5
- paths = [#{paths.collect{|p| "'" + p + "'" } * ", " }]
6
- located = paths.collect{|p| Path.setup(p).find(map) }
7
- identified = paths.collect{|p| Resource.identify(p) }
8
- [located, identified]
9
- EOF
10
- end
11
-
12
- def self.rsync(source_path, target_path, directory: false, source: nil, target: nil, dry_run: false, hard_link: false)
13
- rsync_args = "-avztHP --copy-unsafe-links --omit-dir-times "
14
-
15
- rsync_args << "--link-dest '#{source_path}' " if hard_link && ! source
16
-
17
- source_path = source_path + "/" if directory && ! source_path.end_with?("/")
18
- target_path = target_path + "/" if directory && ! target_path.end_with?("/")
19
- if target
20
- SSHLine.mkdir target, File.dirname(target_path)
21
- else
22
- Open.mkdir(File.dirname(target_path))
23
- end
24
-
25
- cmd = 'rsync '
26
- cmd << rsync_args
27
- cmd << '-nv ' if dry_run
28
- cmd << (source ? [source, source_path] * ":" : source_path) << " "
29
- cmd << (target ? [target, target_path] * ":" : target_path) << " "
30
-
31
- CMD.cmd_log(cmd, :log => Log::HIGH)
32
- end
33
-
34
- def self.sync(paths, source: nil, target: nil, map: :user, **kwargs)
35
- source = nil if source == 'localhost'
36
- target = nil if target == 'localhost'
37
-
38
- if source
39
- source_paths, identified_paths = SSHLine.locate(source, paths)
40
- else
41
- source_paths = paths.collect{|p| Path === p ? p.find : p }
42
- identified_paths = paths.collect{|p| Resource.identify(p) }
43
- end
44
-
45
- if target
46
- target_paths = SSHLine.locate(target, identified_paths, map: map)
47
- else
48
- target_paths = identified_paths.collect{|p| p.find(map) }
49
- end
50
-
51
- source_paths.zip(target_paths).each do |source_path,target_path|
52
- rsync(source_path, target_path, source: source, target: target, **kwargs)
53
- end
54
- end
55
- end
data/lib/scout/offsite.rb DELETED
@@ -1,3 +0,0 @@
1
- require_relative 'offsite/ssh'
2
- require_relative 'offsite/step'
3
- require_relative 'offsite/sync'
@@ -1,30 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'scout'
4
- require 'scout/offsite'
5
-
6
- $0 = "scout #{$previous_commands.any? ? $previous_commands*" " + " " : "" }#{ File.basename(__FILE__) }" if $previous_commands
7
-
8
- options = SOPT.setup <<EOF
9
-
10
- Description of the tool
11
-
12
- $ #{$0} [<options>] <where> <command> ... -- [<protected options>]
13
-
14
- Run a command offsite. Use -- to make sure options reach the offsite
15
-
16
- -h--help Print this help
17
- EOF
18
- if options[:help]
19
- if defined? scout_usage
20
- scout_usage
21
- else
22
- puts SOPT.doc
23
- end
24
- exit 0
25
- end
26
-
27
- where = ARGV.shift
28
- command = ARGV.shift
29
-
30
- puts SSHLine.command(where, command, ARGV)
@@ -1,15 +0,0 @@
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 TestSSH < Test::Unit::TestCase
5
- def test_marshal
6
- return unless SSHLine.reach?
7
-
8
- assert TrueClass === SSHLine.scout(:default, 'true')
9
- end
10
-
11
- def test_localhost
12
- assert SSHLine.scout('localhost', 'true')
13
- end
14
- end
15
-
@@ -1,32 +0,0 @@
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 TestOffsiteStep < Test::Unit::TestCase
5
- def test_offsite_task
6
- workflow_code =<<-EOF
7
- module TestWF
8
- extend Workflow
9
-
10
- input :string, :string, "String", "string"
11
- task :string => :string do |string| string end
12
- end
13
-
14
- TestWF.directory = Path.setup("#{tmpdir.offsite.TestWF}")
15
- EOF
16
-
17
- TmpFile.with_file workflow_code, :extension => 'rb' do |wffile|
18
- wf = Workflow.require_workflow wffile
19
-
20
- job = wf.job(:string)
21
-
22
- off = OffsiteStep.setup job, server: 'localhost', workflow_name: wffile
23
-
24
- refute off.done?
25
- assert_equal 'string', off.run
26
-
27
- assert off.done?
28
- assert_equal 'string', off.run
29
- end
30
- end
31
- end
32
-
@@ -1,36 +0,0 @@
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 TestSync < Test::Unit::TestCase
5
- def test_sync
6
- TmpFile.with_path do |tmpdir|
7
- tmpdir = Scout.tmp.tmpdir_sync
8
- tmpdir.dir1.foo.write("FOO")
9
- tmpdir.dir1.bar.write("BAR")
10
-
11
- TmpFile.with_path do |tmpdir2|
12
- Misc.in_dir tmpdir2 do
13
- SSHLine.sync([tmpdir.dir1], map: :current)
14
-
15
- assert tmpdir2.glob("**/*").select{|f| f.include?('foo') }.any?
16
- end
17
- end
18
- end
19
- end
20
-
21
- def test_sync_dir_map
22
- TmpFile.with_path do |tmpdir|
23
- tmpdir = Scout.tmp.tmpdir_sync
24
- tmpdir.dir1.foo.write("FOO")
25
- tmpdir.dir1.bar.write("BAR")
26
-
27
- TmpFile.with_path do |tmpdir2|
28
- SSHLine.sync([tmpdir.dir1], map: tmpdir2)
29
- Misc.in_dir tmpdir2 do
30
- assert tmpdir2.glob("**/*").select{|f| f.include?('foo') }.any?
31
- end
32
- end
33
- end
34
- end
35
- end
36
-
File without changes
File without changes