From 65a6264c236a779712694d2379cfe4f9e46e2732 Mon Sep 17 00:00:00 2001 From: Nikola Dipanov Date: Mon, 20 May 2013 17:36:49 +0200 Subject: Disallow resize if image not available If a resize is attempted on an instance that was started from an image that has since been deleted, a resize will fail. This change makes error reporting a bit cleaner. This change is needed since in order to actually properly support resize/migrate when the image is deleted - it is necessary for nova to keep a copy of the image metadata and re-use it in case of migration/resize. Fixes bug: 1160773 Fixes bug: 1177001 Change-Id: Ifaea71f79c97046a4cde094e3a5e676772fcceb4 --- nova/api/openstack/compute/servers.py | 11 +++++++++ .../api/openstack/compute/test_server_actions.py | 28 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py index 2df16c886..24b760401 100644 --- a/nova/api/openstack/compute/servers.py +++ b/nova/api/openstack/compute/servers.py @@ -1098,6 +1098,17 @@ class Controller(wsgi.Controller): except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state(state_error, 'resize') + except exception.ImageNotAuthorized as image_error: + msg = _("You are not authorized to access the image " + "the instance was started with.") + raise exc.HTTPUnauthorized(explanation=msg) + except exception.ImageNotFound as image_error: + msg = _("Image that the instance was started " + "with could not be found.") + raise exc.HTTPBadRequest(explanation=msg) + except exception.Invalid: + msg = _("Invalid instance image.") + raise exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202) diff --git a/nova/tests/api/openstack/compute/test_server_actions.py b/nova/tests/api/openstack/compute/test_server_actions.py index 3b8833dd7..473d3a253 100644 --- a/nova/tests/api/openstack/compute/test_server_actions.py +++ b/nova/tests/api/openstack/compute/test_server_actions.py @@ -630,6 +630,34 @@ class ServerActionsControllerTest(test.TestCase): self.controller._action_resize, req, FAKE_UUID, body) + def test_resize_with_image_exceptions(self): + body = dict(resize=dict(flavorRef="http://localhost/3")) + self.resize_called = 0 + image_id = 'fake_image_id' + + exceptions = [ + (exception.ImageNotAuthorized(image_id=image_id), + webob.exc.HTTPUnauthorized), + (exception.ImageNotFound(image_id=image_id), + webob.exc.HTTPBadRequest), + (exception.Invalid, webob.exc.HTTPBadRequest), + ] + + raised, expected = map(iter, zip(*exceptions)) + + def _fake_resize(obj, context, instance, flavor_id): + self.resize_called += 1 + raise raised.next() + + self.stubs.Set(compute_api.API, 'resize', _fake_resize) + + for call_no in range(len(exceptions)): + req = fakes.HTTPRequest.blank(self.url) + self.assertRaises(expected.next(), + self.controller._action_resize, + req, FAKE_UUID, body) + self.assertEqual(self.resize_called, call_no + 1) + def test_resize_with_too_many_instances(self): body = dict(resize=dict(flavorRef="http://localhost/3")) -- cgit