rbbt-util 5.34.20 → 5.34.22

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4109d61e49c9573bc85f7c2b8358b1dbd0bdd032dd0376f01c39f3d1e15e2c46
4
- data.tar.gz: 478773feffcb9b316244ac01a28ed975a08ea21093743db33f11afc0d29a85cb
3
+ metadata.gz: 40183cfe120bb6545a1bb59f150bb3cac9426ce018d18485afdbf0c8f1de92b2
4
+ data.tar.gz: fd625b45572be4a158bc9f08007225e284659ec9ef26fbe66a2e9ae7fb84ce9f
5
5
  SHA512:
6
- metadata.gz: 3090d957c156550db02ba305451af8f09aae6b076038e0390003cb6eac060045a61a41f2a1d81dbcdc6278fb1fc0373a188103a0c9748f2f6974862b7361f254
7
- data.tar.gz: 3d6f359bd83c0f10a7f31f6b5d20573ce4d7ed621b4742bbbd9f9ef8169e480e4a61b60d2f7cb21a2009f3d4cab79a0890331cee489363627900453b06a7ae4d
6
+ metadata.gz: f9f2a5ee2e22b84c8bce0f0da023a39cb917a8210ab1c9a4daca7d67902134221fd671da62ca19a2ce02fb06049ea00f4a8a282a1906235f91380d936240b987
7
+ data.tar.gz: 5124409cb58db3eea7029042ec8671e13075bd814b40a25a905a56ccc52ae660e9981f3146f8a2ecaad2c122ea6edea1ea8b4c7d1a1191a58621c797f317577c
@@ -354,7 +354,7 @@ module Path
354
354
 
355
355
  def yaml
356
356
  self.open do |f|
357
- YAML.unsafe_load f
357
+ YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(f) : YAML.load(f)
358
358
  end
359
359
  end
360
360
 
@@ -11,7 +11,7 @@ module TSV
11
11
  attr_accessor :unnamed, :serializer_module, :entity_options, :entity_templates
12
12
 
13
13
  def info
14
- {:key_field => key_field, :fields => fields, :namespace => namespace, :entity_options => entity_options, :type => type, :filename => filename, :identifiers => identifiers, :unnamed => unnamed, :cast => cast}.delete_if{|k,v| v.nil? }
14
+ {:key_field => key_field, :fields => fields.dup, :namespace => namespace, :entity_options => entity_options, :type => type, :filename => filename, :identifiers => identifiers, :unnamed => unnamed, :cast => cast}.delete_if{|k,v| v.nil? }
15
15
  end
16
16
 
17
17
  def annotate(tsv)
@@ -516,7 +516,7 @@ module TSV
516
516
  data.extend TSV unless TSV === data
517
517
  data.type = @type
518
518
  data.key_field = @key_field
519
- data.fields = @fields
519
+ data.fields = @fields.nil? ? nil : @fields.dup
520
520
  data.namespace = @namespace
521
521
  data.filename = @filename
522
522
  data.identifiers = @identifiers
@@ -84,7 +84,7 @@ puts resource[path].find(search_path)
84
84
  #cmd = "rsync -avztAXHP --copy-unsafe-links #{test_str} #{files_from_str} #{excludes_str} '#{source_path}' #{target_path} #{other * " "}"
85
85
 
86
86
  # rsync_args = "-avztAXHP --copy-unsafe-links"
87
- rsync_args = "-avztAHP --copy-unsafe-links"
87
+ rsync_args = "-avztHP --copy-unsafe-links"
88
88
 
89
89
  rsync_args << " --link-dest '#{source_path}'" if hard_link && ! options[:source]
90
90
 
@@ -96,7 +96,7 @@ puts resource[path].find(search_path)
96
96
  puts cmd
97
97
  exit 0
98
98
  else
99
- CMD.cmd_log(cmd, :log => Log::INFO)
99
+ CMD.cmd_log(cmd, :log => Log::HIGH)
100
100
 
101
101
  if options[:delete] && options[:files]
102
102
  remove_files = options[:files].collect{|f| File.join(source_path, f) }
@@ -417,12 +417,42 @@ def self.add_libdir(dir=nil)
417
417
  end
418
418
  end
419
419
 
420
- def self.ssh_run(server, script = nil, &block)
420
+ def self.ssh_run(server, script = nil)
421
421
  Log.debug "Run ssh script in #{server}:\n#{script}"
422
422
 
423
423
  CMD.cmd("ssh '#{server}' 'shopt -s expand_aliases; bash -l -c \"ruby\"' ", :in => script, :log => true).read
