1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
10 from arvnodeman.computenode import ARVADOS_TIMEFMT
12 from libcloud.compute.base import NodeSize, Node, NodeDriver, NodeState, NodeImage
13 from libcloud.compute.drivers.gce import GCEDiskType
14 from libcloud.common.exceptions import BaseHTTPError, RateLimitReachedError
20 class FakeDriver(NodeDriver):
21 def __init__(self, *args, **kwargs):
22 self.name = "FakeDriver"
24 def list_sizes(self, **kwargs):
25 return [NodeSize("Standard_D3", "Standard_D3", 3500, 200, 0, 0, self),
26 NodeSize("Standard_D4", "Standard_D4", 7000, 400, 0, 0, self)]
28 def list_nodes(self, **kwargs):
31 def create_node(self, name=None,
35 ex_storage_account=None,
37 ex_resource_group=None,
43 global all_nodes, create_calls
45 nodeid = "node%i" % create_calls
48 ex_tags.update({'arvados_node_size': size.id})
49 n = Node(nodeid, nodeid, NodeState.RUNNING, [], [], self, size=size, extra={"tags": ex_tags})
52 ping_url = re.search(r"echo '(.*)' > /var/tmp/arv-node-data/arv-ping-url", ex_customdata).groups(1)[0]
54 ping_url = ex_userdata
56 ping_url = ex_metadata["arv-ping-url"]
57 ping_url += "&instance_id=" + nodeid
58 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
59 ctx.verify_mode = ssl.CERT_NONE
60 f = urllib.urlopen(ping_url, "", context=ctx)
64 def destroy_node(self, cloud_node):
66 all_nodes = [n for n in all_nodes if n.id != cloud_node.id]
69 def get_image(self, img):
72 def ex_create_tags(self, cloud_node, tags):
75 class QuotaDriver(FakeDriver):
76 def create_node(self, name=None,
80 ex_storage_account=None,
82 ex_resource_group=None,
86 global all_nodes, create_calls, quota
87 if len(all_nodes) >= quota:
88 raise BaseHTTPError(503, "Quota exceeded")
90 return super(QuotaDriver, self).create_node(name=name,
94 ex_storage_account=ex_storage_account,
95 ex_customdata=ex_customdata,
96 ex_resource_group=ex_resource_group,
97 ex_user_name=ex_user_name,
99 ex_network=ex_network)
101 def destroy_node(self, cloud_node):
102 global all_nodes, quota
103 all_nodes = [n for n in all_nodes if n.id != cloud_node.id]
104 if len(all_nodes) == 0:
108 class FailingDriver(FakeDriver):
109 def create_node(self, name=None,
113 ex_storage_account=None,
115 ex_resource_group=None,
119 raise Exception("nope")
121 class RetryDriver(FakeDriver):
122 def create_node(self, name=None,
126 ex_storage_account=None,
128 ex_resource_group=None,
135 raise RateLimitReachedError(429, "Rate limit exceeded",
136 headers={'retry-after': '2'})
137 elif create_calls < 3:
138 raise BaseHTTPError(429, "Rate limit exceeded",
139 {'retry-after': '1'})
141 return super(RetryDriver, self).create_node(name=name,
145 ex_storage_account=ex_storage_account,
146 ex_customdata=ex_customdata,
147 ex_resource_group=ex_resource_group,
148 ex_user_name=ex_user_name,
150 ex_network=ex_network)
152 class FakeAwsDriver(FakeDriver):
154 def create_node(self, name=None,
160 ex_blockdevicemappings=None):
161 n = super(FakeAwsDriver, self).create_node(name=name,
165 ex_metadata=ex_metadata,
166 ex_userdata=ex_userdata)
168 "launch_time": time.strftime(ARVADOS_TIMEFMT, time.gmtime())[:-1],
170 "arvados_node_size": size.id
175 def list_sizes(self, **kwargs):
176 return [NodeSize("m3.xlarge", "Extra Large Instance", 3500, 80, 0, 0, self),
177 NodeSize("m4.xlarge", "Extra Large Instance", 3500, 0, 0, 0, self),
178 NodeSize("m4.2xlarge", "Double Extra Large Instance", 7000, 0, 0, 0, self)]
181 class FakeGceDriver(FakeDriver):
183 def create_node(self, name=None,
190 ex_disks_gce_struct=None):
191 n = super(FakeGceDriver, self).create_node(name=name,
195 ex_metadata=ex_metadata)
198 "items": [{"key": k, "value": v} for k,v in ex_metadata.iteritems()],
199 "arvados_node_size": size.id
205 def list_images(self, ex_project=None):
206 return [NodeImage("fake_image_id", "fake_image_id", self)]
208 def list_sizes(self, **kwargs):
209 return [NodeSize("n1-standard-1", "Standard", 3750, None, 0, 0, self),
210 NodeSize("n1-standard-2", "Double standard", 7500, None, 0, 0, self)]
212 def ex_list_disktypes(self, zone=None):
213 return [GCEDiskType("pd-standard", "pd-standard", zone, self,
214 extra={"selfLink": "pd-standard"}),
215 GCEDiskType("local-ssd", "local-ssd", zone, self,
216 extra={"selfLink": "local-ssd"})]
218 def ex_get_node(self, name, zone=None):
225 def ex_set_node_metadata(self, n, items):
226 n.extra["metadata"]["items"] = items