ood_core 0.10.0 → 0.12.0

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.
@@ -24,21 +24,32 @@ class QstatXmlRListener
24
24
  @parsed_jobs = []
25
25
  @current_job = {
26
26
  :tasks => [],
27
- :native => {} # TODO: improve native reporting
27
+ :native => {
28
+ :ST_name => ''
29
+ }
28
30
  }
29
31
  @current_text = nil
32
+ @processing_JB_stdout_path_list = false
30
33
 
31
34
  @current_request = nil
35
+ @native_tags = ['JB_job_number', 'JB_job_name', 'JB_version', 'JB_project', 'JB_exec_file', 'JB_script_file', 'JB_script_size', 'JB_submission_time', 'JB_execution_time', 'JB_deadline', 'JB_owner', 'JB_uid', 'JB_group', 'JB_gid', 'JB_account', 'JB_cwd', 'JB_notify', 'JB_type', 'JB_reserve', 'JB_priority', 'JB_jobshare', 'JB_verify', 'JB_checkpoint_attr', 'JB_checkpoint_interval', 'JB_restart']
32
36
  end
33
37
 
34
38
  def tag_start(name, attributes)
35
39
  case name
36
40
  when 'hard_request'
37
41
  start_hard_request(attributes)
42
+ when "JB_stdout_path_list"
43
+ @processing_JB_stdout_path_list = true
38
44
  end
39
45
  end
40
46
 
41
47
  def tag_end(name)
48
+ #Add text if in native_tags
49
+ if (@native_tags.include?(name))
50
+ @current_job[:native][:"#{name}"] = @current_text
51
+ end
52
+
42
53
  case name
43
54
  when 'job_list'
44
55
  end_job_list
@@ -64,6 +75,10 @@ class QstatXmlRListener
64
75
  end_hard_request
65
76
  when 'tasks'
66
77
  add_child_tasks
78
+ when 'PN_path'
79
+ end_PN_path
80
+ when 'ST_name'
81
+ end_ST_name
67
82
  end
68
83
  end
69
84
 
@@ -130,6 +145,15 @@ class QstatXmlRListener
130
145
  end
131
146
  end
132
147
 
148
+ def end_PN_path
149
+ @current_job[:native][:PN_path] = @current_text if @processing_JB_stdout_path_list
150
+ @processing_JB_stdout_path_list = false
151
+ end
152
+
153
+ def end_ST_name
154
+ @current_job[:native][:ST_name] = @current_job[:native][:ST_name] + @current_text + ' '
155
+ end
156
+
133
157
  # Store a completed job and reset current_job for the next pass
134
158
  def end_job_list
135
159
  @parsed_jobs << @current_job
@@ -145,4 +169,3 @@ class QstatXmlRListener
145
169
  }
146
170
  end
147
171
  end
148
-
@@ -14,13 +14,17 @@ module OodCore
14
14
  # @option config [Object] :conf (nil) Path to the slurm conf
15
15
  # @option config [Object] :bin (nil) Path to slurm client binaries
16
16
  # @option config [#to_h] :bin_overrides ({}) Optional overrides to Slurm client executables
17
+ # @option config [Object] :submit_host ("") Submit job on login node via ssh
18
+ # @option config [Object] :strict_host_checking (true) Whether to use strict host checking when ssh to submit_host
17
19
  def self.build_slurm(config)
18
20
  c = config.to_h.symbolize_keys