424
424
  end
425
425
 
426
+ def self.ssh_connection(server, reset = false)
427
+ @@ssh_connections ||= {}
428
+ @@ssh_connections.delete server if reset
429
+ @@ssh_connections[server] ||= begin
430
+ require 'pty'
431
+ master, slave = PTY.open
432
+ read, write = Misc.pipe
433
+ pid = spawn("ssh '#{server}' 'shopt -s expand_aliases; bash -l' ", :in => read, :out => slave, :err => STDERR.fileno)
434
+ read.close
435
+ slave.close
436
+ [write, master, pid]
437
+ end
438
+ end
439
+
440
+ def self.ssh_run(server, script = nil)
441
+ Log.debug "Run ssh script in #{server}:\n#{script}"
442
+
443
+ write, master, pid = ssh_connection(server)
444
+ write, master = ssh_connection(server, true) if PTY.check pid
445
+ write.puts "echo '#{script.gsub("'", '"') + "\n" + 'puts "\nCMD_OUT_END"'}' | ruby "
446
+ lines = []
447
+ while true
448
+ line = master.gets
449
+ break if line.strip == "CMD_OUT_END"
450
+ lines << line.strip unless line.strip.empty?
451
+ end
452
+ lines * "\n"
453
+
454
+ end
455
+
426
456
  def self.timeout_insist(time, msg = nil, &block)
427
457
  Misc.insist do
428
458
  begin
@@ -72,7 +72,10 @@ module Workflow
72
72
  def setup_override_dependency(dep, workflow, task_name)
73
73
  return [] if dep == :skip || dep == 'skip'
74
74
 
75
- dep = Step === dep ? dep.dup : Workflow.load_step(dep)
75
+ if ! Step === dep
76
+ located = Open.exists?(dep)
77
+ dep = Workflow.load_step(dep)
78
+ end
76
79
 
77
80
  dep.original_workflow ||= dep.workflow if dep.workflow
78
81
  dep.original_task_name ||= dep.task_name if dep.task_name
@@ -92,7 +95,7 @@ module Workflow
92
95
  end
93
96
 
94
97
  dep.task_name = task_name
95
- dep.overriden = dep.original_task_name.to_sym if dep.original_task_name
98
+ dep.overriden = dep.original_task_name.to_sym if dep.original_task_name && located
96
99
 
97
100
  dep.extend step_module
98
101
 
@@ -106,9 +106,9 @@ STDOUT.write res
106
106
  script += job_script(inputs_id, jobname)
107
107
  script +=<<-EOF
108
108
  job.init_info
109
- STDOUT.write job.name
109
+ STDOUT.write job.path
110
110
  EOF
111
- @name = Misc.ssh_run(server, script)
111
+ Misc.ssh_run(server, script)
112
112
  end
113
113
 
114
114
  def self.run_job(url, input_id, jobname = nil)
@@ -117,6 +117,7 @@ STDOUT.write job.name
117
117
  script = path_script(path)
118
118
  script += job_script(input_id, jobname)
119
119
  script +=<<-EOF
120
+ ENV["RBBT_UPDATE"]="#{(ENV["RBBT_UPDATE"] || false).to_s}"
120
121
  job.produce
121
122
  STDOUT.write job.path
122
123
  EOF
@@ -153,31 +154,67 @@ job.clean
153
154
  new = Step.migrate(path, :user, :target => server)
154
155
  Open.write(file, new)
155
156
  end
156
- CMD.cmd("ssh '#{server}' mkdir -p .rbbt/tmp/tmp-ssh_job_inputs/; scp -r '#{dir}' #{server}:.rbbt/tmp/tmp-ssh_job_inputs/#{input_id}")
157
+ CMD.cmd_log("ssh '#{server}' mkdir -p .rbbt/tmp/tmp-ssh_job_inputs/; scp -r '#{dir}' #{server}:.rbbt/tmp/tmp-ssh_job_inputs/#{input_id}")
157
158
  end
158
159
  end
159
160
  end
160
161
 
161
- def self.relay(workflow, task, jobname, inputs, server, options = {})
162
- options = Misc.add_defaults options, :search_path => 'user'
163
- search_path = options[:search_path]
162
+ #def self.relay_old(workflow, task, jobname, inputs, server, options = {})
163
+ # options = Misc.add_defaults options, :search_path => 'user'
164
+ # search_path = options[:search_path]
164
165
 
