summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/tests/test_xenapi.py12
-rw-r--r--nova/tests/xenapi/stubs.py19
-rw-r--r--nova/utils.py7
-rw-r--r--nova/virt/xenapi/vmops.py38
4 files changed, 54 insertions, 22 deletions
diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
index 66a973a78..e54ffe712 100644
--- a/nova/tests/test_xenapi.py
+++ b/nova/tests/test_xenapi.py
@@ -186,6 +186,7 @@ class XenAPIVMTestCase(test.TestCase):
stubs.stubout_stream_disk(self.stubs)
stubs.stubout_is_vdi_pv(self.stubs)
self.stubs.Set(VMOps, 'reset_network', reset_network)
+ stubs.stub_out_vm_methods(self.stubs)
glance_stubs.stubout_glance_client(self.stubs,
glance_stubs.FakeGlance)
self.conn = xenapi_conn.get_connection(False)
@@ -369,6 +370,17 @@ class XenAPIVMTestCase(test.TestCase):
self.assertEquals(vif_rec['qos_algorithm_params']['kbps'],
str(4 * 1024))
+ def test_rescue(self):
+ instance = self._create_instance()
+ conn = xenapi_conn.get_connection(False)
+ conn.rescue(instance, None)
+
+ def test_unrescue(self):
+ instance = self._create_instance()
+ conn = xenapi_conn.get_connection(False)
+ # Ensure that it will not unrescue a non-rescued instance.
+ self.assertRaises(Exception, conn.unrescue, instance, None)
+
def tearDown(self):
super(XenAPIVMTestCase, self).tearDown()
self.manager.delete_project(self.project)
diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py
index 7f9706a3d..7c33710c0 100644
--- a/nova/tests/xenapi/stubs.py
+++ b/nova/tests/xenapi/stubs.py
@@ -185,6 +185,25 @@ class FakeSessionForVMTests(fake.SessionBase):
pass
+def stub_out_vm_methods(stubs):
+ def fake_shutdown(self, inst, vm, method="clean"):
+ pass
+
+ def fake_acquire_bootlock(self, vm):
+ pass
+
+ def fake_release_bootlock(self, vm):
+ pass
+
+ def fake_spawn_rescue(self, inst):
+ pass
+
+ stubs.Set(vmops.VMOps, "_shutdown", fake_shutdown)
+ stubs.Set(vmops.VMOps, "_acquire_bootlock", fake_acquire_bootlock)
+ stubs.Set(vmops.VMOps, "_release_bootlock", fake_release_bootlock)
+ stubs.Set(vmops.VMOps, "spawn_rescue", fake_spawn_rescue)
+
+
class FakeSessionForVolumeTests(fake.SessionBase):
""" Stubs out a XenAPISession for Volume tests """
def __init__(self, uri):
diff --git a/nova/utils.py b/nova/utils.py
index 465f81250..fa01f2c94 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -341,11 +341,8 @@ utcnow.override_time = None
def is_older_than(before, seconds):
- """Return True if before is older than 'seconds'"""
- if utcnow() - before > datetime.timedelta(seconds=seconds):
- return True
- else:
- return False
+ """Return True if before is older than seconds"""
+ return utcnow() - before > datetime.timedelta(seconds=seconds)
def utcnow_ts():
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index af39a3def..419b9ad90 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -117,6 +117,10 @@ class VMOps(object):
vm_ref = self._create_vm(instance, vdi_uuid, network_info)
self._spawn(instance, vm_ref)
+ def spawn_rescue(self, instance):
+ """Spawn a rescue instance"""
+ self.spawn(instance)
+
def _create_vm(self, instance, vdi_uuid, network_info=None):
"""Create VM instance"""
instance_name = instance.name
@@ -543,7 +547,7 @@ class VMOps(object):
vbd_refs = self._session.get_xenapi().VM.get_VBDs(rescue_vm_ref)
for vbd_ref in vbd_refs:
vbd_rec = self._session.get_xenapi().VBD.get_record(vbd_ref)
- if vbd_rec["userdevice"] == "1": # primary VBD is always 1
+ if vbd_rec.get("userdevice", None) == "1": # VBD is always 1
VMHelper.unplug_vbd(self._session, vbd_ref)
VMHelper.destroy_vbd(self._session, vbd_ref)
@@ -680,18 +684,18 @@ class VMOps(object):
"""
rescue_vm_ref = VMHelper.lookup(self._session,
- instance.name + "-rescue")
+ "%s-rescue" % instance.name)
if rescue_vm_ref:
raise RuntimeError(_(
"Instance is already in Rescue Mode: %s" % instance.name))
- vm_ref = self._get_vm_opaque_ref(instance)
+ vm_ref = VMHelper.lookup(self._session, instance.name)
self._shutdown(instance, vm_ref)
self._acquire_bootlock(vm_ref)
instance._rescue = True
- self.spawn(instance)
- rescue_vm_ref = self._get_vm_opaque_ref(instance)
+ self.spawn_rescue(instance)
+ rescue_vm_ref = VMHelper.lookup(self._session, instance.name)
vbd_ref = self._session.get_xenapi().VM.get_VBDs(vm_ref)[0]
vdi_ref = self._session.get_xenapi().VBD.get_record(vbd_ref)["VDI"]
@@ -708,13 +712,13 @@ class VMOps(object):
"""
rescue_vm_ref = VMHelper.lookup(self._session,
- instance.name + "-rescue")
+ "%s-rescue" % instance.name)
if not rescue_vm_ref:
raise exception.NotFound(_(
"Instance is not in Rescue Mode: %s" % instance.name))
- original_vm_ref = self._get_vm_opaque_ref(instance)
+ original_vm_ref = VMHelper.lookup(self._session, instance.name)
instance._rescue = False
self._destroy_rescue_instance(rescue_vm_ref)
@@ -727,24 +731,24 @@ class VMOps(object):
in rescue mode for >= the provided timeout
"""
last_ran = self.poll_rescue_last_ran
- if last_ran:
- if not utils.is_older_than(last_ran, timeout):
- # Do not run. Let's bail.
- return
- else:
- # Update the time tracker and proceed.
- self.poll_rescue_last_ran = utils.utcnow()
- else:
+ if not last_ran:
# We need a base time to start tracking.
self.poll_rescue_last_ran = utils.utcnow()
return
+ if not utils.is_older_than(last_ran, timeout):
+ # Do not run. Let's bail.
+ return
+
+ # Update the time tracker and proceed.
+ self.poll_rescue_last_ran = utils.utcnow()
+
rescue_vms = []
for instance in self.list_instances():
if instance.endswith("-rescue"):
rescue_vms.append(dict(name=instance,
- vm_ref=VMHelper.lookup(self._session,
- instance)))
+ vm_ref=VMHelper.lookup(self._session,
+ instance)))
for vm in rescue_vms:
rescue_name = vm["name"]