19
- cluster = c.fetch(:cluster, nil)
20
- conf = c.fetch(:conf, nil)
21
- bin = c.fetch(:bin, nil)
22
- bin_overrides = c.fetch(:bin_overrides, {})
23
- slurm = Adapters::Slurm::Batch.new(cluster: cluster, conf: conf, bin: bin, bin_overrides: bin_overrides)
21
+ cluster = c.fetch(:cluster, nil)
22
+ conf = c.fetch(:conf, nil)
23
+ bin = c.fetch(:bin, nil)
24
+ bin_overrides = c.fetch(:bin_overrides, {})
25
+ submit_host = c.fetch(:submit_host, "")
26
+ strict_host_checking = c.fetch(:strict_host_checking, true)
27
+ slurm = Adapters::Slurm::Batch.new(cluster: cluster, conf: conf, bin: bin, bin_overrides: bin_overrides, submit_host: submit_host, strict_host_checking: strict_host_checking)
24
28
  Adapters::Slurm.new(slurm: slurm)
25
29
  end
26
30
  end
@@ -62,6 +66,16 @@ module OodCore
62
66
  # @return Hash<String, String>
63
67
  attr_reader :bin_overrides
64
68
 
69
+ # The login node where the job is submitted via ssh
70
+ # @example owens.osc.edu
71
+ # @return [String] The login node
72
+ attr_reader :submit_host
73
+
74
+ # Wheter to use strict host checking when ssh to submit_host
75
+ # @example false
76
+ # @return [Bool]; true if empty
77
+ attr_reader :strict_host_checking
78
+
65
79
  # The root exception class that all Slurm-specific exceptions inherit
66
80
  # from
67
81
  class Error < StandardError; end
@@ -69,11 +83,16 @@ module OodCore
69
83
  # @param cluster [#to_s, nil] the cluster name
70
84
  # @param conf [#to_s, nil] path to the slurm conf
71
85
  # @param bin [#to_s] path to slurm installation binaries
72
- def initialize(cluster: nil, bin: nil, conf: nil, bin_overrides: {})
73
- @cluster = cluster && cluster.to_s
74
- @conf = conf && Pathname.new(conf.to_s)
75
- @bin = Pathname.new(bin.to_s)
76
- @bin_overrides = bin_overrides
86
+ # @param bin_overrides [#to_h] a hash of bin ovverides to be used in job
87
+ # @param submit_host [#to_s] Submits the job on a login node via ssh
88
+ # @param strict_host_checking [Bool] Whether to use strict host checking when ssh to submit_host
89
+ def initialize(cluster: nil, bin: nil, conf: nil, bin_overrides: {}, submit_host: "", strict_host_checking: true)
90
+ @cluster = cluster && cluster.to_s
91
+ @conf = conf && Pathname.new(conf.to_s)
92
+ @bin = Pathname.new(bin.to_s)
93
+ @bin_overrides = bin_overrides
94
+ @submit_host = submit_host.to_s
95
+ @strict_host_checking = strict_host_checking
77
96
  end
78
97
 
79
98
  # Get a list of hashes detailing each of the jobs on the batch server
@@ -148,9 +167,9 @@ module OodCore
148
167
  #TODO: write some barebones test for this? like 2 options and id or no id
149
168
  def squeue_args(id: "", owner: nil, options: [])
150
169
  args = ["--all", "--states=all", "--noconvert"]
151
- args += ["-o", "#{RECORD_SEPARATOR}#{options.join(UNIT_SEPARATOR)}"]
152
- args += ["-u", owner.to_s] unless owner.to_s.empty?
153
- args += ["-j", id.to_s] unless id.to_s.empty?
170
+ args.concat ["-o", "#{RECORD_SEPARATOR}#{options.join(UNIT_SEPARATOR)}"]
171
+ args.concat ["-u", owner.to_s] unless owner.to_s.empty?
172
+ args.concat ["-j", id.to_s] unless id.to_s.empty?
154
173
  args
155
174
  end
156
175
 
@@ -192,7 +211,7 @@ module OodCore
192
211
  # @return [String] the id of the job that was created
193
212
  def submit_string(str, args: [], env: {})
194
213
  args = args.map(&:to_s) + ["--parsable"]