165
- job = workflow.job(task, jobname, inputs)
166
+ # job = workflow.job(task, jobname, inputs)
166
167
 
167
- job.dependencies.each do |dep|
168
- dep.produce
169
- end
168
+ # job.dependencies.each do |dep|
169
+ # dep.produce
170
+ # end
170
171
 
171
- override_dependencies = job.dependencies.collect{|dep| [dep.workflow.to_s, dep.task_name.to_s] * "#" << "=" << Rbbt.identify(dep.path)}
172
+ # override_dependencies = job.dependencies.collect{|dep| [dep.workflow.to_s, dep.task_name.to_s] * "#" << "=" << Rbbt.identify(dep.path)}
173
+
174
+ # job.dependencies.each do |dep|
175
+ # Step.migrate(dep.path, search_path, :target => server)
176
+ # end
177
+
178
+ # remote = RemoteWorkflow.new("ssh://#{server}:#{workflow.to_s}", "#{workflow.to_s}")
179
+ # rjob = remote.job(task, jobname, {})
180
+ # rjob.override_dependencies = override_dependencies
181
+ # rjob.run
182
+ #end
183
+
184
+ def self.relay_job(job, server, options = {})
185
+ migrate, produce, produce_dependencies, search_path = Misc.process_options options.dup,
186
+ :migrate, :produce, :produce_dependencies, :search_path
187
+
188
+ search_path ||= 'user'
189
+
190
+ produce = true if migrate
191
+
192
+ workflow_name = job.workflow.to_s
193
+ inputs = job.inputs.to_hash
194
+ job.dependencies.each do |dep|
195
+ dep.produce if options[:produce_dependencies]
196
+ next unless dep.done?
172
197
 
173
- job.dependencies.each do |dep|
174
198
  Step.migrate(dep.path, search_path, :target => server)
175
199
  end
176
200
 
177
- remote = RemoteWorkflow.new("ssh://#{server}:#{workflow.to_s}", "#{workflow.to_s}")
178
- rjob = remote.job(task, jobname, {})
201
+ remote_workflow = RemoteWorkflow.new("ssh://#{server}:#{job.workflow.to_s}", "#{job.workflow.to_s}")
202
+ rjob = remote_workflow.job(job.task_name.to_s, job.clean_name, inputs)
203
+
204
+ override_dependencies = job.dependencies.collect{|dep| [dep.workflow.to_s, dep.task_name.to_s] * "#" << "=" << Rbbt.identify(dep.path)}
179
205
  rjob.override_dependencies = override_dependencies
180
- rjob.run
206
+
207
+ if options[:migrate]
208
+ rjob.produce
209
+ Step.migrate(Rbbt.identify(job.path), 'user', :source => server)
210
+ end
211
+
212
+ rjob
213
+ end
214
+
215
+ def self.relay(workflow, task, jobname, inputs, server, options = {})
216
+ job = workflow.job(task, jobname, inputs)
217
+ relay_job(job, server, options)
181
218
  end
182
219
 
183
220
  def workflow_description
@@ -22,12 +22,13 @@ class RemoteStep
22
22
 
23
23
  RemoteWorkflow::SSH.upload_inputs(@server, inputs, @input_types, @input_id)
24
24
 
25
- @name ||= Persist.memory("RemoteSteps", :workflow => self, :task => task, :jobname => @name, :inputs => inputs, :cache_type => cache_type) do
25
+ @remote_path ||= Persist.memory("RemoteSteps", :workflow => self, :task => task, :jobname => @name, :inputs => inputs, :cache_type => cache_type) do
26
26
  Misc.insist do
27
27
  input_types = {}
28
28
  RemoteWorkflow::SSH.post_job(File.join(base_url, task.to_s), @input_id, @base_name)
29
29
  end
30
30
  end
31
+ @name = @remote_path.split("/").last
31
32
 
32
33
  if Open.remote?(@name)
33
34
  @url = @name
@@ -41,9 +42,10 @@ class RemoteStep
41
42
 
42
43
  def path
43
44
  @server, @server_path = RemoteWorkflow::SSH.parse_url @base_url
44
- init_job unless @name
45
45
  if info[:path]
46
46
  "ssh://" + @server + ":" + info[:path]
47
+ elsif @remote_path
48
+ "ssh://" + @server + ":" + @remote_path
47
49
  else
48
50
  "ssh://" + @server + ":" + ["var/jobs", self.workflow.to_s, task_name.to_s, @name] * "/"
49
51
  end
@@ -57,6 +59,7 @@ class RemoteStep
57
59
  while ! done?
