Updated Branches: refs/heads/0.12.x fbcfa0764 -> 3386cfdeb
Various bug fixes and improvements in the HostVirtual driver. Contributed by Dinesh Bhoopathy, part of LIBCLOUD-249. git-svn-id: https://svn.apache.org/repos/asf/libcloud/trunk@1480490 13f79535-47bb-0310-9956-ffa450edef68 Conflicts: CHANGES Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/3386cfde Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/3386cfde Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/3386cfde Branch: refs/heads/0.12.x Commit: 3386cfdeb38f995f9355bbcc089d20077a92c11b Parents: fbcfa07 Author: Tomaž Muraus <[email protected]> Authored: Wed May 8 22:35:25 2013 +0000 Committer: Tomaz Muraus <[email protected]> Committed: Fri Jun 14 16:06:35 2013 -0700 ---------------------------------------------------------------------- CHANGES | 4 + libcloud/compute/drivers/hostvirtual.py | 98 ++++++++++++-------- .../fixtures/hostvirtual/create_node.json | 16 +--- libcloud/test/compute/test_hostvirtual.py | 24 +++-- 4 files changed, 82 insertions(+), 60 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/3386cfde/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index a27f3f9..85a13fd 100644 --- a/CHANGES +++ b/CHANGES @@ -84,6 +84,10 @@ Changes with Apache Libcloud in deveploment: - Fix a bug in the GoGrid driver get_uuid method. (LIBCLOUD-341) [Bob Thompson] + - Various bug fixes and improvements in the HostVirtual driver. + (LIBCLOUD-249) + [Dinesh Bhoopathy] + *) Storage - Fix an issue with double encoding the container name in the CloudFiles http://git-wip-us.apache.org/repos/asf/libcloud/blob/3386cfde/libcloud/compute/drivers/hostvirtual.py ---------------------------------------------------------------------- diff --git a/libcloud/compute/drivers/hostvirtual.py b/libcloud/compute/drivers/hostvirtual.py index 088f4a7..e311224 100644 --- a/libcloud/compute/drivers/hostvirtual.py +++ b/libcloud/compute/drivers/hostvirtual.py @@ -17,14 +17,13 @@ libcloud driver for the Host Virtual Inc. (VR) API Home page http://www.vr.org/ """ +import time + try: import simplejson as json except ImportError: import json - -from libcloud.utils.py3 import httplib - from libcloud.common.hostvirtual import HostVirtualResponse from libcloud.common.hostvirtual import HostVirtualConnection from libcloud.common.hostvirtual import HostVirtualException @@ -36,7 +35,6 @@ from libcloud.compute.base import NodeAuthSSHKey, NodeAuthPassword API_ROOT = '/vapi' -#API_VERSION = '0.1' NODE_STATE_MAP = { 'BUILDING': NodeState.PENDING, 'PENDING': NodeState.PENDING, @@ -47,6 +45,8 @@ NODE_STATE_MAP = { 'TERMINATED': NodeState.TERMINATED # server is powered down } +DEFAULT_NODE_LOCATION_ID = 4 + class HostVirtualComputeResponse(HostVirtualResponse): pass @@ -78,8 +78,8 @@ class HostVirtualNodeDriver(NodeDriver): extra['image'] = data['os_id'] if 'location_id' in data: extra['location'] = data['location_id'] - - public_ips.append(data['ip']) + if 'ip' in data: + public_ips.append(data['ip']) node = Node(id=data['mbpkgid'], name=data['fqdn'], state=state, public_ips=public_ips, private_ips=private_ips, @@ -137,40 +137,59 @@ class HostVirtualNodeDriver(NodeDriver): nodes.append(node) return nodes + def _wait_for_node(self, node_id, timeout=30, interval=5.0): + """ + @param node_id: ID of the node to wait for. + @type node_id: C{int} + + @param timeout: Timeout (in seconds). + @type timeout: C{int} + + @param interval: How long to wait (in seconds) between each attempt. + @type interval: C{float} + """ + # poll until we get a node + for i in range(0, timeout, int(interval)): + try: + node = self.ex_get_node(node_id) + return node + except HostVirtualException: + time.sleep(interval) + + raise HostVirtualException(412, 'Timedout on getting node details') + def create_node(self, **kwargs): - name = kwargs['name'] # expects fqdn ex: test.com + dc = None + size = kwargs['size'] image = kwargs['image'] - auth = kwargs['auth'] - dc = None - if "location" in kwargs: - dc = kwargs["location"].id - else: - dc = '3' + params = {'plan': size.name} - params = {'fqdn': name, - 'plan': size.name, - 'image': image.id, - 'location': dc - } + dc = DEFAULT_NODE_LOCATION_ID + if 'location' in kwargs: + dc = kwargs['location'].id - ssh_key = None - password = None - if isinstance(auth, NodeAuthSSHKey): - ssh_key = auth.pubkey - params['ssh_key'] = ssh_key - elif isinstance(auth, NodeAuthPassword): - password = auth.password - params['password'] = password - - if not ssh_key and not password: - raise HostVirtualException(500, "Need SSH key or Root password") - - result = self.connection.request(API_ROOT + '/cloud/buy_build', + # simply order a package first + result = self.connection.request(API_ROOT + '/cloud/buy/', data=json.dumps(params), method='POST').object - return self._to_node(result) + + # create a stub node + stub_node = self._to_node({ + 'mbpkgid': result['id'], + 'status': 'PENDING', + 'fqdn': kwargs['name'], + 'plan_id': size.id, + 'os_id': image.id, + 'location_id': dc + }) + + # provisioning a server using the stub node + self.ex_provision_node(node=stub_node, auth=kwargs['auth']) + + node = self._wait_for_node(stub_node.id) + return node def reboot_node(self, node): params = {'force': 0, 'mbpkgid': node.id} @@ -182,7 +201,11 @@ class HostVirtualNodeDriver(NodeDriver): return bool(result) def destroy_node(self, node): - params = {'mbpkgid': node.id} + params = { + 'mbpkgid': node.id, + #'reason': 'Submitted through Libcloud API' + } + result = self.connection.request( API_ROOT + '/cloud/cancel', data=json.dumps(params), method='POST').object @@ -216,7 +239,7 @@ class HostVirtualNodeDriver(NodeDriver): """ params = {'force': 0, 'mbpkgid': node.id} result = self.connection.request( - API_ROOT + '/cloud/server/stop', + API_ROOT + '/cloud/server/shutdown', data=json.dumps(params), method='POST').object @@ -239,9 +262,9 @@ class HostVirtualNodeDriver(NodeDriver): return bool(result) - def ex_build_node(self, **kwargs): + def ex_provision_node(self, **kwargs): """ - Build a server on a VR package and get it booted + Provision a server on a VR package and get it booted @keyword node: node which should be used @type node: L{Node} @@ -255,7 +278,8 @@ class HostVirtualNodeDriver(NodeDriver): @keyword location: which datacenter to create the server in @type location: L{NodeLocation} - @rtype: C{bool} + @return: Node representing the newly built server + @rtype: L{Node} """ node = kwargs['node'] http://git-wip-us.apache.org/repos/asf/libcloud/blob/3386cfde/libcloud/test/compute/fixtures/hostvirtual/create_node.json ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/hostvirtual/create_node.json b/libcloud/test/compute/fixtures/hostvirtual/create_node.json index fd92b81..b9b3a09 100644 --- a/libcloud/test/compute/fixtures/hostvirtual/create_node.json +++ b/libcloud/test/compute/fixtures/hostvirtual/create_node.json @@ -1,17 +1,3 @@ { - "mbpkgid": "76070", - "package_status": "Active", - "domu_package": null, - "rescue": null, - "locked": null, - "state": null, - "installed": null, - "package": null, - "ipv6": "", - "city": null, - "fqdn": "test.com", - "uptime": false, - "ip": null, - "name": "VR512", - "status": "BUILDING" + "id": "62291" } http://git-wip-us.apache.org/repos/asf/libcloud/blob/3386cfde/libcloud/test/compute/test_hostvirtual.py ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/test_hostvirtual.py b/libcloud/test/compute/test_hostvirtual.py index 9a83b15..9b90554 100644 --- a/libcloud/test/compute/test_hostvirtual.py +++ b/libcloud/test/compute/test_hostvirtual.py @@ -103,13 +103,21 @@ class HostVirtualTest(unittest.TestCase): size=size, auth=auth ) - self.assertEqual('76070', node.id) - self.assertEqual('test.com', node.name) + self.assertEqual('62291', node.id) + self.assertEqual('server1.vr-cluster.org', node.name) - def test_ex_build_node(self): + def test_ex_provision_node(self): node = self.driver.list_nodes()[0] auth = NodeAuthPassword('vr!@#hosted#@!') - self.assertTrue(self.driver.ex_build_node( + self.assertTrue(self.driver.ex_provision_node( + node=node, + auth=auth + )) + + def test_ex_provision_node(self): + node = self.driver.list_nodes()[0] + auth = NodeAuthPassword('vr!@#hosted#@!') + self.assertTrue(self.driver.ex_provision_node( node=node, auth=auth )) @@ -126,8 +134,8 @@ class HostVirtualTest(unittest.TestCase): auth=auth, location=location ) - self.assertEqual('76070', node.id) - self.assertEqual('test.com', node.name) + self.assertEqual('62291', node.id) + self.assertEqual('server1.vr-cluster.org', node.name) class HostVirtualMockHttp(MockHttp): @@ -161,7 +169,7 @@ class HostVirtualMockHttp(MockHttp): body = self.fixtures.load('node_reboot.json') return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - def _vapi_cloud_server_stop(self, method, url, body, headers): + def _vapi_cloud_server_shutdown(self, method, url, body, headers): body = self.fixtures.load('node_stop.json') return (httplib.OK, body, {}, httplib.responses[httplib.OK]) @@ -169,7 +177,7 @@ class HostVirtualMockHttp(MockHttp): body = self.fixtures.load('node_start.json') return (httplib.OK, body, {}, httplib.responses[httplib.OK]) - def _vapi_cloud_buy_build(self, method, url, body, headers): + def _vapi_cloud_buy(self, method, url, body, headers): body = self.fixtures.load('create_node.json') return (httplib.OK, body, {}, httplib.responses[httplib.OK])
