Return 409 error if get_vnc_console is called before VM is created
Fixes bug 1034117 In the xenapi driver, the URL returned for a VNC console will include information to locate the particular VM on the dom0, however the VM isn't create until part way through the build process. This leaves a window where a 404 error could be returned by the os-getVNCConsole action. Change this to return a 409 meaning it's not ready yet. Change-Id: Icc3b288d1aae12eb264b2be7fc8f9465d568af74
This commit is contained in:
parent
ce4b2e27be
commit
26b1523eba
|
@ -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']}}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue