2 # Copyright (C) The Arvados Authors. All rights reserved.
4 # SPDX-License-Identifier: AGPL-3.0
6 from __future__ import absolute_import, print_function
8 import subprocess32 as subprocess
10 from . import clientactor
15 class ArvadosNodeListMonitorActor(clientactor.RemotePollLoopActor):
16 """Actor to poll the Arvados node list.
18 This actor regularly polls the list of Arvados node records,
19 augments it with the latest SLURM node info (`sinfo`), and sends
23 def is_common_error(self, exception):
24 return isinstance(exception, config.ARVADOS_ERRORS)
26 def _item_key(self, node):
29 def _send_request(self):
30 nodelist = arvados.util.list_all(self._client.nodes().list)
32 # node hostname, state
33 sinfo_out = subprocess.check_output(["sinfo", "--noheader", "--format=%n|%t|%f"])
36 for out in sinfo_out.splitlines():
38 nodename, state, features = out.split("|", 3)
41 if state in ('alloc', 'alloc*',
45 nodestates[nodename] = 'busy'
46 elif state in ('idle', 'fail'):
47 nodestates[nodename] = state
49 nodestates[nodename] = 'down'
50 if features != "(null)":
51 nodefeatures[nodename] = features
54 if n["slot_number"] and n["hostname"] and n["hostname"] in nodestates:
55 n["crunch_worker_state"] = nodestates[n["hostname"]]
57 n["crunch_worker_state"] = 'down'
58 n["slurm_node_features"] = nodefeatures.get(n["hostname"], "")
62 class CloudNodeListMonitorActor(clientactor.RemotePollLoopActor):
63 """Actor to poll the cloud node list.
65 This actor regularly polls the cloud to get a list of running compute
66 nodes, and sends it to subscribers.
69 def __init__(self, client, timer_actor, server_calc, *args, **kwargs):
70 super(CloudNodeListMonitorActor, self).__init__(
71 client, timer_actor, *args, **kwargs)
72 self._calculator = server_calc
74 def is_common_error(self, exception):
75 return isinstance(exception, config.CLOUD_ERRORS)
77 def _item_key(self, node):
80 def _send_request(self):
81 nodes = self._client.list_nodes()
83 # Replace the libcloud NodeSize object with compatible
84 # CloudSizeWrapper object which merges the size info reported from
85 # the cloud with size information from the configuration file.
86 n.size = self._calculator.find_size(n.extra['arvados_node_size'])