diff --git a/api/code/src/main/python/stratuslab/CloudInfo.py b/api/code/src/main/python/stratuslab/CloudInfo.py index 64acef8c..29ff511a 100644 --- a/api/code/src/main/python/stratuslab/CloudInfo.py +++ b/api/code/src/main/python/stratuslab/CloudInfo.py @@ -35,9 +35,17 @@ def _populate(self, element, parentHierachy=[]): for child in children: self._populate(child, _parentHierachy) else: - # skip the root element - hierachy = parentHierachy[1:] + [element.tag] - attributeName = '_'.join(hierachy) + # root element is not included + if parentHierachy[-1].tag == 'DISK': + try: + disk_id = parentHierachy[-1].find('DISK_ID').text + except Exception: + disk_id = 'X' + hierachy = [e.tag for e in parentHierachy[1:]] + [disk_id, element.tag] + attributeName = '_'.join(hierachy) + else: + hierachy = parentHierachy[1:] + [element] + attributeName = '_'.join([e.tag for e in hierachy]) if isinstance(element.text, unicode): text = element.text.encode('utf-8') else: @@ -50,7 +58,7 @@ def _getChildren(self, parent): def _updateHierachy(self, element, parentHierachy): _parentHierachy = parentHierachy[:] - _parentHierachy.append(element.tag) + _parentHierachy.append(element) return _parentHierachy def getAttributes(self): diff --git a/api/code/src/main/python/stratuslab/image/Image.py b/api/code/src/main/python/stratuslab/image/Image.py index 925c8f4f..c1fb597f 100644 --- a/api/code/src/main/python/stratuslab/image/Image.py +++ b/api/code/src/main/python/stratuslab/image/Image.py @@ -68,6 +68,9 @@ def getImageDisksBusTypeByImageId(self, imageId): def getInboundPortsByImageId(self, imageId): return self._getImageElementValue('inboundports', imageId) + def get_image_size_by_image_id(self, image_id): + return self._getImageElementValue('bytes', image_id) + def _getImageElementValue(self, element, imageId): if Image.isImageId(imageId): return self.manifestDownloader.getImageElementValue(element, imageId) diff --git a/api/code/src/main/python/stratuslab/vm_manager/Runner.py b/api/code/src/main/python/stratuslab/vm_manager/Runner.py index 80cd7723..38b535b5 100644 --- a/api/code/src/main/python/stratuslab/vm_manager/Runner.py +++ b/api/code/src/main/python/stratuslab/vm_manager/Runner.py @@ -113,6 +113,7 @@ def __init__(self, image, configHolder): self._setCloudContext() self.createImageData = {self.CREATE_IMAGE_KEY_CREATOR_EMAIL: self.authorEmail, self.CREATE_IMAGE_KEY_NEWIMAGE_MARKETPLACE: self.marketplaceEndpointNewimage} + self._image = None self._initVmAttributes() self.instancesDetail = [] self.availableInstanceTypes = self._getAvailableInstanceTypes() @@ -146,6 +147,10 @@ def _initVmAttributes(self): self._initVmAttributesStatic() + if not self._image: + self._image = Image(self.configHolder) + + self._set_root_disk_size_entry() self._setMsgRecipients() self._setUserKeyIfDefined() self._setSaveDisk() @@ -177,6 +182,13 @@ def _initVmAttributesStatic(self): self.diskImageFormat = None self.disk_driver = None self.inbound_ports = '' + self.root_disk_size_entry = '' + + def _set_root_disk_size_entry(self): + if self.vm_image: + size_bytes = int(self._image.get_image_size_by_image_id(self.vm_image)) + size_MB = size_bytes / 1024 ** 2 + self.root_disk_size_entry = 'size = %s,' % size_MB def _setMsgRecipients(self): try: @@ -189,8 +201,7 @@ def _setDiskImageFormat(self): # if image ID was provided extract disk driver type from manifest if self.vm_image: if not useQcowDiskFormat and Image.isImageId(self.vm_image): - image = Image(self.configHolder) - self.disk_driver = image.getImageFormatByImageId(self.vm_image) + self.disk_driver = self._image.getImageFormatByImageId(self.vm_image) return self.disk_driver = (useQcowDiskFormat and 'qcow2') or 'raw' @@ -199,8 +210,7 @@ def _setDisksBusType(self): disks_bus = self.vmDisksBus else: if Image.isImageId(self.vm_image): - image = Image(self.configHolder) - disks_bus = image.getImageDisksBusTypeByImageId(self.vm_image) + disks_bus = self._image.getImageDisksBusTypeByImageId(self.vm_image) else: return @@ -261,9 +271,8 @@ def _setReadonlyDiskOptional(self): def _setInboundPorts(self): if Image.isImageId(self.vm_image): - image = Image(self.configHolder) try: - self.inboundPorts = image.getInboundPortsByImageId(self.vm_image) + self.inboundPorts = self._image.getInboundPortsByImageId(self.vm_image) except Exceptions.ExecutionException: pass @@ -637,8 +646,9 @@ def _checkImageExists(self, imageId): if self.noCheckImageUrl: printWarning('Image availability check is disabled.') return - imageObject = Image(self.configHolder) - imageObject.checkImageExists(imageId) + if not self._image: + self._image = Image(self.configHolder) + self._image.checkImageExists(imageId) def _prependMarketplaceUrlIfImageId(self, image): if Image.isImageId(image): diff --git a/api/code/src/main/resources/share/vm/schema.one b/api/code/src/main/resources/share/vm/schema.one index db6ee84d..bf731cf8 100644 --- a/api/code/src/main/resources/share/vm/schema.one +++ b/api/code/src/main/resources/share/vm/schema.one @@ -12,6 +12,7 @@ source = "%(vm_image)s", target = "%(vm_disks_prefix)sa", save = %(save_disk)s, readonly = "no", +%(root_disk_size_entry)s driver = "%(disk_driver)s" ] DISK = [ diff --git a/api/code/src/test/python/CloudInfoTest.py b/api/code/src/test/python/CloudInfoTest.py index 8a31ffad..89fb5340 100644 --- a/api/code/src/test/python/CloudInfoTest.py +++ b/api/code/src/test/python/CloudInfoTest.py @@ -58,5 +58,33 @@ def testPopulate(self): self.assertEqual('ID3',info.level1_level2_level3_id3) self.assertEqual('ID4',info.level1_id4) + def test_disk_element(self): + xml = ''' + + + ID1 + + 0 + 123 + + + 456 + + + +''' + root = etree.fromstring(xml) + + info = CloudInfo() + info.populate(root) + + assert hasattr(info, 'level1_disk_0_disk_id') + assert hasattr(info, 'level1_disk_0_size') + assert hasattr(info, 'level1_disk_x_size') + assert '0' == info.level1_disk_0_disk_id + assert '123' == info.level1_disk_0_size + assert '456' == info.level1_disk_x_size + + if __name__ == "__main__": unittest.main() diff --git a/api/code/src/test/python/vm_manager/RunnerTest.py b/api/code/src/test/python/vm_manager/RunnerTest.py index a9f054b2..21a799e9 100644 --- a/api/code/src/test/python/vm_manager/RunnerTest.py +++ b/api/code/src/test/python/vm_manager/RunnerTest.py @@ -99,6 +99,12 @@ def setUp(self): def tearDown(self): reload(ConfigHolder) + def test_set_root_disk_size(self): + runner = self._getRunnerForManifest(self.MANIFEST_DISKS_BUS_VIRTIO, + 'MMZu9WvwKIro-rtBQfDk4PsKO7_') + vm_params = runner._vmParamDict() + self.failUnlessEqual('size = 0,', vm_params['root_disk_size_entry']) + def testDisksBusTypeVirtio(self): runner = self._getRunnerForManifest(self.MANIFEST_DISKS_BUS_VIRTIO, 'MMZu9WvwKIro-rtBQfDk4PsKO7_')