8784: Fix test for latest firefox.
[arvados.git] / services / nodemanager / arvnodeman / nodelist.py
1 #!/usr/bin/env python
2
3 from __future__ import absolute_import, print_function
4
5 import subprocess
6
7 from . import clientactor
8 from . import config
9
10 import arvados.util
11
12 class ArvadosNodeListMonitorActor(clientactor.RemotePollLoopActor):
13     """Actor to poll the Arvados node list.
14
15     This actor regularly polls the list of Arvados node records, and
16     sends it to subscribers.
17     """
18
19     def is_common_error(self, exception):
20         return isinstance(exception, config.ARVADOS_ERRORS)
21
22     def _item_key(self, node):
23         return node['uuid']
24
25     def _send_request(self):
26         nodelist = arvados.util.list_all(self._client.nodes().list)
27
28         # node hostname, state
29         sinfo_out = subprocess.check_output(["sinfo", "--noheader", "--format=%n %t"])
30         nodestates = {}
31         for out in sinfo_out.splitlines():
32             try:
33                 nodename, state = out.split(" ", 2)
34                 if state in ('alloc', 'alloc*',
35                              'comp',  'comp*',
36                              'mix',   'mix*',
37                              'drng',  'drng*'):
38                     nodestates[nodename] = 'busy'
39                 elif state == 'idle':
40                     nodestates[nodename] = 'idle'
41                 else:
42                     nodestates[nodename] = 'down'
43             except ValueError:
44                 pass
45
46         for n in nodelist:
47             if n["slot_number"] and n["hostname"] and n["hostname"] in nodestates:
48                 n["crunch_worker_state"] = nodestates[n["hostname"]]
49             else:
50                 n["crunch_worker_state"] = 'down'
51
52         return nodelist
53
54 class CloudNodeListMonitorActor(clientactor.RemotePollLoopActor):
55     """Actor to poll the cloud node list.
56
57     This actor regularly polls the cloud to get a list of running compute
58     nodes, and sends it to subscribers.
59     """
60
61     def __init__(self, client, timer_actor, server_calc, *args, **kwargs):
62         super(CloudNodeListMonitorActor, self).__init__(
63             client, timer_actor, *args, **kwargs)
64         self._calculator = server_calc
65
66     def is_common_error(self, exception):
67         return self._client.is_cloud_exception(exception)
68
69     def _item_key(self, node):
70         return node.id
71
72     def _send_request(self):
73         nodes = self._client.list_nodes()
74         for n in nodes:
75             # Replace with libcloud NodeSize object with compatible
76             # CloudSizeWrapper object which merges the size info reported from
77             # the cloud with size information from the configuration file.
78             n.size = self._calculator.find_size(n.size.id)
79         return nodes