diff --git a/nova/api/openstack/compute/plugins/v3/servers.py b/nova/api/openstack/compute/plugins/v3/servers.py
index b7ec0a5cba8a..d4ef13525153 100644
--- a/nova/api/openstack/compute/plugins/v3/servers.py
+++ b/nova/api/openstack/compute/plugins/v3/servers.py
@@ -509,7 +509,8 @@ class ServersController(wsgi.Controller):
namespace=self.EXTENSION_CREATE_NAMESPACE,
check_func=_create_check_load_extension('server_create'),
invoke_on_load=True,
- invoke_kwds={"extension_info": self.extension_info})
+ invoke_kwds={"extension_info": self.extension_info},
+ propagate_map_exceptions=True)
if not list(self.create_extension_manager):
LOG.debug(_("Did not find any server create extensions"))
@@ -521,7 +522,8 @@ class ServersController(wsgi.Controller):
check_func=_create_check_load_extension(
'server_xml_extract_server_deserialize'),
invoke_on_load=True,
- invoke_kwds={"extension_info": self.extension_info})
+ invoke_kwds={"extension_info": self.extension_info},
+ propagate_map_exceptions=True)
if not list(self.create_xml_deserialize_manager):
LOG.debug(_("Did not find any server create xml deserializer"
" extensions"))
diff --git a/nova/tests/api/openstack/compute/plugins/v3/test_servers.py b/nova/tests/api/openstack/compute/plugins/v3/test_servers.py
index c13996a1c8b0..d2c9cbef21cd 100644
--- a/nova/tests/api/openstack/compute/plugins/v3/test_servers.py
+++ b/nova/tests/api/openstack/compute/plugins/v3/test_servers.py
@@ -30,7 +30,9 @@ import webob
from nova.api.openstack import compute
from nova.api.openstack.compute import plugins
+from nova.api.openstack.compute.plugins.v3 import availability_zone
from nova.api.openstack.compute.plugins.v3 import ips
+from nova.api.openstack.compute.plugins.v3 import keypairs
from nova.api.openstack.compute.plugins.v3 import servers
from nova.api.openstack.compute import views
from nova.api.openstack import xmlutil
@@ -2836,6 +2838,42 @@ class ServersControllerCreateTest(test.TestCase):
self._check_admin_pass_len(server)
self.assertEqual(FAKE_UUID, server['id'])
+ def test_create_instance_extension_create_exception(self):
+ def fake_keypair_server_create(self, server_dict,
+ create_kwargs):
+ raise KeyError
+
+ self.stubs.Set(keypairs.Keypairs, 'server_create',
+ fake_keypair_server_create)
+ # proper local hrefs must start with 'http://localhost/v3/'
+ image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
+ image_href = 'http://localhost/v3/images/%s' % image_uuid
+ flavor_ref = 'http://localhost/123/flavors/3'
+ body = {
+ 'server': {
+ 'name': 'server_test',
+ 'imageRef': image_href,
+ 'flavorRef': flavor_ref,
+ 'metadata': {
+ 'hello': 'world',
+ 'open': 'stack',
+ },
+ 'personality': [
+ {
+ "path": "/etc/banner.txt",
+ "contents": "MQ==",
+ },
+
+ ],
+ },
+ }
+
+ req = fakes.HTTPRequestV3.blank('/servers')
+ req.method = 'POST'
+ req.body = jsonutils.dumps(body)
+ req.headers["content-type"] = "application/json"
+ self.assertRaises(KeyError, self.controller.create, req, body)
+
def test_create_instance_pass_disabled(self):
self.flags(enable_instance_password=False)
# proper local hrefs must start with 'http://localhost/v3/'
@@ -3246,7 +3284,9 @@ class TestServerCreateRequestXMLDeserializer(test.TestCase):
def setUp(self):
super(TestServerCreateRequestXMLDeserializer, self).setUp()
- self.deserializer = servers.CreateDeserializer(None)
+ ext_info = plugins.LoadedExtensionInfo()
+ servers_controller = servers.ServersController(extension_info=ext_info)
+ self.deserializer = servers.CreateDeserializer(servers_controller)
def test_minimal_request(self):
serial_request = """
@@ -3264,6 +3304,23 @@ class TestServerCreateRequestXMLDeserializer(test.TestCase):
}
self.assertEquals(request['body'], expected)
+ def test_xml_create_exception(self):
+ def fake_availablity_extract_xml_deserialize(self,
+ server_node,
+ server_dict):
+ raise KeyError
+
+ self.stubs.Set(availability_zone.AvailabilityZone,
+ 'server_xml_extract_server_deserialize',
+ fake_availablity_extract_xml_deserialize)
+ serial_request = """
+"""
+ self.assertRaises(KeyError, self.deserializer.deserialize,
+ serial_request)
+
def test_request_with_alternate_namespace_prefix(self):
serial_request = """
=2.2.3,<3.0.0
python-glanceclient>=0.9.0
python-keystoneclient>=0.2.0
six
-stevedore>=0.9
+stevedore>=0.10
websockify<0.4
pyparsing>=1.5.7,<2.0 # order-dependent python-quantumclient req, bug 1191866