58
60
  sleep 1
59
61
  end
62
+ self
60
63
  end
61
64
 
62
65
  def load
@@ -216,6 +216,12 @@ class Step
216
216
  def run(no_load = false)
217
217
  result = nil
218
218
 
219
+ if Workflow === workflow && workflow.relay_tasks && workflow.relay_tasks.include?(task_name)
220
+ server, options = workflow.relay_tasks[task_name]
221
+ options[:migrate] = true
222
+ return RemoteWorkflow::SSH.relay_job(self, server, options)
223
+ end
224
+
219
225
  begin
220
226
  time_elapsed = total_time_elapsed = nil
221
227
  res = @mutex.synchronize do
@@ -111,6 +111,7 @@ module Workflow
111
111
 
112
112
  dir.glob("*#*").each do |od|
113
113
  name = File.basename(od)
114
+ name.sub!(/\.as_path$/,'')
114
115
  value = Open.read(od)
115
116
  Log.debug "Loading override dependency #{ name } as #{value}"
116
117
  inputs[name] = value.chomp
@@ -161,6 +161,13 @@ puts files * "\n"
161
161
  end
162
162
 
163
163
  def self.migrate(path, search_path, options = {})
164
+ if Step === path
165
+ if options[:source]
166
+ path = Rbbt.identify(path.path)
167
+ else
168
+ path = path.path
169
+ end
170
+ end
164
171
  search_path = 'user' if search_path.nil?
165
172
 
166
173
  resource = Rbbt
data/lib/rbbt/workflow.rb CHANGED
@@ -45,6 +45,13 @@ module Workflow
45
45
  load_remote_tasks(Rbbt.root.etc.remote_tasks.find) if Rbbt.root.etc.remote_tasks.exists?
46
46
  end
47
47
 
48
+ def self.init_relay_tasks
49
+ return if defined? @@init_relay_tasks and @@init_relay_tasks
50
+ @@init_relay_tasks = true
51
+ load_relay_tasks(Rbbt.root.etc.relay_tasks.find) if Rbbt.root.etc.relay_tasks.exists?
52
+ end
53
+
54
+
48
55
 
49
56
  def self.require_remote_workflow(wf_name, url)
50
57
  require 'rbbt/workflow/remote_workflow'
@@ -142,6 +149,7 @@ module Workflow
142
149
 
143
150
  def self.require_workflow(wf_name, force_local=false)
144
151
  Workflow.init_remote_tasks
152
+ Workflow.init_relay_tasks
145
153
  # Already loaded
146
154
  begin
147
155
  workflow = Misc.string2const wf_name
@@ -219,6 +227,7 @@ module Workflow
219
227
  attr_accessor :step_cache
220
228
  attr_accessor :load_step_cache
221
229
  attr_accessor :remote_tasks
230
+ attr_accessor :relay_tasks
222
231
 
223
232
  #{{{ ATTR DEFAULTS
224
233
 
@@ -244,7 +253,7 @@ module Workflow
244
253
  when :hash
245
254
  clean_inputs = Annotated.purge(inputs)
246
255
  clean_inputs = clean_inputs.collect{|i| Symbol === i ? i.to_s : i }
247
- deps_str = dependencies.collect{|d| (Step === d || (defined?(RemoteStep) && RemoteStep === Step)) ? "Step: " << (Symbol === d.overriden ? d.path : d.short_path) : d }
256
+ deps_str = dependencies.collect{|d| (Step === d || (defined?(RemoteStep) && RemoteStep === d)) ? "Step: " << (Symbol === d.overriden ? d.path : d.short_path) : d }
248
257
  key_obj = {:inputs => clean_inputs, :dependencies => deps_str }
249
258
  key_str = Misc.obj2str(key_obj)
250
259
  hash_str = Misc.digest(key_str)
@@ -543,7 +552,10 @@ module Workflow
543
552
  persist = input_values.nil? ? false : true
544
553
  persist = false
545
554
 
546
- if ! (Path === step_path ? step_path.find : File.exist?(step_path)) && step_path.split("/").length == 3 && File.exist?(new_path = Rbbt.var.jobs[step_path].find)
555
+ if ! (Path === step_path ? step_path.find : File.exist?(step_path)) &&
556
+ step_path.split("/").length == 3 &&
557
+ File.exist?(new_path = Rbbt.var.jobs[step_path].find)
558
+
547
559
  step_path = new_path
548
560
  end
549
561
 
@@ -638,7 +650,7 @@ module Workflow
638
650
  end
