3 from __future__ import absolute_import, print_function
9 ComputeNodeSetupActor, ComputeNodeUpdateActor, ComputeNodeMonitorActor
10 from . import ComputeNodeShutdownActor as ShutdownActorBase
12 class ComputeNodeShutdownActor(ShutdownActorBase):
13 SLURM_END_STATES = frozenset(['down\n', 'down*\n', 'drain\n', 'fail\n'])
16 arv_node = self._monitor.arvados_node.get()
18 return super(ComputeNodeShutdownActor, self).on_start()
20 self._nodename = arv_node['hostname']
21 self._logger.info("Draining SLURM node %s", self._nodename)
22 self._later.issue_slurm_drain()
24 def _set_node_state(self, state, *args):
25 cmd = ['scontrol', 'update', 'NodeName=' + self._nodename,
28 subprocess.check_output(cmd)
30 @ShutdownActorBase._retry((subprocess.CalledProcessError,))
31 def cancel_shutdown(self):
32 self._set_node_state('RESUME')
33 return super(ComputeNodeShutdownActor, self).cancel_shutdown()
35 @ShutdownActorBase._stop_if_window_closed
36 @ShutdownActorBase._retry((subprocess.CalledProcessError,))
37 def issue_slurm_drain(self):
38 self._set_node_state('DRAIN', 'Reason=Node Manager shutdown')
39 self._logger.info("Waiting for SLURM node %s to drain", self._nodename)
40 self._later.await_slurm_drain()
42 @ShutdownActorBase._stop_if_window_closed
43 @ShutdownActorBase._retry((subprocess.CalledProcessError,))
44 def await_slurm_drain(self):
45 output = subprocess.check_output(
46 ['sinfo', '--noheader', '-o', '%t', '-n', self._nodename])
47 if output in self.SLURM_END_STATES:
48 self._later.shutdown_node()
50 self._timer.schedule(time.time() + 10,
51 self._later.await_slurm_drain)