Skip to content

Commit a05fe76

Browse files
committed
Backport: Few fixes and handle modification consistently (#300)
- handle modification of objects via `modify()` consistently - use correct list of node states when modifying the node state - remove `consumable_resource` attribute of Partition class again, logic is merged into the `select_type_parameters` attribute
1 parent cd3742f commit a05fe76

File tree

10 files changed

+107
-70
lines changed

10 files changed

+107
-70
lines changed

docs/reference/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ The `pyslurm` package is a wrapper around the Slurm C-API
4141
* Node API
4242
* [pyslurm.Node][]
4343
* [pyslurm.Nodes][]
44+
* Partition API
45+
* [pyslurm.Partition][]
46+
* [pyslurm.Partitions][]
4447
* New Exceptions
4548
* [pyslurm.RPCError][]
4649
* [pyslurm.PyslurmError][]

pyslurm/core/job/job.pyx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ cdef class Jobs(dict):
9292
9393
Raises:
9494
RPCError: When getting all the Jobs from the slurmctld failed.
95-
MemoryError: If malloc fails to allocate memory.
9695
"""
9796
cdef:
9897
dict passwd = {}
@@ -188,7 +187,7 @@ cdef class Jobs(dict):
188187
"""Format the information as list of Job objects.
189188
190189
Returns:
191-
(list): List of Job objects
190+
(list[pyslurm.Job]): List of Job objects
192191
"""
193192
return list(self.values())
194193

@@ -258,7 +257,6 @@ cdef class Job:
258257
Raises:
259258
RPCError: If requesting the Job information from the slurmctld was
260259
not successful.
261-
MemoryError: If malloc failed to allocate memory.
262260
263261
Examples:
264262
>>> import pyslurm

pyslurm/core/job/step.pyx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,15 +279,17 @@ cdef class JobStep:
279279
step_id = self.ptr.step_id.step_id
280280
verify_rpc(slurm_kill_job_step(self.job_id, step_id, 9))
281281

282-
def modify(self, changes):
282+
def modify(self, JobStep changes):
283283
"""Modify a job step.
284284
285285
Implements the slurm_update_step RPC.
286286
287287
Args:
288288
changes (pyslurm.JobStep):
289-
Another JobStep object which contains all the changes that
290-
should be applied to this instance.
289+
Another JobStep object that contains all the changes to apply.
290+
Check the `Other Parameters` of the JobStep class to see which
291+
properties can be modified.
292+
291293
Raises:
292294
RPCError: When updating the JobStep was not successful.
293295

pyslurm/core/node.pxd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ cdef class Node:
117117
Default CPU-Binding for the node
118118
state (str):
119119
State of the node
120+
reason (str):
121+
Reason for the Node, typically used along with updating the node
122+
state
120123
121124
Attributes:
122125
name (str):

pyslurm/core/partition.pxd

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ cdef class Partition:
101101
* total_cpus
102102
* total_nodes
103103
* select_type_parameters
104-
* consumable_resource
105104
106105
Attributes:
107106
name (str):
@@ -116,10 +115,8 @@ cdef class Partition:
116115
List of QoS which are allowed to execute Jobs
117116
alternate (str):
118117
Name of the alternate Partition in case a Partition is down.
119-
consumable_resource (str):
120-
The type of consumable resource used in the Partition.
121118
select_type_parameters (list[str]):
122-
List of additional parameters passed to the select plugin used.
119+
List of Select type parameters for the select plugin.
123120
cpu_binding (str):
124121
Default CPU-binding for Jobs that execute in a Partition.
125122
default_memory_per_cpu (int):

pyslurm/core/partition.pyx

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -143,18 +143,29 @@ cdef class Partitions(dict):
143143

144144
return self
145145

146-
def set_state(self, state):
147-
"""Modify the State of all Partitions in this Collection.
146+
def modify(self, changes):
147+
"""Modify all Partitions in a Collection.
148148
149149
Args:
150-
state (str):
151-
Partition state to set
150+
changes (pyslurm.Partition):
151+
Another Partition object that contains all the changes to
152+
apply. Check the `Other Parameters` of the Partition class to
153+
see which properties can be modified.
152154
153155
Raises:
154-
RPCError: When updating the state failed
156+
RPCError: When updating at least one Partition failed.
157+
158+
Examples:
159+
>>> import pyslurm
160+
>>>
161+
>>> parts = pyslurm.Partitions.load()
162+
>>> # Prepare the changes
163+
>>> changes = pyslurm.Partition(state="DRAIN")
164+
>>> # Apply the changes to all the partitions
165+
>>> parts.modify(changes)
155166
"""
156167
for part in self.values():
157-
part.modify(state=state)
168+
part.modify(changes)
158169

159170
def as_list(self):
160171
"""Format the information as list of Partition objects.
@@ -270,40 +281,30 @@ cdef class Partition:
270281
verify_rpc(slurm_create_partition(self.ptr))
271282
return self
272283

273-
def modify(self, **changes):
284+
def modify(self, Partition changes):
274285
"""Modify a Partition.
275286
276287
Implements the slurm_update_partition RPC.
277288
278289
Args:
279-
**changes (Any):
280-
Changes for the Partition. Almost every Attribute from a
281-
Partition can be modified, except for:
282-
283-
* total_cpus
284-
* total_nodes
285-
* select_type_parameters
286-
* consumable_resource
290+
changes (pyslurm.Partition):
291+
Another Partition object that contains all the changes to
292+
apply. Check the `Other Parameters` of the Partition class to
293+
see which properties can be modified.
287294
288295
Raises:
289-
ValueError: When no changes were specified or when a parsing error
290-
occured.
291296
RPCError: When updating the Partition was not successful.
292297
293298
Examples:
294299
>>> import pyslurm
295300
>>>
296-
>>> # Modifying the maximum time limit
297-
>>> mypart = pyslurm.Partition("normal")
298-
>>> mypart.modify(max_time_limit="10-00:00:00")
299-
>>>
300-
>>> # Modifying the partition state
301-
>>> mypart.modify(state="DRAIN")
301+
>>> part = pyslurm.Partition.load("normal")
302+
>>> # Prepare the changes
303+
>>> changes = pyslurm.Partition(state="DRAIN")
304+
>>> # Apply the changes to the "normal" Partition
305+
>>> part.modify(changes)
302306
"""
303-
if not changes:
304-
raise ValueError("No changes were specified")
305-
306-
cdef Partition part = Partition(**changes)
307+
cdef Partition part = <Partition>changes
307308
part.name = self._error_or_name()
308309
verify_rpc(slurm_update_partition(part.ptr))
309310

@@ -381,10 +382,6 @@ cdef class Partition:
381382
def alternate(self, val):
382383
cstr.fmalloc(&self.ptr.alternate, val)
383384

384-
@property
385-
def consumable_resource(self):
386-
return _select_type_int_to_cons_res(self.ptr.cr_type)
387-
388385
@property
389386
def select_type_parameters(self):
390387
return _select_type_int_to_list(self.ptr.cr_type)
@@ -757,7 +754,7 @@ def _split_oversubscribe_str(val):
757754
def _select_type_int_to_list(stype):
758755
# The rest of the CR_* stuff are just some extra parameters to the select
759756
# plugin
760-
out = []
757+
out = _select_type_int_to_cons_res(stype)
761758

762759
if stype & slurm.CR_OTHER_CONS_RES:
763760
out.append("OTHER_CONS_RES")
@@ -800,7 +797,7 @@ def _select_type_int_to_cons_res(stype):
800797
elif stype & slurm.CR_MEMORY:
801798
return "MEMORY"
802799
else:
803-
return None
800+
return []
804801

805802

806803
def _preempt_mode_str_to_int(mode):

pyslurm/db/job.pyx

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -282,14 +282,19 @@ cdef class Jobs(dict):
282282
return jobs
283283

284284
@staticmethod
285-
def modify(search_filter, db_connection=None, **changes):
285+
def modify(search_filter, Job changes, db_connection=None):
286286
"""Modify Slurm database Jobs.
287287
288288
Implements the slurm_job_modify RPC.
289289
290290
Args:
291291
search_filter (Union[pyslurm.db.JobSearchFilter, pyslurm.db.Jobs]):
292292
A filter to decide which Jobs should be modified.
293+
changes (pyslurm.db.Job):
294+
Another [pyslurm.db.Job][] object that contains all the
295+
changes to apply. Check the `Other Parameters` of the
296+
[pyslurm.db.Job][] class to see which properties can be
297+
modified.
293298
db_connection (pyslurm.db.Connection):
294299
A Connection to the slurmdbd. By default, if no connection is
295300
supplied, one will automatically be created internally. This
@@ -306,25 +311,21 @@ cdef class Jobs(dict):
306311
be committed or rolled back by using the respective methods on
307312
the connection object. This way, you have a chance to see
308313
which Jobs were modified before you commit the changes.
309-
**changes (Any):
310-
Check the `Other Parameters` Section of [pyslurm.db.Job][] to
311-
see what attributes can be modified.
312314
313315
Returns:
314316
(list[int]): A list of Jobs that were modified
315317
316318
Raises:
317-
ValueError: When a parsing error occured or the Database
318-
connection is not open
319319
RPCError: When a failure modifying the Jobs occurred.
320320
321321
Examples:
322322
In its simplest form, you can do something like this:
323323
324324
>>> import pyslurm
325+
>>>
325326
>>> search_filter = pyslurm.db.JobSearchFilter(ids=[9999])
326-
>>> modified_jobs = pyslurm.db.Jobs.modify(
327-
... search_filter, comment="A comment for the job")
327+
>>> changes = pyslurm.db.Job(comment="A comment for the job")
328+
>>> modified_jobs = pyslurm.db.Jobs.modify(search_filter, changes)
328329
>>> print(modified_jobs)
329330
>>> [9999]
330331
@@ -334,11 +335,13 @@ cdef class Jobs(dict):
334335
connection object:
335336
336337
>>> import pyslurm
337-
>>> search_filter = pyslurm.db.JobSearchFilter(ids=[9999])
338+
>>>
338339
>>> db_conn = pyslurm.db.Connection.open()
340+
>>> search_filter = pyslurm.db.JobSearchFilter(ids=[9999])
341+
>>> changes = pyslurm.db.Job(comment="A comment for the job")
339342
>>> modified_jobs = pyslurm.db.Jobs.modify(
340-
... search_filter, db_conn,
341-
... comment="A comment for the job")
343+
... search_filter, changes, db_conn)
344+
>>>
342345
>>> # Now you can first examine which Jobs have been modified
343346
>>> print(modified_jobs)
344347
>>> [9999]
@@ -348,7 +351,7 @@ cdef class Jobs(dict):
348351
"""
349352

350353
cdef:
351-
Job job = Job(**changes)
354+
Job job = <Job>changes
352355
JobSearchFilter jfilter
353356
Connection conn = <Connection>db_connection
354357
SlurmList response
@@ -499,23 +502,25 @@ cdef class Job:
499502

500503
return out
501504

502-
def modify(self, db_connection=None, **changes):
505+
def modify(self, changes, db_connection=None):
503506
"""Modify a Slurm database Job.
504507
505508
Args:
509+
changes (pyslurm.db.Job):
510+
Another [pyslurm.db.Job][] object that contains all the
511+
changes to apply. Check the `Other Parameters` of the
512+
[pyslurm.db.Job][] class to see which properties can be
513+
modified.
506514
db_connection (pyslurm.db.Connection):
507515
A slurmdbd connection. See
508516
[pyslurm.db.Jobs.modify][pyslurm.db.job.Jobs.modify] for more
509-
info
510-
**changes (Any):
511-
Check the `Other Parameters` Section of this class to see what
512-
attributes can be modified.
517+
info on this parameter.
513518
514519
Raises:
515520
RPCError: When modifying the Job failed.
516521
"""
517522
cdef JobSearchFilter jfilter = JobSearchFilter(ids=[self.id])
518-
Jobs.modify(jfilter, db_connection, **changes)
523+
Jobs.modify(jfilter, changes, db_connection)
519524

520525
@property
521526
def account(self):

tests/integration/test_db_job.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ def test_modify(submit_job):
6060
util.wait(5)
6161

6262
jfilter = pyslurm.db.JobSearchFilter(ids=[job.id])
63-
pyslurm.db.Jobs.modify(jfilter, comment="test comment")
63+
changes = pyslurm.db.Job(comment="test comment")
64+
pyslurm.db.Jobs.modify(jfilter, changes)
6465

6566
job = pyslurm.db.Job.load(job.id)
6667
assert job.comment == "test comment"
@@ -72,7 +73,8 @@ def test_modify_with_existing_conn(submit_job):
7273

7374
conn = pyslurm.db.Connection.open()
7475
jfilter = pyslurm.db.JobSearchFilter(ids=[job.id])
75-
pyslurm.db.Jobs.modify(jfilter, conn, comment="test comment")
76+
changes = pyslurm.db.Job(comment="test comment")
77+
pyslurm.db.Jobs.modify(jfilter, changes, conn)
7678

7779
job = pyslurm.db.Job.load(job.id)
7880
assert job.comment != "test comment"

tests/integration/test_partition.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,19 @@ def test_create_delete():
5151
def test_modify():
5252
part = Partitions.load().as_list()[0]
5353

54-
part.modify(default_time=120)
54+
part.modify(Partition(default_time=120))
5555
assert Partition.load(part.name).default_time == 120
5656

57-
part.modify(default_time="1-00:00:00")
57+
part.modify(Partition(default_time="1-00:00:00"))
5858
assert Partition.load(part.name).default_time == 24*60
5959

60-
part.modify(default_time="UNLIMITED")
60+
part.modify(Partition(default_time="UNLIMITED"))
6161
assert Partition.load(part.name).default_time == "UNLIMITED"
6262

63-
part.modify(state="DRAIN")
63+
part.modify(Partition(state="DRAIN"))
6464
assert Partition.load(part.name).state == "DRAIN"
6565

66-
part.modify(state="UP")
66+
part.modify(Partition(state="UP"))
6767
assert Partition.load(part.name).state == "UP"
6868

6969

0 commit comments

Comments
 (0)