7193: Move ex_run_command to post_create_node()
[arvados.git] / services / nodemanager / arvnodeman / computenode / driver / azure.py
1 #!/usr/bin/env python
2
3 from __future__ import absolute_import, print_function
4
5 import time
6
7 import libcloud.compute.base as cloud_base
8 import libcloud.compute.providers as cloud_provider
9 import libcloud.compute.types as cloud_types
10
11 from . import BaseComputeNodeDriver
12 from .. import arvados_node_fqdn, arvados_timestamp, ARVADOS_TIMEFMT
13
14 class ComputeNodeDriver(BaseComputeNodeDriver):
15
16     DEFAULT_DRIVER = cloud_provider.get_driver(cloud_types.Provider.AZURE_ARM)
17     SEARCH_CACHE = {}
18
19     def __init__(self, auth_kwargs, list_kwargs, create_kwargs,
20                  driver_class=DEFAULT_DRIVER):
21
22         if not list_kwargs.get("ex_resource_group"):
23             raise Exception("Must include ex_resource_group in Cloud List configuration (list_kwargs)")
24
25         create_kwargs["ex_resource_group"] = list_kwargs["ex_resource_group"]
26
27         self.tags = {key[4:]: value
28                      for key, value in create_kwargs.iteritems()
29                      if key.startswith('tag_')}
30         # filter out tags from create_kwargs
31         create_kwargs = {key: value
32                          for key, value in create_kwargs.iteritems()
33                          if not key.startswith('tag_')}
34         super(ComputeNodeDriver, self).__init__(
35             auth_kwargs, list_kwargs, create_kwargs,
36             driver_class)
37
38     def arvados_create_kwargs(self, arvados_node):
39         cluster_id, _, node_id = arvados_node['uuid'].split('-')
40         name = 'compute-{}-{}'.format(node_id, cluster_id)
41         tags = {
42             'booted_at': time.strftime(ARVADOS_TIMEFMT, time.gmtime()),
43             'arv-ping-url': self._make_ping_url(arvados_node)
44         }
45         tags.update(self.tags)
46         return {
47             'name': name,
48             'ex_tags': tags,
49         }
50
51     def sync_node(self, cloud_node, arvados_node):
52         self.real.ex_create_tags(cloud_node,
53                                  {'hostname': arvados_node_fqdn(arvados_node)})
54
55     def _init_image(self, urn):
56         return "image", self.get_image(urn)
57
58     def post_create_node(self, cloud_node):
59         self.real.ex_run_command(cloud_node,
60                                  """bash -c '
61                                  mkdir -p /var/tmp/arv-node-data/meta-data
62                                  echo "%s" > /var/tmp/arv-node-data/arv-ping-url
63                                  echo "%s" > /var/tmp/arv-node-data/meta-data/instance-id
64                                  echo "%s" > /var/tmp/arv-node-data/meta-data/instance-type
65                                  echo "%s" > /var/tmp/arv-node-data/meta-data/local-ipv4
66                                  '""" % (self._make_ping_url(arvados_node),
67                                          cloud_node.id,
68                                          cloud_node.extra["properties"]["hardwareProfile"]["vmSize"],
69                                          cloud_node.private_ips[0]),
70                                  timestamp=int(time.time()))
71
72     def list_nodes(self):
73         # Azure only supports filtering node lists by resource group.
74         # Do our own filtering based on tag.
75         return [node for node in
76                 super(ComputeNodeDriver, self).list_nodes()
77                 if node.extra["tags"].get("arvados-class") == self.tags["arvados-class"]]
78
79     @classmethod
80     def node_fqdn(cls, node):
81         return node.extra["tags"].get("hostname")
82
83     @classmethod
84     def node_start_time(cls, node):
85         return arvados_timestamp(node.extra["tags"].get("booted_at"))