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 = []