diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-08-07 22:43:42 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-08-07 22:43:42 +0000 |
| commit | 2dfee64d77aa800cc2f2d6ea7120322ffcec2207 (patch) | |
| tree | d69deac477773410102e8db1913bbfdc54c2a745 | |
| parent | f86a44e1bd1c32e521f8d28794d1c0569540cbb3 (diff) | |
| parent | 26b1523eba3805a497c23e3b6707a85670ee11be (diff) | |
Merge "Return 409 error if get_vnc_console is called before VM is created"
| -rw-r--r-- | nova/api/openstack/compute/contrib/consoles.py | 2 | ||||
| -rw-r--r-- | nova/exception.py | 4 | ||||
| -rw-r--r-- | nova/tests/api/openstack/compute/contrib/test_consoles.py | 17 | ||||
| -rw-r--r-- | nova/virt/xenapi/vmops.py | 17 |
4 files changed, 39 insertions, 1 deletions
diff --git a/nova/api/openstack/compute/contrib/consoles.py b/nova/api/openstack/compute/contrib/consoles.py index ef61d3966..4f88d033c 100644 --- a/nova/api/openstack/compute/contrib/consoles.py +++ b/nova/api/openstack/compute/contrib/consoles.py @@ -48,6 +48,8 @@ class ConsolesController(wsgi.Controller): console_type) except exception.InstanceNotFound as e: raise webob.exc.HTTPNotFound(explanation=unicode(e)) + except exception.InstanceNotReady as e: + raise webob.exc.HTTPConflict(explanation=unicode(e)) return {'console': {'type': console_type, 'url': output['url']}} diff --git a/nova/exception.py b/nova/exception.py index 9c579322b..7e3976d0f 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -327,6 +327,10 @@ class InstanceNotInRescueMode(Invalid): message = _("Instance %(instance_id)s is not in rescue mode") +class InstanceNotReady(Invalid): + message = _("Instance %(instance_id)s is not ready") + + class InstanceSuspendFailure(Invalid): message = _("Failed to suspend instance") + ": %(reason)s" diff --git a/nova/tests/api/openstack/compute/contrib/test_consoles.py b/nova/tests/api/openstack/compute/contrib/test_consoles.py index 8d727a556..887092806 100644 --- a/nova/tests/api/openstack/compute/contrib/test_consoles.py +++ b/nova/tests/api/openstack/compute/contrib/test_consoles.py @@ -31,6 +31,10 @@ def fake_get_vnc_console_invalid_type(self, _context, raise exception.ConsoleTypeInvalid(console_type=_console_type) +def fake_get_vnc_console_not_ready(self, _context, instance, _console_type): + raise exception.InstanceNotReady(instance_id=instance["uuid"]) + + def fake_get_vnc_console_not_found(self, _context, instance, _console_type): raise exception.InstanceNotFound(instance_id=instance["uuid"]) @@ -64,6 +68,19 @@ class ConsolesExtensionTest(test.TestCase): self.assertEqual(output, {u'console': {u'url': u'http://fake', u'type': u'novnc'}}) + def test_get_vnc_console_not_ready(self): + self.stubs.Set(compute.API, 'get_vnc_console', + fake_get_vnc_console_not_ready) + body = {'os-getVNCConsole': {'type': 'novnc'}} + req = webob.Request.blank('/v2/fake/servers/1/action') + req.method = "POST" + req.body = jsonutils.dumps(body) + req.headers["content-type"] = "application/json" + + res = req.get_response(fakes.wsgi_app()) + output = jsonutils.loads(res.body) + self.assertEqual(res.status_int, 409) + def test_get_vnc_console_no_type(self): self.stubs.Set(compute.API, 'get', fake_get) self.stubs.Set(compute.API, 'get_vnc_console', diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 8d443f498..05b2b1579 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -30,6 +30,7 @@ import netaddr from nova.compute import api as compute from nova.compute import power_state from nova.compute import vm_mode +from nova.compute import vm_states from nova import context as nova_context from nova import db from nova import exception @@ -1230,7 +1231,21 @@ class VMOps(object): def get_vnc_console(self, instance): """Return connection info for a vnc console.""" - vm_ref = self._get_vm_opaque_ref(instance) + # NOTE(johannes): This can fail if the VM object hasn't been created + # yet on the dom0. Since that step happens fairly late in the build + # process, there's a potential for a race condition here. Until the + # VM object is created, return back a 409 error instead of a 404 + # error. + try: + vm_ref = self._get_vm_opaque_ref(instance) + except exception.NotFound: + if instance['vm_state'] != vm_states.BUILDING: + raise + + LOG.info(_('Fetching VM ref while BUILDING failed'), + instance=instance) + raise exception.InstanceNotReady(instance_id=instance['uuid']) + session_id = self._session.get_session_id() path = "/console?ref=%s&session_id=%s" % (str(vm_ref), session_id) |
