pbs 1.1.4 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +197 -13
- data/lib/pbs.rb +2 -31
- data/lib/pbs/attributes.rb +7 -8
- data/lib/pbs/batch.rb +334 -0
- data/lib/pbs/torque.rb +180 -62
- data/lib/pbs/version.rb +2 -1
- data/pbs.gemspec +3 -2
- metadata +12 -16
- data/config/batch.yml +0 -24
- data/config/websvcs02.osc.edu.yml +0 -24
- data/config/websvcs08.osc.edu.yml +0 -18
- data/examples/simplejob.rb +0 -66
- data/lib/pbs/conn.rb +0 -75
- data/lib/pbs/job.rb +0 -189
- data/lib/pbs/query.rb +0 -103
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b983a1e056e48ac1fb0973f565910ecaa7b59e8
|
4
|
+
data.tar.gz: 72ea5ac4e9b96137f9d234f44ea9912bb4aef298
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: afe01c15267f13df46e452dab396cf568af6751fe4a92648f174b2d3a2af30443b902115938a28c9e4e7e37b0e436e1d37f13f616c3eff0a61c68f1912956c64
|
7
|
+
data.tar.gz: ef15244b9433ffff530d12da0a90a01a3e7d017c127028005f3831322f7cfac1a7c84c07cdf0c9ffdfc64d8ba3c47f53ae62cec06bd1d37d7141cfdf287e0a61
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -2,33 +2,217 @@
|
|
2
2
|
|
3
3
|
## Description
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
## Requirements
|
8
|
-
|
9
|
-
At minimum you will need:
|
10
|
-
* Ruby 2.0
|
11
|
-
* Ruby-FFI gem
|
12
|
-
* Torque >= 4.2.10
|
5
|
+
Ruby wrapper for the Torque C Library utilizing Ruby-FFI. This has been
|
6
|
+
successfully tested with Torque 4.2.10 and greater. Your mileage may vary.
|
13
7
|
|
14
8
|
## Installation
|
15
9
|
|
16
10
|
Add this to your application's Gemfile:
|
17
11
|
|
18
12
|
```ruby
|
19
|
-
|
13
|
+
gem 'pbs'
|
20
14
|
```
|
21
15
|
|
22
16
|
And then execute:
|
23
17
|
|
24
18
|
```bash
|
25
|
-
|
19
|
+
$ bundle install
|
26
20
|
```
|
27
21
|
|
28
22
|
## Usage
|
29
23
|
|
30
|
-
|
24
|
+
All communication with a specific batch server is handled through the `Batch`
|
25
|
+
object. You can generate this object for a given batch server and Torque client
|
26
|
+
installation as:
|
31
27
|
|
32
|
-
```
|
33
|
-
|
28
|
+
```ruby
|
29
|
+
# Create new batch object for OSC's Oakley batch server
|
30
|
+
oakley = PBS::Batch.new(host: 'oak-batch.osc.edu', prefix: '/usr/local/torque/default')
|
31
|
+
|
32
|
+
# Get status information for this batch server
|
33
|
+
# see http://linux.die.net/man/7/pbs_server_attributes
|
34
|
+
oakley.get_status
|
35
|
+
#=>
|
36
|
+
#{
|
37
|
+
# "oak-batch.osc.edu:15001" => {
|
38
|
+
# :server_state => "Idle",
|
39
|
+
# :total_jobs => "2514",
|
40
|
+
# :default_queue => "batch",
|
41
|
+
# ...
|
42
|
+
# }
|
43
|
+
#}
|
44
|
+
|
45
|
+
# Get status information but only filter through specific attributes
|
46
|
+
oakley.get_status(filters: [:server_state, :total_jobs])
|
47
|
+
#=>
|
48
|
+
#{
|
49
|
+
# "oak-batch.osc.edu:15001" => {
|
50
|
+
# :server_state => "Idle",
|
51
|
+
# :total_jobs => "2514"
|
52
|
+
# }
|
53
|
+
#}
|
54
|
+
```
|
55
|
+
|
56
|
+
You can also query information about the nodes, queues, and jobs running on
|
57
|
+
this batch server:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
# Get list of nodes from batch server
|
61
|
+
b.get_nodes
|
62
|
+
#=>
|
63
|
+
#{
|
64
|
+
# "n0003" => {
|
65
|
+
# :state => "free",
|
66
|
+
# :power_state => "Running",
|
67
|
+
# :np => "12",
|
68
|
+
# ...
|
69
|
+
# },
|
70
|
+
# "n0004" => {
|
71
|
+
# :state => "free",
|
72
|
+
# :power_state => "Running",
|
73
|
+
# :np => "12",
|
74
|
+
# ...
|
75
|
+
# }, ...
|
76
|
+
#}
|
77
|
+
|
78
|
+
# To get info about a single node
|
79
|
+
b.get_node("n0003")
|
80
|
+
#=> { ... }
|
81
|
+
|
82
|
+
# Get list of queues from batch server
|
83
|
+
# see http://linux.die.net/man/7/pbs_queue_attributes
|
84
|
+
b.get_queues
|
85
|
+
#=>
|
86
|
+
#{
|
87
|
+
# "batch" => {
|
88
|
+
# :queue_type => "Route",
|
89
|
+
# :total_jobs => "2",
|
90
|
+
# :enabled => "True",
|
91
|
+
# ...
|
92
|
+
# },
|
93
|
+
# "serial" => {
|
94
|
+
# :queue_type => "Execution",
|
95
|
+
# :total_jobs => "2386",
|
96
|
+
# :enabled => "True",
|
97
|
+
# ...
|
98
|
+
# }, ...
|
99
|
+
#}
|
100
|
+
|
101
|
+
# To get info about a single queue
|
102
|
+
b.get_queue("serial")
|
103
|
+
#=> { ... }
|
104
|
+
|
105
|
+
# Get list of jobs from batch server
|
106
|
+
# see http://linux.die.net/man/7/pbs_server_attributes
|
107
|
+
b.get_jobs
|
108
|
+
#=>
|
109
|
+
#{
|
110
|
+
# "6621251.oak-batch.osc.edu" => {
|
111
|
+
# :Job_Name => "FEA_solver",
|
112
|
+
# :Job_Owner => "bob@oakley01.osc.edu",
|
113
|
+
# :job_state => "Q",
|
114
|
+
# ...
|
115
|
+
# },
|
116
|
+
# "6621252.oak-batch.osc.edu" => {
|
117
|
+
# :Job_Name => "CFD_solver",
|
118
|
+
# :Job_Owner => "sally@oakley02.osc.edu",
|
119
|
+
# :job_state => "R",
|
120
|
+
# ...
|
121
|
+
# }, ...
|
122
|
+
#}
|
123
|
+
|
124
|
+
# To get info about a single job
|
125
|
+
b.get_job("6621251.oak-batch.osc.edu")
|
126
|
+
#=> { ... }
|
127
|
+
```
|
128
|
+
|
129
|
+
### Simple Job Submission
|
130
|
+
|
131
|
+
To submit a script to the batch server:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
# Simple job submission
|
135
|
+
job_id = b.submit_script("/path/to/script")
|
136
|
+
#=> "7166037.oak-batch.osc.edu"
|
137
|
+
|
138
|
+
# Get job information for this job
|
139
|
+
b.get_job(job_id)
|
140
|
+
#=> { ... }
|
141
|
+
|
142
|
+
# Hold this job
|
143
|
+
b.hold_job(job_id)
|
144
|
+
|
145
|
+
# Release this job
|
146
|
+
b.release_job(job_id)
|
147
|
+
|
148
|
+
# Delete this job
|
149
|
+
b.delete_job(job_id)
|
150
|
+
```
|
151
|
+
|
152
|
+
To submit a string to the batch server:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
# Submit a string to the batch server
|
156
|
+
job_id = b.submit_string("sleep 60")
|
157
|
+
```
|
158
|
+
|
159
|
+
The above command will actually generate a temporary file on the local disk and
|
160
|
+
submit that to the batch server before it is cleaned up.
|
161
|
+
|
162
|
+
### Advanced Job Submission
|
163
|
+
|
164
|
+
You can programmatically define the PBS directives of your choosing. They will
|
165
|
+
override any set within the batch script.
|
166
|
+
|
167
|
+
Define headers:
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
# Define headers:
|
171
|
+
# -N job_name
|
172
|
+
# -j oe
|
173
|
+
# -o /path/to/output
|
174
|
+
headers = {
|
175
|
+
PBS::ATTR[:N] => "job_name",
|
176
|
+
PBS::ATTR[:j] => "oe",
|
177
|
+
PBS::ATTR[:o] => "/path/to/output"
|
178
|
+
}
|
179
|
+
|
180
|
+
# or you can directly call the key
|
181
|
+
headers = {
|
182
|
+
Job_Name: "job_name",
|
183
|
+
Join_Path: "oe",
|
184
|
+
Output_Path: "/path/to/output"
|
185
|
+
}
|
186
|
+
```
|
187
|
+
|
188
|
+
Define resources (directives that begin with `-l`):
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
# Define resources:
|
192
|
+
# -l nodes=1:ppn=12
|
193
|
+
# -l walltime=05:00:00
|
194
|
+
resources = {
|
195
|
+
nodes: "1:ppn=12",
|
196
|
+
walltime: "05:00:00"
|
197
|
+
}
|
198
|
+
```
|
199
|
+
|
200
|
+
Define environment variables (directive that begins with `-v`):
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
# Define environment variables that will be exposed to batch job
|
204
|
+
envvars = {
|
205
|
+
TOKEN: 'a8dsjf873js0k',
|
206
|
+
USE_GUI: 1
|
207
|
+
}
|
208
|
+
```
|
209
|
+
|
210
|
+
Submit job with these directives:
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
# Advanced job submission
|
214
|
+
job_id = b.submit_script("/path/to/script", headers: headers, resources: resources, envvars: envvars)
|
215
|
+
|
216
|
+
# Get job info
|
217
|
+
b.get_job(job_id)
|
34
218
|
```
|
data/lib/pbs.rb
CHANGED
@@ -1,38 +1,9 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'socket'
|
3
|
-
|
4
1
|
require_relative 'pbs/error'
|
5
2
|
require_relative 'pbs/attributes'
|
6
3
|
require_relative 'pbs/torque'
|
7
|
-
require_relative 'pbs/
|
8
|
-
require_relative 'pbs/query'
|
9
|
-
require_relative 'pbs/job'
|
4
|
+
require_relative 'pbs/batch'
|
10
5
|
require_relative 'pbs/version'
|
11
6
|
|
7
|
+
# The main namespace for pbs
|
12
8
|
module PBS
|
13
|
-
# Path to the batch config yaml file describing the batch servers for
|
14
|
-
# local batch schedulers.
|
15
|
-
# @return [String] Path to the batch config yaml file.
|
16
|
-
def self.default_batch_config_path
|
17
|
-
default_config = File.expand_path("../../config/batch.yml", __FILE__)
|
18
|
-
host_config = File.expand_path("../../config/#{Socket.gethostname}.yml", __FILE__)
|
19
|
-
File.file?(host_config) ? host_config : default_config
|
20
|
-
end
|
21
|
-
|
22
|
-
# Get the path to the batch config yaml file.
|
23
|
-
def self.batch_config_path
|
24
|
-
@batch_config_path ||= self.default_batch_config_path
|
25
|
-
end
|
26
|
-
|
27
|
-
# Set the path to the batch config yaml file.
|
28
|
-
# @param path [String] The path to the batch config yaml file.
|
29
|
-
def self.batch_config_path=(path)
|
30
|
-
@batch_config_path = File.expand_path(path)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Hash generated from reading the batch config yaml file.
|
34
|
-
# @return [Hash] Batch configuration generated from config yaml file.
|
35
|
-
def self.batch_config
|
36
|
-
YAML.load_file(batch_config_path)
|
37
|
-
end
|
38
9
|
end
|
data/lib/pbs/attributes.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
|
-
# Maintains a constant Hash of defined PBS attribute types
|
2
|
-
#
|
3
|
-
# Includes:
|
4
|
-
# Attribute names used by user commands
|
5
|
-
# Additional job and general attribute names
|
6
|
-
# Additional queue attribute names
|
7
|
-
# Additional server attribute names
|
8
|
-
# Additional node attribute names
|
9
1
|
module PBS
|
2
|
+
# Maintains a constant Hash of defined PBS attribute types
|
3
|
+
# Includes:
|
4
|
+
# Attribute names used by user commands
|
5
|
+
# Additional job and general attribute names
|
6
|
+
# Additional queue attribute names
|
7
|
+
# Additional server attribute names
|
8
|
+
# Additional node attribute names
|
10
9
|
ATTR = {
|
11
10
|
# Attribute names used by user commands
|
12
11
|
a: :Execution_Time,
|
data/lib/pbs/batch.rb
ADDED
@@ -0,0 +1,334 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module PBS
|
4
|
+
# Object used for simplified communication with a batch server
|
5
|
+
class Batch
|
6
|
+
# The host of the Torque batch server
|
7
|
+
# @example OSC's Oakley batch server
|
8
|
+
# my_conn.host #=> "oak-batch.osc.edu"
|
9
|
+
# @return [String] the batch server host
|
10
|
+
attr_reader :host
|
11
|
+
|
12
|
+
# The path to the Torque client installation
|
13
|
+
# @example For Torque 5.0.0
|
14
|
+
# my_conn.prefix.to_s #=> "/usr/local/torque/5.0.0"
|
15
|
+
# @return [Pathname, nil] path to torque installation
|
16
|
+
attr_reader :prefix
|
17
|
+
|
18
|
+
# @param host [#to_s] the batch server host
|
19
|
+
# @param prefix [#to_s, nil] path to torque installation
|
20
|
+
def initialize(host:, prefix: nil, **_)
|
21
|
+
@host = host.to_s
|
22
|
+
@prefix = Pathname.new(prefix) if prefix
|
23
|
+
end
|
24
|
+
|
25
|
+
# Convert object to hash
|
26
|
+
# @return [Hash] the hash describing this object
|
27
|
+
def to_h
|
28
|
+
{host: host, prefix: prefix}
|
29
|
+
end
|
30
|
+
|
31
|
+
# The comparison operator
|
32
|
+
# @param other [#to_h] batch server to compare against
|
33
|
+
# @return [Boolean] how batch servers compare
|
34
|
+
def ==(other)
|
35
|
+
to_h == other.to_h
|
36
|
+
end
|
37
|
+
|
38
|
+
# Checks whether two batch server objects are completely identical to each
|
39
|
+
# other
|
40
|
+
# @param other [Batch] batch server to compare against
|
41
|
+
# @return [Boolean] whether same objects
|
42
|
+
def eql?(other)
|
43
|
+
self.class == other.class && self == other
|
44
|
+
end
|
45
|
+
|
46
|
+
# Generates a hash value for this object
|
47
|
+
# @return [Fixnum] hash value of object
|
48
|
+
def hash
|
49
|
+
[self.class, to_h].hash
|
50
|
+
end
|
51
|
+
|
52
|
+
# Creates a connection to batch server and calls block in context of this
|
53
|
+
# connection
|
54
|
+
# @yieldparam cid [Fixnum] connection id from established batch server connection
|
55
|
+
# @yieldreturn the final value of the block
|
56
|
+
def connect(&block)
|
57
|
+
Torque.lib = prefix ? prefix.join('lib', 'libtorque.so') : nil
|
58
|
+
cid = Torque.pbs_connect(host)
|
59
|
+
Torque.raise_error(cid.abs) if cid < 0 # raise error if negative connection id
|
60
|
+
begin
|
61
|
+
value = yield cid
|
62
|
+
ensure
|
63
|
+
Torque.pbs_disconnect(cid) # always close connection
|
64
|
+
end
|
65
|
+
Torque.check_for_error # check for errors at end
|
66
|
+
value
|
67
|
+
end
|
68
|
+
|
69
|
+
# Get a hash with status info for this batch server
|
70
|
+
# @example Status info for OSC Oakley batch server
|
71
|
+
# my_conn.get_status
|
72
|
+
# #=>
|
73
|
+
# #{
|
74
|
+
# # "oak-batch.osc.edu:15001" => {
|
75
|
+
# # :server_state => "Idle",
|
76
|
+
# # ...
|
77
|
+
# # }
|
78
|
+
# #}
|
79
|
+
# @param filters [Array<Symbol>] list of attribs to filter on
|
80
|
+
# @return [Hash] status info for batch server
|
81
|
+
def get_status(filters: [])
|
82
|
+
connect do |cid|
|
83
|
+
filters = PBS::Torque::Attrl.from_list filters
|
84
|
+
batch_status = Torque.pbs_statserver cid, filters, nil
|
85
|
+
batch_status.to_h.tap { Torque.pbs_statfree batch_status }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Get a list of hashes of the queues on the batch server
|
90
|
+
# @example Status info for OSC Oakley queues
|
91
|
+
# my_conn.get_queues
|
92
|
+
# #=>
|
93
|
+
# #{
|
94
|
+
# # "parallel" => {
|
95
|
+
# # :queue_type => "Execution",
|
96
|
+
# # ...
|
97
|
+
# # },
|
98
|
+
# # "serial" => {
|
99
|
+
# # :queue_type => "Execution",
|
100
|
+
# # ...
|
101
|
+
# # },
|
102
|
+
# # ...
|
103
|
+
# #}
|
104
|
+
# @param id [#to_s] the id of requested information
|
105
|
+
# @param filters [Array<Symbol>] list of attribs to filter on
|
106
|
+
# @return [Hash] hash of details for the queues
|
107
|
+
def get_queues(id: '', filters: [])
|
108
|
+
connect do |cid|
|
109
|
+
filters = PBS::Torque::Attrl.from_list(filters)
|
110
|
+
batch_status = Torque.pbs_statque cid, id.to_s, filters, nil
|
111
|
+
batch_status.to_h.tap { Torque.pbs_statfree batch_status }
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Get info for given batch server's queue
|
116
|
+
# @example Status info for OSC Oakley's parallel queue
|
117
|
+
# my_conn.get_queue("parallel")
|
118
|
+
# #=>
|
119
|
+
# #{
|
120
|
+
# # "parallel" => {
|
121
|
+
# # :queue_type => "Execution",
|
122
|
+
# # ...
|
123
|
+
# # }
|
124
|
+
# #}
|
125
|
+
# @param (see @get_queues)
|
126
|
+
# @return [Hash] status info for the queue
|
127
|
+
def get_queue(id, **kwargs)
|
128
|
+
get_queues(id: id, **kwargs)
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
# Get a list of hashes of the nodes on the batch server
|
133
|
+
# @example Status info for OSC Oakley nodes
|
134
|
+
# my_conn.get_nodes
|
135
|
+
# #=>
|
136
|
+
# #{
|
137
|
+
# # "n0001" => {
|
138
|
+
# # :np => "12",
|
139
|
+
# # ...
|
140
|
+
# # },
|
141
|
+
# # "n0002" => {
|
142
|
+
# # :np => "12",
|
143
|
+
# # ...
|
144
|
+
# # },
|
145
|
+
# # ...
|
146
|
+
# #}
|
147
|
+
# @param id [#to_s] the id of requested information
|
148
|
+
# @param filters [Array<Symbol>] list of attribs to filter on
|
149
|
+
# @return [Hash] hash of details for nodes
|
150
|
+
def get_nodes(id: '', filters: [])
|
151
|
+
connect do |cid|
|
152
|
+
filters = PBS::Torque::Attrl.from_list(filters)
|
153
|
+
batch_status = Torque.pbs_statnode cid, id.to_s, filters, nil
|
154
|
+
batch_status.to_h.tap { Torque.pbs_statfree batch_status }
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Get info for given batch server's node
|
159
|
+
# @example Status info for OSC Oakley's 'n0001' node
|
160
|
+
# my_conn.get_node('n0001')
|
161
|
+
# #=>
|
162
|
+
# #{
|
163
|
+
# # "n0001" => {
|
164
|
+
# # :np => "12",
|
165
|
+
# # ...
|
166
|
+
# # }
|
167
|
+
# #}
|
168
|
+
# @param (see #get_nodes)
|
169
|
+
# @return [Hash] status info for the node
|
170
|
+
def get_node(id, **kwargs)
|
171
|
+
get_nodes(id: id, **kwargs)
|
172
|
+
end
|
173
|
+
|
174
|
+
# Get a list of hashes of the jobs on the batch server
|
175
|
+
# @example Status info for OSC Oakley jobs
|
176
|
+
# my_conn.get_jobs
|
177
|
+
# #=>
|
178
|
+
# #{
|
179
|
+
# # "10219837.oak-batch.osc.edu" => {
|
180
|
+
# # :Job_Owner => "bob@oakley02.osc.edu",
|
181
|
+
# # :Job_Name => "CFD_Solver",
|
182
|
+
# # ...
|
183
|
+
# # },
|
184
|
+
# # "10219838.oak-batch.osc.edu" => {
|
185
|
+
# # :Job_Owner => "sally@oakley01.osc.edu",
|
186
|
+
# # :Job_Name => "FEA_Solver",
|
187
|
+
# # ...
|
188
|
+
# # },
|
189
|
+
# # ...
|
190
|
+
# #}
|
191
|
+
# @param id [#to_s] the id of requested information
|
192
|
+
# @param filters [Array<Symbol>] list of attribs to filter on
|
193
|
+
# @return [Hash] hash of details for jobs
|
194
|
+
def get_jobs(id: '', filters: [])
|
195
|
+
connect do |cid|
|
196
|
+
filters = PBS::Torque::Attrl.from_list(filters)
|
197
|
+
batch_status = Torque.pbs_statjob cid, id.to_s, filters, nil
|
198
|
+
batch_status.to_h.tap { Torque.pbs_statfree batch_status }
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# Get info for given batch server's job
|
203
|
+
# @example Status info for OSC Oakley's '10219837.oak-batch.osc.edu' job
|
204
|
+
# my_conn.get_job('102719837.oak-batch.osc.edu')
|
205
|
+
# #=>
|
206
|
+
# #{
|
207
|
+
# # "10219837.oak-batch.osc.edu" => {
|
208
|
+
# # :Job_Owner => "bob@oakley02.osc.edu",
|
209
|
+
# # :Job_Name => "CFD_Solver",
|
210
|
+
# # ...
|
211
|
+
# # }
|
212
|
+
# #}
|
213
|
+
# @param (see #get_jobs)
|
214
|
+
# @return [Hash] hash with details of job
|
215
|
+
def get_job(id, **kwargs)
|
216
|
+
get_jobs(id: id, **kwargs)
|
217
|
+
end
|
218
|
+
|
219
|
+
# Put specified job on hold
|
220
|
+
# Possible hold types:
|
221
|
+
# :u => Available to the owner of the job, the batch operator and the batch administrator
|
222
|
+
# :o => Available to the batch operator and the batch administrator
|
223
|
+
# :s => Available to the batch administrator
|
224
|
+
# @example Put job '10219837.oak-batch.osc.edu' on hold
|
225
|
+
# my_conn.hold_job('10219837.oak-batch.osc.edu')
|
226
|
+
# @param id [#to_s] the id of the job
|
227
|
+
# @param type [Symbol] type of hold to be applied
|
228
|
+
# @return [void]
|
229
|
+
def hold_job(id, type: :u)
|
230
|
+
connect do |cid|
|
231
|
+
Torque.pbs_holdjob cid, id.to_s, type.to_s, nil
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
# Release a specified job that is on hold
|
236
|
+
# Possible hold types:
|
237
|
+
# :u => Available to the owner of the job, the batch operator and the batch administrator
|
238
|
+
# :o => Available to the batch operator and the batch administrator
|
239
|
+
# :s => Available to the batch administrator
|
240
|
+
# @example Release job '10219837.oak-batch.osc.edu' from hold
|
241
|
+
# my_conn.release_job('10219837.oak-batch.osc.edu')
|
242
|
+
# @param id [#to_s] the id of the job
|
243
|
+
# @param type [Symbol] type of hold to be removed
|
244
|
+
# @return [void]
|
245
|
+
def release_job(id, type: :u)
|
246
|
+
connect do |cid|
|
247
|
+
Torque.pbs_rlsjob cid, id.to_s, type.to_s, nil
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
# Delete a specified job from batch server
|
252
|
+
# @example Delete job '10219837.oak-batch.osc.edu' from batch
|
253
|
+
# my_conn.delete_job('10219837.oak-batch.osc.edu')
|
254
|
+
# @param id [#to_s] the id of the job
|
255
|
+
# @return [void]
|
256
|
+
def delete_job(id)
|
257
|
+
connect do |cid|
|
258
|
+
Torque.pbs_deljob cid, id.to_s, nil
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
# Submit a script to the batch server
|
263
|
+
# @example Submit a script with a few PBS directives
|
264
|
+
# my_conn.submit_script("/path/to/script",
|
265
|
+
# headers: {
|
266
|
+
# Job_Name: "myjob",
|
267
|
+
# Join_Path: "oe"
|
268
|
+
# },
|
269
|
+
# resources: {
|
270
|
+
# nodes: "4:ppn=12",
|
271
|
+
# walltime: "12:00:00"
|
272
|
+
# },
|
273
|
+
# envvars: {
|
274
|
+
# TOKEN: "asd90f9sd8g90hk34"
|
275
|
+
# }
|
276
|
+
# )
|
277
|
+
# #=> "6621251.oak-batch.osc.edu"
|
278
|
+
# @param script [#to_s] path to the script
|
279
|
+
# @param queue [#to_s] queue to submit script to
|
280
|
+
# @param headers [Hash] pbs headers
|
281
|
+
# @param resources [Hash] pbs resources
|
282
|
+
# @param envvars [Hash] pbs environment variables
|
283
|
+
# @param qsub [Boolean] whether use library or binary for submission
|
284
|
+
# @return [String] the id of the job that was created
|
285
|
+
def submit_script(script, queue: nil, headers: {}, resources: {}, envvars: {}, qsub: true)
|
286
|
+
send(qsub ? :qsub_submit : :pbs_submit, script, queue, headers, resources, envvars)
|
287
|
+
end
|
288
|
+
|
289
|
+
# Submit a script expanded into a string to the batch server
|
290
|
+
# @param string [#to_s] script as a string
|
291
|
+
# @param (see #submit_script)
|
292
|
+
# @return [String] the id of the job that was created
|
293
|
+
def submit_string(string, **kwargs)
|
294
|
+
Tempfile.open('qsub.') do |f|
|
295
|
+
f.write string.to_s
|
296
|
+
f.close
|
297
|
+
submit_script(f.path, **kwargs)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
private
|
302
|
+
# Submit a script using Torque library
|
303
|
+
def pbs_submit(script, queue, headers, resources, envvars)
|
304
|
+
attribs = headers.dup
|
305
|
+
attribs[ATTR[:l]] = resources.dup unless resources.empty?
|
306
|
+
attribs[ATTR[:v]] = envvars.map{|k,v| "#{k}=#{v}"}.join(",") unless envvars.empty?
|
307
|
+
|
308
|
+
connect do |cid|
|
309
|
+
attropl = Torque::Attropl.from_hash attribs
|
310
|
+
Torque.pbs_submit cid, attropl, script.to_s, queue.to_s, nil
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
# Submit a script using Torque binary
|
315
|
+
# NB: The binary includes many useful filters and is preferred
|
316
|
+
def qsub_submit(script, queue, headers, resources, envvars)
|
317
|
+
params = ["-q", "#{queue}@#{host}"]
|
318
|
+
params += resources.map{|k,v| ["-l", "#{k}=#{v}"]}.flatten unless resources.empty?
|
319
|
+
params += ["-v", envvars.map{|k,v| "#{k}=#{v}"}.join(",")] unless envvars.empty?
|
320
|
+
params += headers.map do |k,v|
|
321
|
+
if param = ATTR.key(k) and param.length == 1
|
322
|
+
["-#{param}", "#{v}"]
|
323
|
+
else
|
324
|
+
["-W", "#{k}=#{v}"]
|
325
|
+
end
|
326
|
+
end.flatten
|
327
|
+
params << script.to_s
|
328
|
+
|
329
|
+
o, e, s = Open3.capture3(prefix.join("bin", "qsub").to_s, *params)
|
330
|
+
raise PBS::Error, e unless s.success?
|
331
|
+
o.chomp
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|