Author: tomaz
Date: Wed Mar 27 03:05:58 2013
New Revision: 1461394
URL: http://svn.apache.org/r1461394
Log:
Backport commits from trunk.
Modified:
libcloud/branches/0.12.x/ (props changed)
libcloud/branches/0.12.x/CHANGES
libcloud/branches/0.12.x/libcloud/compute/base.py
Propchange: libcloud/branches/0.12.x/
------------------------------------------------------------------------------
Merged /libcloud/trunk:r1460094-1460106
Modified: libcloud/branches/0.12.x/CHANGES
URL:
http://svn.apache.org/viewvc/libcloud/branches/0.12.x/CHANGES?rev=1461394&r1=1461393&r2=1461394&view=diff
==============================================================================
--- libcloud/branches/0.12.x/CHANGES (original)
+++ libcloud/branches/0.12.x/CHANGES Wed Mar 27 03:05:58 2013
@@ -8,6 +8,11 @@ Changes with Apache Libcloud in developm
(LIBCLOUD-310)
[Jason Johnson]
+ - Allow user to pass alternate ssh usernames to deploy_node
+ (ssh_alternate_usernames kwarg) which are used for authentication if the
+ default one doesn't work. (LIBCLOUD-309)
+ [Chris Psaltis, Tomaz Muraus]
+
Changes with Apache Libcloud 0.12.3:
*) General
Modified: libcloud/branches/0.12.x/libcloud/compute/base.py
URL:
http://svn.apache.org/viewvc/libcloud/branches/0.12.x/libcloud/compute/base.py?rev=1461394&r1=1461393&r2=1461394&view=diff
==============================================================================
--- libcloud/branches/0.12.x/libcloud/compute/base.py (original)
+++ libcloud/branches/0.12.x/libcloud/compute/base.py Wed Mar 27 03:05:58 2013
@@ -592,6 +592,11 @@ class NodeDriver(BaseDriver):
SSH server (default is root)
@type ssh_username: C{str}
+ @keyword ssh_alternate_usernames: Optional list of ssh usernames to
+ try to connect with if using the
+ default one fails
+ @type ssh_alternate_usernames: C{list}
+
@keyword ssh_port: Optional SSH server port (default is 22)
@type ssh_port: C{int}
@@ -647,42 +652,53 @@ class NodeDriver(BaseDriver):
if 'generates_password' in self.features['create_node']:
password = node.extra.get('password')
+ ssh_interface = kwargs.get('ssh_interface', 'public_ips')
+
+ # Wait until node is up and running and has IP assigned
try:
- # Wait until node is up and running and has IP assigned
- ssh_interface = kwargs.get('ssh_interface', 'public_ips')
node, ip_addresses = self.wait_until_running(
nodes=[node],
wait_period=3, timeout=NODE_ONLINE_WAIT_TIMEOUT,
ssh_interface=ssh_interface)[0]
-
- if password:
- node.extra['password'] = password
-
- ssh_username = kwargs.get('ssh_username', 'root')
- ssh_port = kwargs.get('ssh_port', 22)
- ssh_timeout = kwargs.get('ssh_timeout', 10)
- ssh_key_file = kwargs.get('ssh_key', None)
- timeout = kwargs.get('timeout', SSH_CONNECT_TIMEOUT)
-
- ssh_client = SSHClient(hostname=ip_addresses[0],
- port=ssh_port, username=ssh_username,
- password=password,
- key=ssh_key_file,
- timeout=ssh_timeout)
-
- # Connect to the SSH server running on the node
- ssh_client = self._ssh_client_connect(ssh_client=ssh_client,
- timeout=timeout)
-
- # Execute the deployment task
- self._run_deployment_script(task=kwargs['deploy'],
- node=node,
- ssh_client=ssh_client,
- max_tries=max_tries)
except Exception:
e = sys.exc_info()[1]
raise DeploymentError(node=node, original_exception=e, driver=self)
+ if password:
+ node.extra['password'] = password
+
+ ssh_username = kwargs.get('ssh_username', 'root')
+ ssh_alternate_usernames = kwargs.get('ssh_alternate_usernames', [])
+ ssh_port = kwargs.get('ssh_port', 22)
+ ssh_timeout = kwargs.get('ssh_timeout', 10)
+ ssh_key_file = kwargs.get('ssh_key', None)
+ timeout = kwargs.get('timeout', SSH_CONNECT_TIMEOUT)
+
+ deploy_error = None
+
+ for username in ([ssh_username] + ssh_alternate_usernames):
+ try:
+ self._connect_and_run_deployment_script(
+ task=kwargs['deploy'], node=node,
+ ssh_hostname=ip_addresses[0], ssh_port=ssh_port,
+ ssh_username=username, ssh_password=password,
+ ssh_key_file=ssh_key_file, ssh_timeout=ssh_timeout,
+ timeout=timeout, max_tries=max_tries)
+ except Exception:
+ # Try alternate username
+ # Todo: Need to fix paramiko so we can catch a more specific
+ # exception
+ e = sys.exc_info()[1]
+ deploy_error = e
+ else:
+ # Script sucesfully executed, don't try alternate username
+ deploy_error = None
+ break
+
+ if deploy_error is not None:
+ raise DeploymentError(node=node, original_exception=deploy_error,
+ driver=self)
+
return node
def create_volume(self, size, name, location=None, snapshot=None):
@@ -757,14 +773,16 @@ class NodeDriver(BaseDriver):
ssh_interface='public_ips', force_ipv4=True):
# This is here for backward compatibility and will be removed in the
# next major release
- return wait_until_running(nodes=[node], wait_period=wait_period,
- timeout=timeout, ssh_interface=ssh_interface,
- force_ipv4=force_ipv4)
+ return self._wait_until_running(nodes=[node], wait_period=wait_period,
+ timeout=timeout,
+ ssh_interface=ssh_interface,
+ force_ipv4=force_ipv4)
def wait_until_running(self, nodes, wait_period=3, timeout=600,
ssh_interface='public_ips', force_ipv4=True):
"""
- Block until the given nodes are fully booted and have an IP address
assigned.
+ Block until the given nodes are fully booted and have an IP address
+ assigned.
@keyword nodes: list of node instances.
@type nodes: C{List} of L{Node}
@@ -817,13 +835,14 @@ class NodeDriver(BaseDriver):
if len(nodes) > len(uuids):
found_uuids = [n.uuid for n in nodes]
- raise LibcloudError(value=('Unable to match specified uuids ' +
- '(%s) with existing nodes. Found '
% uuids +
- 'multiple nodes with same uuid:
(%s)' % found_uuids),
- driver=self)
+ msg = ('Unable to match specified uuids ' +
+ '(%s) with existing nodes. Found ' % (uuids) +
+ 'multiple nodes with same uuid: (%s)' % (found_uuids))
+ raise LibcloudError(value=msg, driver=self)
running_nodes = [n for n in nodes if n.state == NodeState.RUNNING]
- addresses = [filter_addresses(getattr(n, ssh_interface)) for n in
running_nodes]
+ addresses = [filter_addresses(getattr(n, ssh_interface)) for n in
+ running_nodes]
if len(running_nodes) == len(uuids) == len(addresses):
return list(zip(running_nodes, addresses))
else:
@@ -869,6 +888,25 @@ class NodeDriver(BaseDriver):
raise LibcloudError(value='Could not connect to the remote SSH ' +
'server. Giving up.', driver=self)
+ def _connect_and_run_deployment_script(self, task, node, ssh_hostname,
+ ssh_port, ssh_username,
+ ssh_password, ssh_key_file,
+ ssh_timeout, timeout, max_tries):
+ ssh_client = SSHClient(hostname=ssh_hostname,
+ port=ssh_port, username=ssh_username,
+ password=ssh_password,
+ key=ssh_key_file,
+ timeout=ssh_timeout)
+
+ # Connect to the SSH server running on the node
+ ssh_client = self._ssh_client_connect(ssh_client=ssh_client,
+ timeout=timeout)
+
+ # Execute the deployment task
+ self._run_deployment_script(task=task, node=node,
+ ssh_client=ssh_client,
+ max_tries=max_tries)
+
def _run_deployment_script(self, task, node, ssh_client, max_tries=3):
"""
Run the deployment script on the provided node. At this point it is
@@ -894,6 +932,7 @@ class NodeDriver(BaseDriver):
try:
node = task.run(node, ssh_client)
except Exception:
+ e = sys.exc_info()[1]
tries += 1
if tries >= max_tries:
e = sys.exc_info()[1]