Repository: libcloud Updated Branches: refs/heads/trunk 3d56532c9 -> 535896087
Add libcloud support for image guest OS features. Guest OS features are a repeated field in the API. Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/67368d0b Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/67368d0b Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/67368d0b Branch: refs/heads/trunk Commit: 67368d0b51e386e5b5a62e06e68e58f858238926 Parents: 3d56532 Author: Max Illfelder <[email protected]> Authored: Fri Jun 24 17:15:00 2016 -0700 Committer: Anthony Shaw <[email protected]> Committed: Wed Jun 29 14:30:34 2016 +1000 ---------------------------------------------------------------------- libcloud/compute/drivers/gce.py | 54 ++++++++++++++------ .../projects_coreos-cloud_global_images.json | 5 ++ libcloud/test/compute/test_gce.py | 7 ++- 3 files changed, 50 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/67368d0b/libcloud/compute/drivers/gce.py ---------------------------------------------------------------------- diff --git a/libcloud/compute/drivers/gce.py b/libcloud/compute/drivers/gce.py index 9f9b8c1..61f6e0c 100644 --- a/libcloud/compute/drivers/gce.py +++ b/libcloud/compute/drivers/gce.py @@ -2192,7 +2192,8 @@ class GCENodeDriver(NodeDriver): return self.ex_get_forwarding_rule(name, global_rule=global_rule) def ex_create_image(self, name, volume, description=None, family=None, - use_existing=True, wait_for_completion=True): + guest_os_features=None, use_existing=True, + wait_for_completion=True): """ Create an image from the provided volume. @@ -2203,15 +2204,21 @@ class GCENodeDriver(NodeDriver): Google Cloud Storage URI :type volume: ``str`` or :class:`StorageVolume` - :keyword description: Description of the new Image - :type description: ``str`` + :keyword description: Description of the new Image + :type description: ``str`` - :keyword family: The name of the image family to which this image - belongs. If you create resources by specifying an - image family instead of a specific image name, the - resource uses the latest non-deprecated image that - is set with that family name. - :type family: ``str`` + :keyword family: The name of the image family to which this image + belongs. If you create resources by specifying an + image family instead of a specific image name, the + resource uses the latest non-deprecated image that + is set with that family name. + :type family: ``str`` + + :keywork guest_os_features: Features of the guest operating system, + valid for bootable images only. Possible + values include \'VIRTIO_SCSI_MULTIQUEUE\' + if specified. + :type guest_os_features: ``list`` of ``str`` or ``None`` :keyword use_existing: If True and an image with the given name already exists, return an object for that @@ -2226,10 +2233,11 @@ class GCENodeDriver(NodeDriver): creation progress :type wait_for_completion: ``bool`` - :return: A GCENodeImage object for the new image - :rtype: :class:`GCENodeImage` + :return: A GCENodeImage object for the new image + :rtype: :class:`GCENodeImage` """ + possible_features = ['VIRTIO_SCSI_MULTIQUEUE'] image_data = {} image_data['name'] = name image_data['description'] = description @@ -2243,7 +2251,14 @@ class GCENodeDriver(NodeDriver): image_data['rawDisk'] = {'source': volume, 'containerType': 'TAR'} else: raise ValueError('Source must be instance of StorageVolume or URI') - + if guest_os_features: + image_data['guestOsFeatures'] = [] + for feature in guest_os_features: + if feature in possible_features: + image_data['guestOsFeatures'].append({'type': feature}) + else: + raise ValueError('Features must be one of %s' + % ','.join(possible_features)) request = '/global/images' try: @@ -4348,7 +4363,7 @@ class GCENodeDriver(NodeDriver): """ Return an GCENodeImage object based on an image family name. - :param image_family: The name of the Image Family to return the + :param image_family: The name of the 'Image Family' to return the latest image from. :type image_family: ``str`` @@ -4723,7 +4738,8 @@ class GCENodeDriver(NodeDriver): return None return self._to_zone(response) - def ex_copy_image(self, name, url, description=None, family=None): + def ex_copy_image(self, name, url, description=None, family=None, + guest_os_features=None): """ Copy an image to your image collection. @@ -4739,12 +4755,15 @@ class GCENodeDriver(NodeDriver): :param family: The family of the image :type family: ``str`` + :param guest_os_features: The features of the guest operating system. + :type guest_os_features: ``list`` of ``str`` or ``None`` + :return: NodeImage object based on provided information or None if an image with that name is not found. :rtype: :class:`NodeImage` or ``None`` """ - # the URL for an image can start with gs:// + # The URL for an image can start with gs:// if url.startswith('gs://'): url = url.replace('gs://', 'https://storage.googleapis.com/', 1) @@ -4758,6 +4777,9 @@ class GCENodeDriver(NodeDriver): }, } + if guest_os_features: + image_data['guestOsFeatures'] = guest_os_features + request = '/global/images' self.connection.async_request(request, method='POST', data=image_data) @@ -5713,6 +5735,8 @@ class GCENodeDriver(NodeDriver): extra['status'] = image.get('status', None) extra['archiveSizeBytes'] = image.get('archiveSizeBytes', None) extra['diskSizeGb'] = image.get('diskSizeGb', None) + if 'guestOsFeatures' in image: + extra['guestOsFeatures'] = image.get('guestOsFeatures', []) if 'sourceDisk' in image: extra['sourceDisk'] = image.get('sourceDisk', None) if 'sourceDiskId' in image: http://git-wip-us.apache.org/repos/asf/libcloud/blob/67368d0b/libcloud/test/compute/fixtures/gce/projects_coreos-cloud_global_images.json ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/gce/projects_coreos-cloud_global_images.json b/libcloud/test/compute/fixtures/gce/projects_coreos-cloud_global_images.json index ce1a1fd..5e48b10 100644 --- a/libcloud/test/compute/fixtures/gce/projects_coreos-cloud_global_images.json +++ b/libcloud/test/compute/fixtures/gce/projects_coreos-cloud_global_images.json @@ -1327,6 +1327,11 @@ "name": "coreos-beta-522-3-0-v20141226", "description": "CoreOS beta 522.3.0", "family": "coreos", + "guestOsFeatures": [ + { + "type": "VIRTIO_SCSI_MULTIQUEUE" + } + ], "sourceType": "RAW", "rawDisk": { "source": "", http://git-wip-us.apache.org/repos/asf/libcloud/blob/67368d0b/libcloud/test/compute/test_gce.py ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/test_gce.py b/libcloud/test/compute/test_gce.py index 88ca644..0d8843f 100644 --- a/libcloud/test/compute/test_gce.py +++ b/libcloud/test/compute/test_gce.py @@ -454,6 +454,8 @@ class GCENodeDriverTest(GoogleTestCase, TestCaseMixin): self.assertTrue(image.name.startswith('coreos')) self.assertEqual(image.extra['description'], 'CoreOS beta 522.3.0') self.assertEqual(image.extra['family'], 'coreos') + self.assertEqual(image.extra['guestOsFeatures'], + [{'type': 'VIRTIO_SCSI_MULTIQUEUE'}]) def test_ex_create_firewall(self): firewall_name = 'lcfirewall' @@ -1350,11 +1352,14 @@ class GCENodeDriverTest(GoogleTestCase, TestCaseMixin): url = 'gs://storage.core-os.net/coreos/amd64-generic/247.0.0/coreos_production_gce.tar.gz' description = 'CoreOS beta 522.3.0' family = 'coreos' + guest_os_features = [{'type': 'VIRTIO_SCSI_MULTIQUEUE'}] image = self.driver.ex_copy_image(name, url, description=description, - family=family) + family=family, + guest_os_features=guest_os_features) self.assertTrue(image.name.startswith(name)) self.assertEqual(image.extra['description'], description) self.assertEqual(image.extra['family'], family) + self.assertEqual(image.extra['guestOsFeatures'], guest_os_features) def test_ex_get_route(self): route_name = 'lcdemoroute'