195
- env = {"SBATCH_EXPORT" => "NONE"}.merge env.each_with_object({}) { |(k, v), h| h[k.to_s] = v.to_s }
214
+ env = env.to_h.each_with_object({}) { |(k, v), h| h[k.to_s] = v.to_s }
196
215
  call("sbatch", *args, env: env, stdin: str.to_s).strip.split(";").first
197
216
  end
198
217
 
@@ -275,11 +294,15 @@ module OodCore
275
294
  # Call a forked Slurm command for a given cluster
276
295
  def call(cmd, *args, env: {}, stdin: "")
277
296
  cmd = OodCore::Job::Adapters::Helper.bin_path(cmd, bin, bin_overrides)
297
+
278
298
  args = args.map(&:to_s)
279
- args += ["-M", cluster] if cluster
299
+ args.concat ["-M", cluster] if cluster
300
+
280
301
  env = env.to_h
281
302
  env["SLURM_CONF"] = conf.to_s if conf
282
- o, e, s = Open3.capture3(env, cmd, *args, stdin_data: stdin.to_s)
303
+
304
+ cmd, args = OodCore::Job::Adapters::Helper.ssh_wrap(submit_host, cmd, args, strict_host_checking)
305
+ o, e, s = Open3.capture3(env, cmd, *(args.map(&:to_s)), stdin_data: stdin.to_s)
283
306
  s.success? ? o : raise(Error, e)
284
307
  end
285
308
 
@@ -358,30 +381,31 @@ module OodCore
358
381
  # Set sbatch options
359
382
  args = []
360
383
  # ignore args, don't know how to do this for slurm
361
- args += ["-H"] if script.submit_as_hold
362
- args += (script.rerunnable ? ["--requeue"] : ["--no-requeue"]) unless script.rerunnable.nil?
363
- args += ["-D", script.workdir.to_s] unless script.workdir.nil?
364
- args += ["--mail-user", script.email.join(",")] unless script.email.nil?
384
+ args.concat ["-H"] if script.submit_as_hold
385
+ args.concat (script.rerunnable ? ["--requeue"] : ["--no-requeue"]) unless script.rerunnable.nil?
386
+ args.concat ["-D", script.workdir.to_s] unless script.workdir.nil?
387
+ args.concat ["--mail-user", script.email.join(",")] unless script.email.nil?
365
388
  if script.email_on_started && script.email_on_terminated
366
- args += ["--mail-type", "ALL"]
389
+ args.concat ["--mail-type", "ALL"]
367
390
  elsif script.email_on_started
368
- args += ["--mail-type", "BEGIN"]
391
+ args.concat ["--mail-type", "BEGIN"]
369
392
  elsif script.email_on_terminated
370
- args += ["--mail-type", "END"]
393
+ args.concat ["--mail-type", "END"]
371
394
  elsif script.email_on_started == false && script.email_on_terminated == false
372
- args += ["--mail-type", "NONE"]
395
+ args.concat ["--mail-type", "NONE"]
373
396
  end
374
- args += ["-J", script.job_name] unless script.job_name.nil?
375
- args += ["-i", script.input_path] unless script.input_path.nil?
376
- args += ["-o", script.output_path] unless script.output_path.nil?
377
- args += ["-e", script.error_path] unless script.error_path.nil?
378
- args += ["--reservation", script.reservation_id] unless script.reservation_id.nil?
379
- args += ["-p", script.queue_name] unless script.queue_name.nil?
380
- args += ["--priority", script.priority] unless script.priority.nil?
381
- args += ["--begin", script.start_time.localtime.strftime("%C%y-%m-%dT%H:%M:%S")] unless script.start_time.nil?
382
- args += ["-A", script.accounting_id] unless script.accounting_id.nil?
383
- args += ["-t", seconds_to_duration(script.wall_time)] unless script.wall_time.nil?
384
- args += ['-a', script.job_array_request] unless script.job_array_request.nil?
397
+ args.concat ["-J", script.job_name] unless script.job_name.nil?
398
+ args.concat ["-i", script.input_path] unless script.input_path.nil?
399
+ args.concat ["-o", script.output_path] unless script.output_path.nil?
400
+ args.concat ["-e", script.error_path] unless script.error_path.nil?
401
+ args.concat ["--reservation", script.reservation_id] unless script.reservation_id.nil?
402
+ args.concat ["-p", script.queue_name] unless script.queue_name.nil?
403
+ args.concat ["--priority", script.priority] unless script.priority.nil?
404
+ args.concat ["--begin", script.start_time.localtime.strftime("%C%y-%m-%dT%H:%M:%S")] unless script.start_time.nil?
405
+ args.concat ["-A", script.accounting_id] unless script.accounting_id.nil?
406
+ args.concat ["-t", seconds_to_duration(script.wall_time)] unless script.wall_time.nil?
407
+ args.concat ['-a', script.job_array_request] unless script.job_array_request.nil?
408
+ args.concat ['--qos', script.qos] unless script.qos.nil?
385
409
  # ignore nodes, don't know how to do this for slurm
386
410
 
387
411
  # Set dependencies
@@ -390,14 +414,14 @@ module OodCore
390
414
  depend << "afterok:#{afterok.join(":")}" unless afterok.empty?
391
415
  depend << "afternotok:#{afternotok.join(":")}" unless afternotok.empty?
392
416
  depend << "afterany:#{afterany.join(":")}" unless afterany.empty?
393
- args += ["-d", depend.join(",")] unless depend.empty?
417
+ args.concat ["-d", depend.join(",")] unless depend.empty?
394
418
 
395
419
  # Set environment variables
396
420
  env = script.job_environment || {}
397
- args += ["--export", script.job_environment.keys.join(",")] unless script.job_environment.nil? || script.job_environment.empty?
421
+ args.concat ["--export", export_arg(env, script.copy_environment?)]
398
422
 
399
423
  # Set native options
400
- args += script.native if script.native
424
+ args.concat script.native if script.native
401
425
 
402
426
  # Set content
403
427
  content = if script.shell_path.nil?
@@ -530,6 +554,10 @@ module OodCore
530
554
  raise JobAdapterError, e.message unless /Invalid job id specified/ =~ e.message
531
555
  end
532
556
 
557
+ def directive_prefix
558
+ '#SBATCH'
559
+ end
560
+
533
561
  private
534
562
  # Convert duration to seconds
535
563
  def duration_in_seconds(time)
@@ -623,6 +651,25 @@ module OodCore
623
651
 
624
652
  Info.new(**parent_task_hash)
625
653
  end
654
+
655
+
656
+ # we default to export NONE, but SLURM defaults to ALL.
657
+ # we do this bc SLURM setups a new environment, loading /etc/profile
658
+ # and all giving 'module' function (among other things shells give),
659
+ # where the PUN did not.
660
+ # --export=ALL export the PUN's environment.
661
+ def export_arg(env, copy_environment)
662
+ if !env.empty? && !copy_environment
663
+ env.keys.join(",")
664
+ elsif !env.empty? && copy_environment
665
+ "ALL," + env.keys.join(",")
666
+ elsif env.empty? && copy_environment
667
+ # only this option changes behaivor dramatically
668
+ "ALL"
669
+ else
670
+ "NONE"
671
+ end
672
+ end
626
673
  end
627
674
  end
628
675
  end
@@ -1,5 +1,6 @@
1
1
  require "ood_core/refinements/hash_extensions"
2
2
  require "ood_core/job/adapters/helper"
3
+ require 'shellwords'
3
4
 
4
5
  module OodCore
5
6
  module Job
@@ -9,16 +10,18 @@ module OodCore
9
10
  # Build the Torque adapter from a configuration
10
11
  # @param config [#to_h] the configuration for job adapter
11
12
  # @option config [#to_s] :host The batch server host
13
+ # @option config [#to_s] :submit_host The login node to submit the job via ssh
12
14
  # @option config [#to_s] :lib ('') Path to torque client libraries
13
15
  # @option config [#to_s] :bin ('') Path to torque client binaries
14
16
  # @option config [#to_h] :custom_bin ({}) Optional overrides to Torque client executables
15
17
  def self.build_torque(config)
16
18
  c = config.to_h.symbolize_keys
17
19
  host = c.fetch(:host) { raise ArgumentError, "No host specified. Missing argument: host" }.to_s
20
+ submit_host = c.fetch(:submit_host, "").to_s
18
21
  lib = c.fetch(:lib, "").to_s
19
22
  bin = c.fetch(:bin, "").to_s
20
23
  custom_bin = c.fetch(:custom_bin, {})
21
- pbs = Adapters::Torque::Batch.new(host: host, lib: lib, bin: bin, custom_bin: custom_bin)
24
+ pbs = Adapters::Torque::Batch.new(host: host, submit_host: submit_host, lib: lib, bin: bin, custom_bin: custom_bin)
22
25
  Adapters::Torque.new(pbs: pbs)
23
26
  end
24
27
  end
@@ -85,7 +88,7 @@ module OodCore
85
88
  depend << "afterany:#{afterany.join(':')}" unless afterany.empty?
86
89
 
87
90
  # Set mailing options
88
- mail_points = ""
91
+ mail_points = ""
89
92
  mail_points += "b" if script.email_on_started
90
93
  mail_points += "e" if script.email_on_terminated
91
94
 
@@ -129,39 +132,44 @@ module OodCore
129
132
  envvars.merge! script.native.fetch(:envvars, {})
130
133
  end
131
134
 
135
+ # Destructively change envvars to shellescape values
136
+ envvars.transform_values! { |v| Shellwords.escape(v) }
137
+
132
138
  # Submit job
133
139
  @pbs.submit_string(script.content, queue: script.queue_name, headers: headers, resources: resources, envvars: envvars)
134
140
  else
135
141
  # Set qsub arguments
136
142
  args = []
137
- args += ["-F", script.args.join(" ")] unless script.args.nil?
138
- args += ["-h"] if script.submit_as_hold
139
- args += ["-r", script.rerunnable ? "y" : "n"] unless script.rerunnable.nil?
140
- args += ["-M", script.email.join(",")] unless script.email.nil?
141
- args += ["-m", mail_points] unless mail_points.empty?
142
- args += ["-N", script.job_name] unless script.job_name.nil?
143
- args += ["-S", script.shell_path] unless script.shell_path.nil?
143
+ args.concat ["-F", script.args.join(" ")] unless script.args.nil?
144
+ args.concat ["-h"] if script.submit_as_hold
145
+ args.concat ["-r", script.rerunnable ? "y" : "n"] unless script.rerunnable.nil?
146
+ args.concat ["-M", script.email.join(",")] unless script.email.nil?
147
+ args.concat ["-m", mail_points] unless mail_points.empty?
148
+ args.concat ["-N", script.job_name] unless script.job_name.nil?
149
+ args.concat ["-S", script.shell_path] unless script.shell_path.nil?
144
150
  # ignore input_path (not defined in Torque)
