@@ -38,6 +38,7 @@ from pyslurm.utils.helpers import (
38
38
instance_to_dict,
39
39
_sum_prop,
40
40
nodelist_from_range_str,
41
+ nodelist_to_range_str,
41
42
)
42
43
43
44
@@ -157,10 +158,37 @@ cdef class Nodes(dict):
157
158
""" Format the information as list of Node objects.
158
159
159
160
Returns:
160
- (list): List of Node objects
161
+ (list[pyslurm.Node] ): List of Node objects
161
162
"""
162
163
return list (self .values())
163
164
165
+ def modify (self , Node changes ):
166
+ """ Modify all Nodes in a collection.
167
+
168
+ Args:
169
+ changes (pyslurm.Node):
170
+ Another Node object that contains all the changes to apply.
171
+ Check the `Other Parameters` of the Node class to see which
172
+ properties can be modified.
173
+
174
+ Raises:
175
+ RPCError: When updating the Node was not successful.
176
+
177
+ Examples:
178
+ >>> import pyslurm
179
+ >>>
180
+ >>> nodes = pyslurm.Nodes.load()
181
+ >>> # Prepare the changes
182
+ >>> changes = pyslurm.Node(state="DRAIN", reason="DRAIN Reason")
183
+ >>> # Apply the changes to all the nodes
184
+ >>> nodes.modify(changes)
185
+ """
186
+ cdef Node n = < Node> changes
187
+ node_str = nodelist_to_range_str(list (self .keys()))
188
+ n._alloc_umsg()
189
+ cstr.fmalloc(& n.umsg.node_names, node_str)
190
+ verify_rpc(slurm_update_node(n.umsg))
191
+
164
192
@property
165
193
def free_memory (self ):
166
194
return _sum_prop(self , Node.free_memory)
@@ -340,25 +368,27 @@ cdef class Node:
340
368
341
369
return self
342
370
343
- def modify (self , changes ):
371
+ def modify (self , Node changes ):
344
372
""" Modify a node.
345
373
346
374
Implements the slurm_update_node RPC.
347
375
348
376
Args:
349
377
changes (pyslurm.Node):
350
- Another Node object which contains all the changes that
351
- should be applied to this instance.
378
+ Another Node object that contains all the changes to apply.
379
+ Check the `Other Parameters` of the Node class to see which
380
+ properties can be modified.
352
381
353
382
Raises:
354
383
RPCError: When updating the Node was not successful.
355
384
356
385
Examples:
357
386
>>> import pyslurm
358
387
>>>
359
- >>> mynode = pyslurm.Node("localhost")
360
- >>> changes = pyslurm.Node(weight=100)
361
- >>> # Setting the weight to 100 for the "localhost" node
388
+ >>> mynode = pyslurm.Node.load("localhost")
389
+ >>> # Prepare the changes
390
+ >>> changes = pyslurm.Node(state="DRAIN", reason="DRAIN Reason")
391
+ >>> # Modify it
362
392
>>> mynode.modify(changes)
363
393
"""
364
394
cdef Node n = < Node> changes
@@ -448,6 +478,10 @@ cdef class Node:
448
478
def reason (self ):
449
479
return cstr.to_unicode(self .info.reason)
450
480
481
+ @reason.setter
482
+ def reason (self , val ):
483
+ cstr.fmalloc2(& self .info.reason, & self .umsg.reason, val)
484
+
451
485
@property
452
486
def reason_user (self ):
453
487
return uid_to_name(self .info.reason_uid, lookup = self .passwd)
@@ -667,6 +701,10 @@ cdef class Node:
667
701
xfree(state)
668
702
return state_str
669
703
704
+ @state.setter
705
+ def state (self , val ):
706
+ self .umsg.node_state= self .info.node_state = _node_state_from_str(val)
707
+
670
708
@property
671
709
def next_state (self ):
672
710
if ((self .info.next_state != slurm.NO_VAL)
@@ -677,10 +715,6 @@ cdef class Node:
677
715
else :
678
716
return None
679
717
680
- @state.setter
681
- def state (self , val ):
682
- self .umsg.node_state= self .info.node_state = _node_state_from_str(val)
683
-
684
718
@property
685
719
def cpu_load (self ):
686
720
load = u32_parse(self .info.cpu_load)
@@ -694,10 +728,36 @@ cdef class Node:
694
728
def _node_state_from_str (state , err_on_invalid = True ):
695
729
if not state:
696
730
return slurm.NO_VAL
697
-
698
- for i in range (slurm.NODE_STATE_END):
699
- if state == slurm_node_state_string(i):
700
- return i
731
+ ustate = state.upper()
732
+
733
+ # Following states are explicitly possible as per documentation
734
+ # https://slurm.schedmd.com/scontrol.html#OPT_State_1
735
+ if ustate == " CANCEL_REBOOT" :
736
+ return slurm.NODE_STATE_CANCEL_REBOOT
737
+ elif ustate == " DOWN" :
738
+ return slurm.NODE_STATE_DOWN
739
+ elif ustate == " DRAIN" :
740
+ return slurm.NODE_STATE_DRAIN
741
+ elif ustate == " FAIL" :
742
+ return slurm.NODE_STATE_FAIL
743
+ elif ustate == " FUTURE" :
744
+ return slurm.NODE_STATE_FUTURE
745
+ elif ustate == " NORESP" or ustate == " NO_RESP" :
746
+ return slurm.NODE_STATE_NO_RESPOND
747
+ elif ustate == " POWER_DOWN" :
748
+ return slurm.NODE_STATE_POWER_DOWN
749
+ elif ustate == " POWER_DOWN_ASAP" :
750
+ # Drain and mark for power down
751
+ return slurm.NODE_STATE_POWER_DOWN | slurm.NODE_STATE_POWER_DRAIN
752
+ elif ustate == " POWER_DOWN_FORCE" :
753
+ # Kill all Jobs and power down
754
+ return slurm.NODE_STATE_POWER_DOWN | slurm.NODE_STATE_POWERED_DOWN
755
+ elif ustate == " POWER_UP" :
756
+ return slurm.NODE_STATE_POWER_UP
757
+ elif ustate == " RESUME" :
758
+ return slurm.NODE_RESUME
759
+ elif ustate == " UNDRAIN" :
760
+ return slurm.NODE_STATE_UNDRAIN
701
761
702
762
if err_on_invalid:
703
763
raise ValueError (f" Invalid Node state: {state}" )
0 commit comments