Author: tomaz
Date: Tue Jan 10 23:34:18 2012
New Revision: 1229803
URL: http://svn.apache.org/viewvc?rev=1229803&view=rev
Log:
Return NodeImage instance in the OpenStack 1.1 node driver ex_save_image method.
This patch has been contributed by Shawn Smith <shawnpsmith at gmail dot com>
and is part of LIBCLOUD-138.
Modified:
libcloud/trunk/CHANGES
libcloud/trunk/libcloud/compute/drivers/openstack.py
libcloud/trunk/test/compute/test_openstack.py
Modified: libcloud/trunk/CHANGES
URL:
http://svn.apache.org/viewvc/libcloud/trunk/CHANGES?rev=1229803&r1=1229802&r2=1229803&view=diff
==============================================================================
--- libcloud/trunk/CHANGES (original)
+++ libcloud/trunk/CHANGES Tue Jan 10 23:34:18 2012
@@ -34,6 +34,10 @@ Changes with Apache Libcloud in developm
- Enable ex_delete_image method in the OpenStack 1.1 driver.
[Shawn Smith]
+ - Return NodeImage instance in OpenStack 1.1 driver ex_save_image method
+ ; LIBCLOUD-138
+ [Shawn Smith]
+
*) Storage:
- Propagate extra keyword arguments passed to the Rackspace driver
Modified: libcloud/trunk/libcloud/compute/drivers/openstack.py
URL:
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/openstack.py?rev=1229803&r1=1229802&r2=1229803&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/openstack.py (original)
+++ libcloud/trunk/libcloud/compute/drivers/openstack.py Tue Jan 10 23:34:18
2012
@@ -30,6 +30,7 @@ import warnings
from libcloud.utils.py3 import httplib
from libcloud.utils.py3 import b
from libcloud.utils.py3 import next
+from libcloud.utils.py3 import urlparse
import base64
@@ -934,8 +935,8 @@ class OpenStack_1_1_NodeDriver(OpenStack
optional_params['metadata'] = metadata
resp = self._node_action(node, 'createImage', name=name,
**optional_params)
- # TODO: concevt location header into NodeImage object
- return resp.status == httplib.ACCEPTED
+ image_id = self._extract_image_id_from_url(resp.headers['location'])
+ return self.ex_get_image(image_id=image_id)
def ex_set_server_name(self, node, name):
"""
@@ -1065,3 +1066,8 @@ class OpenStack_1_1_NodeDriver(OpenStack
)
except KeyError:
return(0.0)
+
+ def _extract_image_id_from_url(self, location_header):
+ path = urlparse.urlparse(location_header).path
+ image_id = path.split('/')[-1]
+ return image_id
Modified: libcloud/trunk/test/compute/test_openstack.py
URL:
http://svn.apache.org/viewvc/libcloud/trunk/test/compute/test_openstack.py?rev=1229803&r1=1229802&r2=1229803&view=diff
==============================================================================
--- libcloud/trunk/test/compute/test_openstack.py (original)
+++ libcloud/trunk/test/compute/test_openstack.py Tue Jan 10 23:34:18 2012
@@ -16,6 +16,11 @@ import sys
import unittest
import types
+try:
+ import simplejson as json
+except ImportError:
+ import json
+
from libcloud.utils.py3 import httplib
from libcloud.utils.py3 import method_type
from libcloud.utils.py3 import u
@@ -608,8 +613,9 @@ class OpenStack_1_1_Tests(unittest.TestC
self.fail('An error was raised: ' + repr(e))
def test_ex_save_image(self):
- result = self.driver.ex_save_image(self.node, 'new_image')
- self.assertTrue(result)
+ image = self.driver.ex_save_image(self.node, 'new_image')
+ self.assertEqual(image.name, 'new_image')
+ self.assertEqual(image.id, '4949f9ee-2421-4c81-8b49-13119446008b')
def test_ex_set_server_name(self):
old_node = Node(
@@ -673,6 +679,14 @@ class OpenStack_1_1_Tests(unittest.TestC
result = self.driver.ex_delete_image(image)
self.assertTrue(result)
+ def test_extract_image_id_from_url(self):
+ url =
'http://127.0.0.1/v1.1/68/images/1d4a8ea9-aae7-4242-a42d-5ff4702f2f14'
+ url_two = 'http://127.0.0.1/v1.1/68/images/13'
+ image_id = self.driver._extract_image_id_from_url(url)
+ image_id_two = self.driver._extract_image_id_from_url(url_two)
+ self.assertEqual(image_id, '1d4a8ea9-aae7-4242-a42d-5ff4702f2f14')
+ self.assertEqual(image_id_two, '13')
+
class OpenStack_1_1_FactoryMethodTests(OpenStack_1_1_Tests):
should_list_locations = False
@@ -736,6 +750,10 @@ class OpenStack_1_1_MockHttp(MockHttpTes
def _v1_1_slug_servers_12064_action(self, method, url, body, headers):
if method != "POST":
self.fail('HTTP method other than POST to action URL')
+ if "createImage" in json.loads(body):
+ return (httplib.ACCEPTED, "",
+ {"location":
"http://127.0.0.1/v1.1/68/images/4949f9ee-2421-4c81-8b49-13119446008b"},
+ httplib.responses[httplib.ACCEPTED])
return (httplib.ACCEPTED, "", {}, httplib.responses[httplib.ACCEPTED])
@@ -790,6 +808,13 @@ class OpenStack_1_1_MockHttp(MockHttpTes
else:
raise NotImplementedError()
+ def _v1_1_slug_images_4949f9ee_2421_4c81_8b49_13119446008b(self, method,
url, body, headers):
+ if method == "GET":
+ body =
self.fixtures.load('_images_4949f9ee_2421_4c81_8b49_13119446008b.json')
+ return (httplib.OK, body, self.json_content_headers,
httplib.responses[httplib.OK])
+ else:
+ raise NotImplementedError()
+
class OpenStack_1_1_Auth_2_0_MockHttp(OpenStack_1_1_MockHttp):
fixtures = ComputeFileFixtures('openstack_v1.1')
auth_fixtures = OpenStackFixtures()