145
- args += ["-o", script.output_path] unless script.output_path.nil?
146
- args += ["-e", script.error_path] unless script.error_path.nil?
147
- args += ["-W", "x=advres:#{script.reservation_id}"] unless script.reservation_id.nil?
148
- args += ["-q", script.queue_name] unless script.queue_name.nil?
149
- args += ["-p", script.priority] unless script.priority.nil?
150
- args += ["-a", script.start_time.localtime.strftime("%C%y%m%d%H%M.%S")] unless script.start_time.nil?
151
- args += ["-A", script.accounting_id] unless script.accounting_id.nil?
152
- args += ["-W", "depend=#{depend.join(",")}"] unless depend.empty?
153
- args += ["-l", "walltime=#{seconds_to_duration(script.wall_time)}"] unless script.wall_time.nil?
154
- args += ['-t', script.job_array_request] unless script.job_array_request.nil?
151
+ args.concat ["-o", script.output_path] unless script.output_path.nil?
152
+ args.concat ["-e", script.error_path] unless script.error_path.nil?
153
+ args.concat ["-W", "x=advres:#{script.reservation_id}"] unless script.reservation_id.nil?
154
+ args.concat ["-q", script.queue_name] unless script.queue_name.nil?
155
+ args.concat ["-p", script.priority] unless script.priority.nil?
156
+ args.concat ["-a", script.start_time.localtime.strftime("%C%y%m%d%H%M.%S")] unless script.start_time.nil?
157
+ args.concat ["-A", script.accounting_id] unless script.accounting_id.nil?
158
+ args.concat ["-W", "depend=#{depend.join(",")}"] unless depend.empty?
159
+ args.concat ["-l", "walltime=#{seconds_to_duration(script.wall_time)}"] unless script.wall_time.nil?
160
+ args.concat ['-t', script.job_array_request] unless script.job_array_request.nil?
161
+ args.concat ['-l', "qos=#{script.qos}"] unless script.qos.nil?
155
162
  # Set environment variables
156
163
  env = script.job_environment.to_h
157
- args += ["-v", env.keys.join(",")] unless env.empty?
164
+ args.concat ["-v", env.keys.join(",")] unless env.empty?
165
+ args.concat ["-V"] if script.copy_environment?
158
166
 
159
167
  # If error_path is not specified we join stdout & stderr (as this
160
168
  # mimics what the other resource managers do)
161
- args += ["-j", "oe"] if script.error_path.nil?
169
+ args.concat ["-j", "oe"] if script.error_path.nil?
162
170
 
163
171
  # Set native options
164
- args += script.native if script.native
172
+ args.concat script.native if script.native
165
173
 
166
174
  # Submit job
167
175
  @pbs.submit(script.content, args: args, env: env, chdir: script.workdir)
@@ -288,6 +296,10 @@ module OodCore
288
296
  raise JobAdapterError, e.message
289
297
  end
290
298
 
299
+ def directive_prefix
300
+ '#QSUB'
301
+ end
302
+
291
303
  private
292
304
  # Convert duration to seconds
293
305
  def duration_in_seconds(time)
@@ -9,6 +9,18 @@ class OodCore::Job::Adapters::Torque
9
9
  # @return [String] the batch server host
10
10
  attr_reader :host
11
11
 
12
+ # The login node where job is submitted via ssh
13
+ # @example OSC's owens login node
14
+ # my_conn.submit_host #=> "owens.osc.edu"
15
+ # @return [String] the login node
16
+ attr_reader :submit_host
17
+
18
+ # Determines whether to use strict_host_checking for ssh
19
+ # @example
20
+ # my_conn.strict_host_checking.to_s #=> "owens.osc.edu"
21
+ # @return [Bool]
22
+ attr_reader :strict_host_checking
23
+
12
24
  # The path to the Torque client installation libraries
13
25
  # @example For Torque 5.0.0
14
26
  # my_conn.lib.to_s #=> "/usr/local/Torque/5.0.0/lib"
@@ -32,19 +44,23 @@ class OodCore::Job::Adapters::Torque
32
44
  class Error < StandardError; end
33
45
 
34
46
  # @param host [#to_s] the batch server host
47
+ # @param submit_host [#to_s] the login node
48
+ # @param strict_host_checking [bool] use strict host checking when ssh to submit_host
35
49
  # @param lib [#to_s] path to FFI installation libraries
36
50
  # @param bin [#to_s] path to FFI installation binaries
