3 from __future__ import absolute_import, print_function
5 class BaseComputeNodeDriver(object):
6 """Abstract base class for compute node drivers.
8 libcloud abstracts away many of the differences between cloud providers,
9 but managing compute nodes requires some cloud-specific features (e.g.,
10 on EC2 we use tags to identify compute nodes). Compute node drivers
11 are responsible for translating the node manager's cloud requests to a
12 specific cloud's vocabulary.
14 Subclasses must implement arvados_create_kwargs (to update node
15 creation kwargs with information about the specific Arvados node
16 record), sync_node, and node_start_time.
18 def __init__(self, auth_kwargs, list_kwargs, create_kwargs, driver_class):
19 self.real = driver_class(**auth_kwargs)
20 self.list_kwargs = list_kwargs
21 self.create_kwargs = create_kwargs
23 def __getattr__(self, name):
24 # Proxy non-extension methods to the real driver.
25 if (not name.startswith('_') and not name.startswith('ex_')
26 and hasattr(self.real, name)):
27 return getattr(self.real, name)
29 return super(BaseComputeNodeDriver, self).__getattr__(name)
31 def search_for(self, term, list_method, key=lambda item: item.id):
32 cache_key = (list_method, term)
33 if cache_key not in self.SEARCH_CACHE:
34 results = [item for item in getattr(self.real, list_method)()
38 raise ValueError("{} returned {} results for '{}'".format(
39 list_method, count, term))
40 self.SEARCH_CACHE[cache_key] = results[0]
41 return self.SEARCH_CACHE[cache_key]
44 return self.real.list_nodes(**self.list_kwargs)
46 def arvados_create_kwargs(self, arvados_node):
47 raise NotImplementedError("BaseComputeNodeDriver.arvados_create_kwargs")
49 def create_node(self, size, arvados_node):
50 kwargs = self.create_kwargs.copy()
51 kwargs.update(self.arvados_create_kwargs(arvados_node))
53 return self.real.create_node(**kwargs)
55 def sync_node(self, cloud_node, arvados_node):
56 # When a compute node first pings the API server, the API server
57 # will automatically assign some attributes on the corresponding
58 # node record, like hostname. This method should propagate that
59 # information back to the cloud node appropriately.
60 raise NotImplementedError("BaseComputeNodeDriver.sync_node")
63 def node_start_time(cls, node):
64 raise NotImplementedError("BaseComputeNodeDriver.node_start_time")