You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by pq...@apache.org on 2010/05/05 02:32:05 UTC
svn commit: r941122 - in /incubator/libcloud/trunk/libcloud: base.py types.py
Author: pquerna
Date: Wed May 5 00:32:05 2010
New Revision: 941122
URL: http://svn.apache.org/viewvc?rev=941122&view=rev
Log:
Add DeploymentException, which allows you to better recover and detect a failure to deploy which is different than a failure of the provider's create_node, this will let you possibly cleanup a partially boot-strapped node.
Modified:
incubator/libcloud/trunk/libcloud/base.py
incubator/libcloud/trunk/libcloud/types.py
Modified: incubator/libcloud/trunk/libcloud/base.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/base.py?rev=941122&r1=941121&r2=941122&view=diff
==============================================================================
--- incubator/libcloud/trunk/libcloud/base.py (original)
+++ incubator/libcloud/trunk/libcloud/base.py Wed May 5 00:32:05 2010
@@ -26,7 +26,7 @@ from libcloud.interface import INodeDriv
from libcloud.interface import INodeFactory, INode
from libcloud.interface import INodeSizeFactory, INodeSize
from libcloud.interface import INodeImageFactory, INodeImage
-from libcloud.types import NodeState
+from libcloud.types import NodeState, DeploymentException
from libcloud.ssh import SSHClient
import time
import hashlib
@@ -640,6 +640,11 @@ class NodeDriver(object):
Depends on a Provider Driver supporting either using a specific password
or returning a generated password.
+ This function may raise a L{DeplyomentException}, if a create_node
+ call was successful, but there is a later error (like SSH failing or
+ timing out). This exception includes a Node object which you may want
+ to destroy if incomplete deployments are not desirable.
+
@keyword deploy: Deployment to run once machine is online and availble to SSH.
@type deploy: L{Deployment}
@@ -659,43 +664,48 @@ class NodeDriver(object):
password = kwargs['auth'].password
node = self.create_node(**kwargs)
- if 'generates_password' in self.features["create_node"]:
- password = node.extra.get('password')
- start = time.time()
- end = start + (60 * 15)
- while time.time() < end:
- # need to wait until we get a public IP address.
- # TODO: there must be a better way of doing this
- time.sleep(WAIT_PERIOD)
- nodes = self.list_nodes()
- nodes = filter(lambda n: n.uuid == node.uuid, nodes)
- if len(nodes) == 0:
- raise Exception("Booted node[%s] is missing form list_nodes.", node)
- if len(nodes) > 1:
- raise Exception("Booted single node[%s], but multiple nodes have same UUID", node)
-
- node = nodes[0]
-
- if node.public_ip is not None and node.public_ip != "" and node.state == NodeState.RUNNING:
- break
-
- client = SSHClient(hostname=node.public_ip[0],
- port=22, username='root',
- password=password)
- laste = None
- while time.time() < end:
- laste = None
- try:
- client.connect()
- break
- except (IOError, socket.gaierror, socket.error), e:
- laste = e
- time.sleep(WAIT_PERIOD)
- if laste is not None:
- raise e
-
- n = kwargs["deploy"].run(node, client)
- client.close()
+ try:
+ if 'generates_password' in self.features["create_node"]:
+ password = node.extra.get('password')
+ start = time.time()
+ end = start + (60 * 15)
+ while time.time() < end:
+ # need to wait until we get a public IP address.
+ # TODO: there must be a better way of doing this
+ time.sleep(WAIT_PERIOD)
+ nodes = self.list_nodes()
+ nodes = filter(lambda n: n.uuid == node.uuid, nodes)
+ if len(nodes) == 0:
+ raise DeploymentException(node, "Booted node[%s] is missing form list_nodes." % node)
+ if len(nodes) > 1:
+ raise DeploymentException(node, "Booted single node[%s], but multiple nodes have same UUID"% node)
+
+ node = nodes[0]
+
+ if node.public_ip is not None and node.public_ip != "" and node.state == NodeState.RUNNING:
+ break
+
+ client = SSHClient(hostname=node.public_ip[0],
+ port=22, username='root',
+ password=password)
+ laste = None
+ while time.time() < end:
+ laste = None
+ try:
+ client.connect()
+ break
+ except (IOError, socket.gaierror, socket.error), e:
+ laste = e
+ time.sleep(WAIT_PERIOD)
+ if laste is not None:
+ raise e
+
+ n = kwargs["deploy"].run(node, client)
+ client.close()
+ except DeploymentException, e:
+ raise
+ except Exception, e:
+ raise DeploymentException(node, e)
return n
def is_private_subnet(ip):
Modified: incubator/libcloud/trunk/libcloud/types.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/types.py?rev=941122&r1=941121&r2=941122&view=diff
==============================================================================
--- incubator/libcloud/trunk/libcloud/types.py (original)
+++ incubator/libcloud/trunk/libcloud/types.py Wed May 5 00:32:05 2010
@@ -77,3 +77,15 @@ class InvalidCredsException(Exception):
self.value = value
def __str__(self):
return repr(self.value)
+
+class DeploymentException(Exception):
+ """
+ Exception used when a Deployment Task failed.
+
+ @ivar node: L{Node} on which this exception happened, you might want to call L{Node.destroy}
+ """
+ def __init__(self, node, original_exception=None):
+ self.node = node
+ self.value = original_exception
+ def __str__(self):
+ return repr(self.value)