summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSulochan Acharya <sulochan@gmail.com>2013-03-19 15:05:27 -0500
committerSulochan Acharya <sulochan@gmail.com>2013-03-22 07:47:41 -0500
commite136de1aea8d1469465272942fa3d2769cbe3a80 (patch)
tree96395293aaf9f2368213d6414923fa42fbb5ebbb
parent07694d4ffa2b64b7cb21d76af70b8f0df1166915 (diff)
xenapi: fix console for rescued instance
Check if the instance is in vm_state RESCUED and if so change the name-label to reflect that. Name label is used to get vm ref and currently the original instance is being referenced even when in rescue mode. If rescue vm is not ready yet, InstanceNotReady is raised. Added tests cases for xenapi get_vnc_console for instance and rescue mode. Fixes bug #1157389 Change-Id: I5438103d517c40c1c87ddecd5f88b1487bfc0339
-rw-r--r--nova/tests/test_xenapi.py56
-rw-r--r--nova/virt/xenapi/vmops.py17
2 files changed, 68 insertions, 5 deletions
diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
index 275abfaea..8d00aa924 100644
--- a/nova/tests/test_xenapi.py
+++ b/nova/tests/test_xenapi.py
@@ -419,6 +419,62 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
expected = self.conn.get_diagnostics(instance)
self.assertThat(fake_diagnostics, matchers.DictMatches(expected))
+ def test_get_vnc_console(self):
+ instance = self._create_instance()
+ session = xenapi_conn.XenAPISession('test_url', 'root', 'test_pass',
+ fake.FakeVirtAPI())
+ conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
+ vm_ref = vm_utils.lookup(session, instance['name'])
+
+ console = conn.get_vnc_console(instance)
+
+ # Note(sulo): We dont care about session id in test
+ # they will always differ so strip that out
+ actual_path = console['internal_access_path'].split('&')[0]
+ expected_path = "/console?ref=%s" % str(vm_ref)
+
+ self.assertEqual(expected_path, actual_path)
+
+ def test_get_vnc_console_for_rescue(self):
+ instance = self._create_instance()
+ session = xenapi_conn.XenAPISession('test_url', 'root', 'test_pass',
+ fake.FakeVirtAPI())
+ conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
+ rescue_vm = xenapi_fake.create_vm(instance['name'] + '-rescue',
+ 'Running')
+ # Set instance state to rescued
+ instance['vm_state'] = 'rescued'
+
+ console = conn.get_vnc_console(instance)
+
+ # Note(sulo): We dont care about session id in test
+ # they will always differ so strip that out
+ actual_path = console['internal_access_path'].split('&')[0]
+ expected_path = "/console?ref=%s" % str(rescue_vm)
+
+ self.assertEqual(expected_path, actual_path)
+
+ def test_get_vnc_console_instance_not_ready(self):
+ instance = {}
+ # set instance name and state
+ instance['name'] = 'fake-instance'
+ instance['uuid'] = '00000000-0000-0000-0000-000000000000'
+ instance['vm_state'] = 'building'
+
+ conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
+ self.assertRaises(exception.InstanceNotFound,
+ conn.get_vnc_console, instance)
+
+ def test_get_vnc_console_rescue_not_ready(self):
+ instance = {}
+ instance['name'] = 'fake-rescue'
+ instance['uuid'] = '00000000-0000-0000-0000-000000000001'
+ instance['vm_state'] = 'rescued'
+
+ conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
+ self.assertRaises(exception.InstanceNotReady,
+ conn.get_vnc_console, instance)
+
def test_instance_snapshot_fails_with_no_primary_vdi(self):
def create_bad_vbd(session, vm_ref, vdi_ref, userdevice,
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index 8728a46a4..ce3301fd9 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -33,6 +33,7 @@ from nova.compute import instance_types
from nova.compute import power_state
from nova.compute import task_states
from nova.compute import vm_mode
+from nova.compute import vm_states
from nova import context as nova_context
from nova import exception
from nova.openstack.common import excutils
@@ -1365,11 +1366,17 @@ class VMOps(object):
def get_vnc_console(self, instance):
"""Return connection info for a vnc console."""
- try:
- vm_ref = self._get_vm_opaque_ref(instance)
- except exception.NotFound:
- # The compute manager expects InstanceNotFound for this case.
- raise exception.InstanceNotFound(instance_id=instance['uuid'])
+ if instance['vm_state'] == vm_states.RESCUED:
+ name = '%s-rescue' % instance['name']
+ vm_ref = vm_utils.lookup(self._session, name)
+ if vm_ref is None:
+ # The rescue instance might not be ready at this point.
+ raise exception.InstanceNotReady(instance_id=instance['uuid'])
+ else:
+ vm_ref = vm_utils.lookup(self._session, instance['name'])
+ if vm_ref is None:
+ # The compute manager expects InstanceNotFound for this case.
+ raise exception.InstanceNotFound(instance_id=instance['uuid'])
session_id = self._session.get_session_id()
path = "/console?ref=%s&session_id=%s" % (str(vm_ref), session_id)