Raise exceptions when Spice/VNC are unavailable

Bug 1192724

Both Spice and/or VNC may be enabled from the perspective of compute
configuration but their actual availability can vary based on
whether either was enabled/disabled at the time the instance was
launched. This patch raises a proper exception in this case, such
that clients (including Horizon) can either message the user or fall
back.

Change-Id: If06e726e606f4a27c8ec4617400b728ce7112e3b
This commit is contained in:
Rafi Khardalian
2013-06-20 00:04:07 +00:00
parent 04c24587f9
commit cc8021df5f
3 changed files with 90 additions and 2 deletions

View File

@@ -839,6 +839,10 @@ class ConsoleTypeInvalid(Invalid):
msg_fmt = _("Invalid console type %(console_type)s")
class ConsoleTypeUnavailable(Invalid):
message = _("Unavailable console type %(console_type)s")
class InstanceTypeNotFound(NotFound):
msg_fmt = _("Instance type %(instance_type_id)s could not be found.")

View File

@@ -4204,6 +4204,86 @@ class LibvirtConnTestCase(test.TestCase):
power_on=False)
self.assertTrue(self.log_error_called)
def test_get_vnc_console(self):
instance_ref = db.instance_create(self.context, self.test_instance)
dummyxml = ("<domain type='kvm'><name>instance-0000000a</name>"
"<devices>"
"<graphics type='vnc' port='5900'/>"
"</devices></domain>")
vdmock = self.mox.CreateMock(libvirt.virDomain)
self.mox.StubOutWithMock(vdmock, "XMLDesc")
vdmock.XMLDesc(0).AndReturn(dummyxml)
def fake_lookup(instance_name):
if instance_name == instance_ref['name']:
return vdmock
self.create_fake_libvirt_mock(lookupByName=fake_lookup)
self.mox.ReplayAll()
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
vnc_dict = conn.get_vnc_console(instance_ref)
self.assertEquals(vnc_dict['port'], '5900')
def test_get_vnc_console_unavailable(self):
instance_ref = db.instance_create(self.context, self.test_instance)
dummyxml = ("<domain type='kvm'><name>instance-0000000a</name>"
"<devices></devices></domain>")
vdmock = self.mox.CreateMock(libvirt.virDomain)
self.mox.StubOutWithMock(vdmock, "XMLDesc")
vdmock.XMLDesc(0).AndReturn(dummyxml)
def fake_lookup(instance_name):
if instance_name == instance_ref['name']:
return vdmock
self.create_fake_libvirt_mock(lookupByName=fake_lookup)
self.mox.ReplayAll()
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.assertRaises(exception.ConsoleTypeUnavailable,
conn.get_vnc_console, instance_ref)
def test_get_spice_console(self):
instance_ref = db.instance_create(self.context, self.test_instance)
dummyxml = ("<domain type='kvm'><name>instance-0000000a</name>"
"<devices>"
"<graphics type='spice' port='5950'/>"
"</devices></domain>")
vdmock = self.mox.CreateMock(libvirt.virDomain)
self.mox.StubOutWithMock(vdmock, "XMLDesc")
vdmock.XMLDesc(0).AndReturn(dummyxml)
def fake_lookup(instance_name):
if instance_name == instance_ref['name']:
return vdmock
self.create_fake_libvirt_mock(lookupByName=fake_lookup)
self.mox.ReplayAll()
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
spice_dict = conn.get_spice_console(instance_ref)
self.assertEquals(spice_dict['port'], '5950')
def test_get_spice_console_unavailable(self):
instance_ref = db.instance_create(self.context, self.test_instance)
dummyxml = ("<domain type='kvm'><name>instance-0000000a</name>"
"<devices></devices></domain>")
vdmock = self.mox.CreateMock(libvirt.virDomain)
self.mox.StubOutWithMock(vdmock, "XMLDesc")
vdmock.XMLDesc(0).AndReturn(dummyxml)
def fake_lookup(instance_name):
if instance_name == instance_ref['name']:
return vdmock
self.create_fake_libvirt_mock(lookupByName=fake_lookup)
self.mox.ReplayAll()
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.assertRaises(exception.ConsoleTypeUnavailable,
conn.get_spice_console, instance_ref)
class HostStateTestCase(test.TestCase):

View File

@@ -1701,6 +1701,9 @@ class LibvirtDriver(driver.ComputeDriver):
for graphic in dom.getElementsByTagName('graphics'):
if graphic.getAttribute('type') == 'vnc':
return graphic.getAttribute('port')
# NOTE(rmk): We had VNC consoles enabled but the instance in
# question is not actually listening for connections.
raise exception.ConsoleTypeUnavailable(console_type='vnc')
port = get_vnc_port_for_instance(instance['name'])
host = CONF.vncserver_proxyclient_address
@@ -1719,8 +1722,9 @@ class LibvirtDriver(driver.ComputeDriver):
if graphic.getAttribute('type') == 'spice':
return (graphic.getAttribute('port'),
graphic.getAttribute('tlsPort'))
return (None, None)
# NOTE(rmk): We had Spice consoles enabled but the instance in
# question is not actually listening for connections.
raise exception.ConsoleTypeUnavailable(console_type='spice')
ports = get_spice_ports_for_instance(instance['name'])
host = CONF.spice.server_proxyclient_address