639
651
  step = Step.new path
640
652
  relocated = false
641
- step.dependencies = (step.info[:dependencies] || []).collect do |task,name,dep_path|
653
+ dependencies = (step.info[:dependencies] || []).collect do |task,name,dep_path|
642
654
  if Open.exists?(dep_path) || Open.exists?(dep_path + '.info') || Open.remote?(dep_path) || Open.ssh?(dep_path)
643
655
  Workflow._load_step dep_path
644
656
  else
@@ -647,6 +659,7 @@ module Workflow
647
659
  Workflow._load_step new_path
648
660
  end
649
661
  end
662
+ step.instance_variable_set("@dependencies", dependencies)
650
663
  step.relocated = relocated
651
664
  step.load_inputs_from_info
652
665
  step
@@ -828,4 +841,28 @@ module Workflow
828
841
  Workflow.process_remote_tasks(remote_workflow_tasks)
829
842
  end
830
843
 
844
+ def self.process_relay_tasks(relay_tasks)
845
+ require 'rbbt/workflow/remote_workflow'
846
+ relay_tasks.each do |workflow, servers|
847
+ wf = Workflow.require_workflow workflow
848
+ wf.relay_tasks ||= {}
849
+ IndiferentHash.setup wf.relay_tasks
850
+ servers.each do |server, tasks|
851
+ case tasks
852
+ when Array
853
+ tasks.each do |task|
854
+ wf.relay_tasks[task.to_sym] = [server, {:migrate => :true}]
855
+ end
856
+ else
857
+ wf.relay_tasks[tasks.to_sym] = [server, {:migrate => :true}]
858
+ end
859
+ end
860
+ end
861
+ end
862
+
863
+ def self.load_relay_tasks(filename)
864
+ yaml_text = Open.read(filename)
865
+ relay_workflow_tasks = YAML.load(yaml_text)
866
+ Workflow.process_relay_tasks(relay_workflow_tasks)
867
+ end
831
868
  end
@@ -106,7 +106,7 @@ options = SOPT.get <<EOF
106
106
  -as--array_separator* Change the character that separates elements of Arrays, ',', '|', or '\\n' by default:
107
107
  -cl--clean Clean the last step of the job so that it gets recomputed:
108
108
  -rcl--recursive_clean Clean the last step and its dependencies to recompute the job completely:
109
- -n--name* Job name to use. The name 'Default' is used by default:
109
+ -n--name* Job name to use. The name '#{Workflow::DEFAULT_NAME}' is used by default:
110
110
  -pn--printname Print the name of the job and exit without starting it:
111
111
  -rw--require_workflow* Workflows to require, separated by commas
112
112
  EOF
@@ -155,7 +155,7 @@ end
155
155
 
156
156
  usage workflow, task if help
157
157
 
158
- name = options.delete(:name) || "Default"
158
+ name = options.delete(:name) || Workflow::DEFAULT_NAME
159
159
 
160
160
  # get job args
161
161
  sopt_option_string = SOPT_options(workflow, task)
@@ -178,7 +178,7 @@ available. Examples can be enacted using `rbbt workflow example <workflow>
178
178
  [<task>] [<example>]`.
179
179
 
180
180
  When a task is enacted a job is instantiated. This job is identified by the
181
- `jobname` (which is *Default* unless specified otherwise) and the values of the
181
+ `jobname` (which is *#{Workflow::DEFAULT_NAME}* unless specified otherwise) and the values of the
182
182
  parameters; these two things determine the filename under which the job result
183
183
  will be saved. If the taks is enacted using the same `jobname` and parameters
184
184
  it will result in the same job, pointing to the same result file.
@@ -194,7 +194,7 @@ The `recursive_clean` cleans all the job dependency steps recursively.
194
194
  -wda--workdir_all* Change the working directory of ALL workflow
195
195
  -as--array_separator* Change the character that separates elements of Arrays, ',', '|', or '\\n' by default
196
196
  -fs--field_separator* Change the character that separates fields of TSV files '\\t' by default
197
- -jn--jobname* Job name to use. The name 'Default' is used by default
197
+ -jn--jobname* Job name to use. The name '#{Workflow::DEFAULT_NAME}' is used by default
198
198
  -pn--printname Print the name of the job and exit without starting it
199
199
  -pf--printpath Print the path of the job result
200
200
  -cl--clean Clean the last step of the job so that it gets recomputed
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbbt-util
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.34.20
4
+ version: 5.34.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-07 00:00:00.000000000 Z
11
+ date: 2022-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake