You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2014/01/03 15:59:30 UTC
[18/44] git commit: Split up ex_create_multiple_nodes to make it a
bit easier to read. Also, add poll_interval keyword.
Split up ex_create_multiple_nodes to make it a bit easier to read.
Also, add poll_interval keyword.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/390c48b3
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/390c48b3
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/390c48b3
Branch: refs/heads/trunk
Commit: 390c48b316f817f14a9882ae3f67d043c6d79ea7
Parents: 9ea6e7c
Author: Rick Wright <ri...@google.com>
Authored: Mon Dec 30 00:47:12 2013 -0800
Committer: Rick Wright <ri...@google.com>
Committed: Mon Dec 30 00:47:12 2013 -0800
----------------------------------------------------------------------
libcloud/compute/drivers/gce.py | 253 +++++++++++++++++++++++------------
1 file changed, 165 insertions(+), 88 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/390c48b3/libcloud/compute/drivers/gce.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/gce.py b/libcloud/compute/drivers/gce.py
index 25bafcf..b3a9110 100644
--- a/libcloud/compute/drivers/gce.py
+++ b/libcloud/compute/drivers/gce.py
@@ -23,6 +23,7 @@ import sys
from libcloud.common.google import GoogleResponse
from libcloud.common.google import GoogleBaseConnection
+from libcloud.common.google import GoogleBaseError
from libcloud.common.google import ResourceNotFoundError
from libcloud.common.google import ResourceExistsError
@@ -1394,10 +1395,144 @@ class GCENodeDriver(NodeDriver):
return self.ex_get_node(name, location.name)
+ def _multi_create_disk(self, status, node_attrs):
+ """Create disk for ex_create_multiple_nodes.
+
+ :param status: Dictionary for holding node/disk creation status.
+ (This dictionary is modified by this method)
+ :type status: ``dict``
+
+ :param node_attrs: Dictionary for holding node attribute information.
+ (size, image, location, etc.)
+ :type node_attrs: ``dict``
+ """
+ disk = None
+ # Check for existing disk
+ if node_attrs['use_existing_disk']:
+ try:
+ disk = self.ex_get_volume(status['name'],
+ node_attrs['location'])
+ except ResourceNotFoundError:
+ pass
+
+ if disk:
+ status['disk'] = disk
+ else:
+ # Create disk and return response object back in the status dict.
+ # 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'])
+ try:
+ disk_res = self.connection.request(
+ disk_req, method='POST', data=disk_data,
+ params=disk_params).object
+ except GoogleBaseError:
+ e = self._catch_error(
+ ignore_errors=node_attrs['ignore_errors'])
+ error = e.value
+ code = e.code
+ disk_res = None
+ status['disk'] = GCEFailedDisk(status['name'],
+ error, code)
+ status['disk_response'] = disk_res
+
+ def _multi_check_disk(self, status, node_attrs):
+ """Check disk status for ex_create_multiple_nodes.
+
+ :param status: Dictionary for holding node/disk creation status.
+ (This dictionary is modified by this method)
+ :type status: ``dict``
+
+ :param node_attrs: Dictionary for holding node attribute information.
+ (size, image, location, etc.)
+ :type node_attrs: ``dict``
+ """
+ error = None
+ try:
+ response = self.connection.request(
+ status['disk_response']['selfLink']).object
+ except GoogleBaseError:
+ e = self._catch_error(ignore_errors=node_attrs['ignore_errors'])
+ error = e.value
+ code = e.code
+ response = {'status': 'DONE'}
+ if response['status'] == 'DONE':
+ status['disk_response'] = None
+ if error:
+ status['disk'] = GCEFailedDisk(status['name'], error, code)
+ else:
+ status['disk'] = self.ex_get_volume(status['name'],
+ node_attrs['location'])
+
+ def _multi_create_node(self, status, node_attrs):
+ """Create node for ex_create_multiple_nodes.
+
+ :param status: Dictionary for holding node/disk creation status.
+ (This dictionary is modified by this method)
+ :type status: ``dict``
+
+ :param node_attrs: Dictionary for holding node attribute information.
+ (size, image, location, etc.)
+ :type node_attrs: ``dict``
+ """
+ # If disk has an error, set the node as failed and return
+ if hasattr(status['disk'], 'error'):
+ status['node'] = status['disk']
+ return
+
+ # Create node and return response object in status dictionary.
+ # Or, if there is an error, mark as failed.
+ request, node_data = self._create_node_req(
+ status['name'], node_attrs['size'], node_attrs['image'],
+ node_attrs['location'], node_attrs['network'], node_attrs['tags'],
+ node_attrs['metadata'], boot_disk=status['disk'])
+ try:
+ node_res = self.connection.request(
+ request, method='POST', data=node_data).object
+ except GoogleBaseError:
+ e = self._catch_error(ignore_errors=node_attrs['ignore_errors'])
+ error = e.value
+ code = e.code
+ node_res = None
+ status['node'] = GCEFailedNode(status['name'],
+ error, code)
+ status['node_response'] = node_res
+
+ def _multi_check_node(self, status, node_attrs):
+ """Check node status for ex_create_multiple_nodes.
+
+ :param status: Dictionary for holding node/disk creation status.
+ (This dictionary is modified by this method)
+ :type status: ``dict``
+
+ :param node_attrs: Dictionary for holding node attribute information.
+ (size, image, location, etc.)
+ :type node_attrs: ``dict``
+ """
+ error = None
+ try:
+ response = self.connection.request(
+ status['node_response']['selfLink']).object
+ except GoogleBaseError:
+ e = self._catch_error(ignore_errors=node_attrs['ignore_errors'])
+ error = e.value
+ code = e.code
+ response = {'status': 'DONE'}
+ if response['status'] == 'DONE':
+ status['node_response'] = None
+ if error:
+ status['node'] = GCEFailedNode(status['name'],
+ error, code)
+ else:
+ status['node'] = self.ex_get_node(status['name'],
+ node_attrs['location'])
+
def ex_create_multiple_nodes(self, base_name, size, image, number,
location=None, ex_network='default',
ex_tags=None, ex_metadata=None,
ignore_errors=True, use_existing_disk=True,
+ poll_interval=2,
timeout=DEFAULT_TASK_COMPLETION_TIMEOUT):
"""
Create multiple nodes and return a list of Node objects.
@@ -1418,8 +1553,6 @@ class GCENodeDriver(NodeDriver):
:param image: The image to use to create the nodes.
:type image: ``str`` or :class:`NodeImage`
- return self.ex_get_snapshot(name)
-
:param number: The number of nodes to create.
:type number: ``int``
@@ -1445,6 +1578,9 @@ class GCENodeDriver(NodeDriver):
disk instead of creating a new one.
:type use_existing_disk: ``bool``
+ :keyword poll_interval: Number of seconds between status checks.
+ :type poll_interval: ``int``
+
:keyword timeout: The number of seconds to wait for all nodes to be
created before timing out.
:type timeout: ``int``
@@ -1452,7 +1588,6 @@ class GCENodeDriver(NodeDriver):
:return: A list of Node objects for the new nodes.
:rtype: ``list`` of :class:`Node`
"""
- node_data = {}
location = location or self.zone
if not hasattr(location, 'name'):
location = self.ex_get_zone(location)
@@ -1463,6 +1598,15 @@ class GCENodeDriver(NodeDriver):
if not hasattr(image, 'name'):
image = self.ex_get_image(image)
+ node_attrs = {'size': size,
+ 'image': image,
+ 'location': location,
+ 'network': ex_network,
+ 'tags': ex_tags,
+ 'metadata': ex_metadata,
+ 'ignore_errors': ignore_errors,
+ 'use_existing_disk': use_existing_disk}
+
# List for holding the status information for disk/node creation.
status_list = []
@@ -1475,34 +1619,12 @@ class GCENodeDriver(NodeDriver):
'disk_response': None,
'disk': None}
- # Create disks for nodes
- disk = None
- if use_existing_disk:
- try:
- disk = self.ex_get_volume(name, location)
- except:
- pass
-
- if disk:
- status['disk'] = disk
- else:
- disk_req, disk_data, disk_params = self._create_vol_req(
- None, name, location=location, image=image)
- try:
- disk_res = self.connection.request(
- disk_req, method='POST', data=disk_data,
- params=disk_params).object
- except:
- e = self._catch_error(ignore_errors=ignore_errors)
- error = e.value
- code = e.code
- disk_res = None
- status['disk'] = GCEFailedDisk(status['name'],
- error, code)
- status['disk_response'] = disk_res
-
status_list.append(status)
+ # Create disks for nodes
+ for status in status_list:
+ self._multi_create_disk(status, node_attrs)
+
start_time = time.time()
complete = False
while not complete:
@@ -1510,73 +1632,25 @@ class GCENodeDriver(NodeDriver):
raise Exception("Timeout (%s sec) while waiting for multiple "
"instances")
complete = True
- time.sleep(2)
- for i, status in enumerate(status_list):
+ time.sleep(poll_interval)
+ for status in status_list:
# If disk does not yet exist, check on its status
if not status['disk']:
- error = None
- try:
- response = self.connection.request(
- status['disk_response']['selfLink']).object
- except:
- e = self._catch_error(ignore_errors=ignore_errors)
- error = e.value
- code = e.code
- response = {'status': 'DONE'}
- if response['status'] == 'DONE':
- status['disk_response'] = None
- if error:
- status['disk'] = GCEFailedDisk(status['name'],
- error, code)
- else:
- status['disk'] = self.ex_get_volume(status['name'],
- location)
+ self._multi_check_disk(status, node_attrs)
# If disk exists, but node does not, create the node or check
# on its status if already in progress.
if status['disk'] and not status['node']:
if not status['node_response']:
- if hasattr(status['disk'], 'error'):
- status['node'] = status['disk']
- continue
- request, node_data = self._create_node_req(
- status['name'], size, image, location, ex_network,
- ex_tags, ex_metadata, boot_disk=status['disk'])
- try:
- node_res = self.connection.request(
- request, method='POST', data=node_data).object
- except:
- e = self._catch_error(ignore_errors=ignore_errors)
- error = e.value
- code = e.code
- node_res = None
- status['node'] = GCEFailedNode(status['name'],
- error, code)
- status['node_response'] = node_res
+ self._multi_create_node(status, node_attrs)
else:
- error = None
- try:
- response = self.connection.request(
- status['node_response']['selfLink']).object
- except:
- e = self._catch_error(ignore_errors=ignore_errors)
- error = e.value
- code = e.code
- response = {'status': 'DONE'}
- if response['status'] == 'DONE':
- status['node_response'] = None
- if error:
- status['node'] = GCEFailedNode(status['name'],
- error, code)
- else:
- status['node'] = self.ex_get_node(status['name'],
- location)
-
+ self._multi_check_node(status, node_attrs)
# If any of the nodes have not been created (or failed) we are
# not done yet.
if not status['node']:
complete = False
+ # Return list of nodes
node_list = []
for status in status_list:
node_list.append(status['node'])
@@ -2249,7 +2323,7 @@ class GCENodeDriver(NodeDriver):
return True
def ex_destroy_multiple_nodes(self, nodelist, ignore_errors=True,
- destroy_boot_disk=False,
+ destroy_boot_disk=False, poll_interval=2,
timeout=DEFAULT_TASK_COMPLETION_TIMEOUT):
"""
Destroy multiple nodes at once.
@@ -2265,6 +2339,9 @@ class GCENodeDriver(NodeDriver):
disks.
:type destroy_boot_disk: ``bool``
+ :keyword poll_interval: Number of seconds between status checks.
+ :type poll_interval: ``int``
+
:keyword timeout: Number of seconds to wait for all nodes to be
destroyed.
:type timeout: ``int``
@@ -2282,7 +2359,7 @@ class GCENodeDriver(NodeDriver):
try:
response = self.connection.request(request,
method='DELETE').object
- except:
+ except GoogleBaseError:
self._catch_error(ignore_errors=ignore_errors)
response = None
@@ -2308,7 +2385,7 @@ class GCENodeDriver(NodeDriver):
try:
response = self.connection.request(
operation['selfLink']).object
- except:
+ except GoogleBaseError:
self._catch_error(ignore_errors=ignore_errors)
no_errors = False
response = {'status': 'DONE'}
@@ -2332,7 +2409,7 @@ class GCENodeDriver(NodeDriver):
try:
response = self.connection.request(
request, method='DELETE').object
- except:
+ except GoogleBaseError:
self._catch_error(ignore_errors=ignore_errors)
no_errors = False
response = None
@@ -2341,7 +2418,7 @@ class GCENodeDriver(NodeDriver):
status['disk_success'] = True
operation = status['node_response'] or status['disk_response']
if operation:
- time.sleep(2)
+ time.sleep(poll_interval)
complete = False
success = []