12055: On EC2 driver, pass the tag list to the node_create call
[arvados.git] / services / nodemanager / arvnodeman / computenode / driver / ec2.py
index 991a2983c7217f1a29368293513587d117d01d59..846aa6c2118b9455ad078dc19532d27eb970768c 100644 (file)
@@ -1,4 +1,7 @@
 #!/usr/bin/env python
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
 
 from __future__ import absolute_import, print_function
 
@@ -49,6 +52,10 @@ class ComputeNodeDriver(BaseComputeNodeDriver):
         self.tags = {key[4:]: value
                      for key, value in list_kwargs.iteritems()
                      if key.startswith('tag:')}
+        # Tags are assigned at instance creation time
+        if not 'ex_metadata' in create_kwargs:
+            create_kwargs['ex_metadata'] = {}
+        create_kwargs['ex_metadata'].update(self.tags)
         super(ComputeNodeDriver, self).__init__(
             auth_kwargs, {'ex_filters': list_kwargs}, create_kwargs,
             driver_class)
@@ -64,12 +71,28 @@ class ComputeNodeDriver(BaseComputeNodeDriver):
     def _init_subnet_id(self, subnet_id):
         return 'ex_subnet', self.search_for(subnet_id, 'ex_list_subnets')
 
+    create_cloud_name = staticmethod(arvados_node_fqdn)
+
     def arvados_create_kwargs(self, size, arvados_node):
-        return {'name': arvados_node_fqdn(arvados_node),
+        kw = {'name': self.create_cloud_name(arvados_node),
                 'ex_userdata': self._make_ping_url(arvados_node)}
-
-    def post_create_node(self, cloud_node):
-        self.real.ex_create_tags(cloud_node, self.tags)
+        # libcloud/ec2 disk sizes are in GB, Arvados/SLURM "scratch" value is in MB
+        scratch = int(size.scratch / 1000) + 1
+        if scratch > size.disk:
+            volsize = scratch - size.disk
+            if volsize > 16384:
+                # Must be 1-16384 for General Purpose SSD (gp2) devices
+                # https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_EbsBlockDevice.html
+                self._logger.warning("Requested EBS volume size %d is too large, capping size request to 16384 GB", volsize)
+                volsize = 16384
+            kw["ex_blockdevicemappings"] = [{
+                "DeviceName": "/dev/xvdt",
+                "Ebs": {
+                    "DeleteOnTermination": True,
+                    "VolumeSize": volsize,
+                    "VolumeType": "gp2"
+                }}]
+        return kw
 
     def sync_node(self, cloud_node, arvados_node):
         self.real.ex_create_tags(cloud_node,
@@ -92,3 +115,7 @@ class ComputeNodeDriver(BaseComputeNodeDriver):
         time_str = node.extra['launch_time'].split('.', 2)[0] + 'UTC'
         return time.mktime(time.strptime(
                 time_str,'%Y-%m-%dT%H:%M:%S%Z')) - time.timezone
+
+    @classmethod
+    def node_id(cls, node):
+        return node.id