37
- def initialize(host:, lib: "", bin: "", bin_overrides: {}, **_)
38
- @host = host.to_s
39
- @lib = Pathname.new(lib.to_s)
40
- @bin = Pathname.new(bin.to_s)
41
- @bin_overrides = bin_overrides
51
+ def initialize(host:, submit_host: "", strict_host_checking: true, lib: "", bin: "", bin_overrides: {}, **_)
52
+ @host = host.to_s
53
+ @submit_host = submit_host.to_s
54
+ @strict_host_checking = strict_host_checking
55
+ @lib = Pathname.new(lib.to_s)
56
+ @bin = Pathname.new(bin.to_s)
57
+ @bin_overrides = bin_overrides
42
58
  end
43
59
 
44
60
  # Convert object to hash
45
61
  # @return [Hash] the hash describing this object
46
62
  def to_h
47
- {host: host, lib: lib, bin: bin}
63
+ {host: host, submit_host: submit_host, strict_host_checking: strict_host_checking, lib: lib, bin: bin}
48
64
  end
49
65
 
50
66
  # The comparison operator
@@ -437,10 +453,10 @@ class OodCore::Job::Adapters::Torque
437
453
  # NB: The binary includes many useful filters and is preferred
438
454
  def qsub_submit(script, queue, headers, resources, envvars)
439
455
  params = []
440
- params += ["-q", "#{queue}"] unless queue.empty?
441
- params += headers.map {|k,v| qsub_arg(k,v)}.flatten
442
- params += resources.map{|k,v| ["-l", "#{k}=#{v}"]}.flatten
443
- params += ["-v", envvars.map{|k,v| "#{k}=#{v}"}.join(",")] unless envvars.empty?
456
+ params.concat ["-q", "#{queue}"] unless queue.empty?
457
+ params.concat headers.map {|k,v| qsub_arg(k,v)}.flatten
458
+ params.concat resources.map{|k,v| ["-l", "#{k}=#{v}"]}.flatten
459
+ params.concat ["-v", envvars.map{|k,v| "#{k}=#{v}"}.join(",")] unless envvars.empty?
444
460
  params << script
445
461
 
446
462
  env = {
@@ -448,6 +464,7 @@ class OodCore::Job::Adapters::Torque
448
464
  "LD_LIBRARY_PATH" => "#{lib}:#{ENV['LD_LIBRARY_PATH']}"
449
465
  }
450
466
  cmd = OodCore::Job::Adapters::Helper.bin_path('qsub', bin, bin_overrides)
467
+ cmd, params = OodCore::Job::Adapters::Helper.ssh_wrap(submit_host, cmd, params, strict_host_checking, env)
451
468
  o, e, s = Open3.capture3(env, cmd, *params)
452
469
  raise Error, e unless s.success?
453
470
  o.chomp
@@ -456,14 +473,14 @@ class OodCore::Job::Adapters::Torque
456
473
  # Call a forked PBS command for a given host
457
474
  def call(cmd, *args, env: {}, stdin: "", chdir: nil)
458
475
  cmd = OodCore::Job::Adapters::Helper.bin_path(cmd, bin, bin_overrides)
459
- args = args.map(&:to_s)
460
476
  env = env.to_h.each_with_object({}) {|(k,v), h| h[k.to_s] = v.to_s}.merge({
461
477
  "PBS_DEFAULT" => host,
462
478
  "LD_LIBRARY_PATH" => %{#{lib}:#{ENV["LD_LIBRARY_PATH"]}}
463
479
  })
480
+ cmd, args = OodCore::Job::Adapters::Helper.ssh_wrap(submit_host, cmd, args, strict_host_checking, env)
464
481
  stdin = stdin.to_s
465
482
  chdir ||= "."
466
- o, e, s = Open3.capture3(env, cmd, *args, stdin_data: stdin, chdir: chdir.to_s)
483
+ o, e, s = Open3.capture3(env, cmd, *(args.map(&:to_s)), stdin_data: stdin, chdir: chdir.to_s)
467
484
  s.success? ? o : raise(Error, e)
468
485
  end
469
486
  end