Add SSD support to GCE Compute driver Closes #339
Signed-off-by: Tomaz Muraus <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/e3edf278 Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/e3edf278 Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/e3edf278 Branch: refs/heads/trunk Commit: e3edf278c3310bd93f5d4e463bcc0373a38d5401 Parents: a26da95 Author: Eric Johnson <[email protected]> Authored: Wed Jul 16 15:40:12 2014 +0000 Committer: Tomaz Muraus <[email protected]> Committed: Mon Jul 21 10:09:13 2014 +0200 ---------------------------------------------------------------------- CHANGES.rst | 3 + demos/gce_demo.py | 6 +- libcloud/compute/drivers/gce.py | 71 +- libcloud/compute/drivers/gce.py.orig | 3353 ++++++++++++++++++ .../gce/global_snapshots_lcsnapshot.json | 4 +- .../fixtures/gce/zones_us-central1-a_disks.json | 8 +- .../gce/zones_us-central1-a_disks_lcdisk.json | 6 +- libcloud/test/compute/test_gce.py | 17 +- 8 files changed, 3445 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/e3edf278/CHANGES.rst ---------------------------------------------------------------------- diff --git a/CHANGES.rst b/CHANGES.rst index 17999cc..bef4c9d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -16,6 +16,9 @@ Compute (LIBCLOUD-594, GITHUB-337) [Atsushi Sasaki] +- Add support for SSD disks to Google Compute driver. + (GITHUB-339) + [Eric Johnson] Loadbalancer ~~~~~~~~~~~~ http://git-wip-us.apache.org/repos/asf/libcloud/blob/e3edf278/demos/gce_demo.py ---------------------------------------------------------------------- diff --git a/demos/gce_demo.py b/demos/gce_demo.py index 5f45c68..3535689 100755 --- a/demos/gce_demo.py +++ b/demos/gce_demo.py @@ -190,16 +190,16 @@ def main(): # == Create Node with disk auto-created == if MAX_NODES > 1: - print('Creating Node with auto-created disk:') + print('Creating Node with auto-created SSD:') name = '%s-np-node' % DEMO_BASE_NAME node_1 = gce.create_node(name, 'n1-standard-1', 'debian-7', - ex_tags=['libcloud']) + ex_tags=['libcloud'], ex_disk_type='pd-ssd') print(' Node %s created' % name) # == Create, and attach a disk == print('Creating a new disk:') disk_name = '%s-attach-disk' % DEMO_BASE_NAME - volume = gce.create_volume(1, disk_name) + volume = gce.create_volume(10, disk_name) if volume.attach(node_1): print (' Attached %s to %s' % (volume.name, node_1.name)) http://git-wip-us.apache.org/repos/asf/libcloud/blob/e3edf278/libcloud/compute/drivers/gce.py ---------------------------------------------------------------------- diff --git a/libcloud/compute/drivers/gce.py b/libcloud/compute/drivers/gce.py index 62164fd..a6f3c9f 100644 --- a/libcloud/compute/drivers/gce.py +++ b/libcloud/compute/drivers/gce.py @@ -1140,7 +1140,8 @@ class GCENodeDriver(NodeDriver): def create_node(self, name, size, image, location=None, ex_network='default', ex_tags=None, ex_metadata=None, ex_boot_disk=None, use_existing_disk=True, - external_ip='ephemeral'): + external_ip='ephemeral', ex_disk_type='pd-standard', + ex_disk_auto_delete=True): """ Create a new node and return a node object for the node. @@ -1182,6 +1183,15 @@ class GCENodeDriver(NodeDriver): a GCEAddress object should be passed in. :type external_ip: :class:`GCEAddress` or ``str`` or None + :keyword ex_disk_type: Specify a pd-standard (default) disk or pd-ssd + for an SSD disk. + :type ex_disk_type: ``str`` + + :keyword ex_disk_auto_delete: Indicate that the boot disk should be + deleted when the Node is deleted. Set to + True by default. + :type ex_disk_auto_delete: ``bool`` + :return: A Node object for the new node. :rtype: :class:`Node` """ @@ -1198,7 +1208,8 @@ class GCENodeDriver(NodeDriver): if not ex_boot_disk: ex_boot_disk = self.create_volume(None, name, location=location, image=image, - use_existing=use_existing_disk) + use_existing=use_existing_disk, + ex_disk_type=ex_disk_type) if ex_metadata is not None: ex_metadata = {"items": [{"key": k, "value": v} @@ -1207,7 +1218,9 @@ class GCENodeDriver(NodeDriver): request, node_data = self._create_node_req(name, size, image, location, ex_network, ex_tags, ex_metadata, - ex_boot_disk, external_ip) + ex_boot_disk, external_ip, + ex_disk_type, + ex_disk_auto_delete) self.connection.async_request(request, method='POST', data=node_data) return self.ex_get_node(name, location.name) @@ -1217,6 +1230,8 @@ class GCENodeDriver(NodeDriver): ex_tags=None, ex_metadata=None, ignore_errors=True, use_existing_disk=True, poll_interval=2, external_ip='ephemeral', + ex_disk_type='pd-standard', + ex_auto_disk_delete=True, timeout=DEFAULT_TASK_COMPLETION_TIMEOUT): """ Create multiple nodes and return a list of Node objects. @@ -1273,6 +1288,15 @@ class GCENodeDriver(NodeDriver): multiple node creation.) :type external_ip: ``str`` or None + :keyword ex_disk_type: Specify a pd-standard (default) disk or pd-ssd + for an SSD disk. + :type ex_disk_type: ``str`` + + :keyword ex_disk_auto_delete: Indicate that the boot disk should be + deleted when the Node is deleted. Set to + True by default. + :type ex_disk_auto_delete: ``bool`` + :keyword timeout: The number of seconds to wait for all nodes to be created before timing out. :type timeout: ``int`` @@ -1298,7 +1322,8 @@ class GCENodeDriver(NodeDriver): 'metadata': ex_metadata, 'ignore_errors': ignore_errors, 'use_existing_disk': use_existing_disk, - 'external_ip': external_ip} + 'external_ip': external_ip, + 'ex_disk_type': ex_disk_type} # List for holding the status information for disk/node creation. status_list = [] @@ -1406,7 +1431,8 @@ class GCENodeDriver(NodeDriver): return self.ex_get_targetpool(name, region) def create_volume(self, size, name, location=None, snapshot=None, - image=None, use_existing=True): + image=None, use_existing=True, + ex_disk_type='pd-standard'): """ Create a volume (disk). @@ -1432,11 +1458,15 @@ class GCENodeDriver(NodeDriver): of attempting to create a new disk. :type use_existing: ``bool`` + :keyword ex_disk_type: Specify a pd-standard (default) disk or pd-ssd + for an SSD disk. + :type ex_disk_type: ``str`` + :return: Storage Volume object :rtype: :class:`StorageVolume` """ request, volume_data, params = self._create_vol_req( - size, name, location, snapshot, image) + size, name, location, snapshot, image, ex_disk_type) try: self.connection.async_request(request, method='POST', data=volume_data, params=params) @@ -2716,7 +2746,8 @@ class GCENodeDriver(NodeDriver): def _create_node_req(self, name, size, image, location, network, tags=None, metadata=None, boot_disk=None, - external_ip='ephemeral'): + external_ip='ephemeral', ex_disk_type='pd-standard', + ex_disk_auto_delete=True): """ Returns a request and body to create a new node. This is a helper method to support both :class:`create_node` and @@ -2754,6 +2785,15 @@ class GCENodeDriver(NodeDriver): a GCEAddress object should be passed in. :type external_ip: :class:`GCEAddress` or ``str`` or None + :keyword ex_disk_type: Specify a pd-standard (default) disk or pd-ssd + for an SSD disk. + :type ex_disk_type: ``str`` + + :keyword ex_disk_auto_delete: Indicate that the boot disk should be + deleted when the Node is deleted. Set to + True by default. + :type ex_disk_auto_delete: ``bool`` + :return: A tuple containing a request string and a node_data dict. :rtype: ``tuple`` of ``str`` and ``dict`` """ @@ -2799,7 +2839,7 @@ class GCENodeDriver(NodeDriver): :type status: ``dict`` :param node_attrs: Dictionary for holding node attribute information. - (size, image, location, etc.) + (size, image, location, ex_disk_type, etc.) :type node_attrs: ``dict`` """ disk = None @@ -2818,7 +2858,8 @@ class GCENodeDriver(NodeDriver): # Or, if there is an error, mark as failed. disk_req, disk_data, disk_params = self._create_vol_req( None, status['name'], location=node_attrs['location'], - image=node_attrs['image']) + image=node_attrs['image'], + ex_disk_type=node_attrs['ex_disk_type']) try: disk_res = self.connection.request( disk_req, method='POST', data=disk_data, @@ -2926,7 +2967,7 @@ class GCENodeDriver(NodeDriver): node_attrs['location']) def _create_vol_req(self, size, name, location=None, snapshot=None, - image=None): + image=None, ex_disk_type='pd-standard'): """ Assemble the request/data for creating a volume. @@ -2949,6 +2990,9 @@ class GCENodeDriver(NodeDriver): :keyword image: Image to create disk from. :type image: :class:`GCENodeImage` or ``str`` or ``None`` + :keyword ex_disk_type: Specify pd-standard (default) or pd-ssd + :type ex_disk_type: ``str`` + :return: Tuple containing the request string, the data dictionary and the URL parameters :rtype: ``tuple`` @@ -2976,6 +3020,12 @@ class GCENodeDriver(NodeDriver): location = location or self.zone if not hasattr(location, 'name'): location = self.ex_get_zone(location) + if ex_disk_type.startswith('https'): + volume_data['type'] = ex_disk_type + else: + volume_data['type'] = 'https://www.googleapis.com/compute/' + volume_data['type'] += '%s/projects/%s/zones/%s/diskTypes/%s' % ( + API_VERSION, self.project, location.name, ex_disk_type) request = '/zones/%s/disks' % (location.name) return request, volume_data, params @@ -3305,6 +3355,7 @@ class GCENodeDriver(NodeDriver): extra['status'] = volume.get('status') extra['creationTimestamp'] = volume.get('creationTimestamp') extra['description'] = volume.get('description') + extra['type'] = volume.get('type', 'pd-standard').split('/')[-1] return StorageVolume(id=volume['id'], name=volume['name'], size=volume['sizeGb'], driver=self, extra=extra)
