diff --git a/Authors b/Authors index 2f38958ad901..a5b7ac22d1a6 100644 --- a/Authors +++ b/Authors @@ -34,6 +34,7 @@ Dave Walker David Pravec David Subiros Dean Troyer +Derek Higgins Devendra Modium Devin Carlen Donal Lafferty diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index 28af606bc70b..d0ca361add36 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -1063,6 +1063,25 @@ class LibvirtConnTestCase(test.TestCase): instance = db.instance_create(self.context, self.test_instance) conn.destroy(instance, {}) + @test.skip_if(missing_libvirt(), "Test requires libvirt") + def test_destroy_saved(self): + """Ensure destroy calls managedSaveRemove for saved instance""" + mock = self.mox.CreateMock(libvirt.virDomain) + mock.destroy() + mock.hasManagedSaveImage(0).AndReturn(1) + mock.managedSaveRemove(0) + mock.undefine() + + self.mox.ReplayAll() + + def fake_lookup_by_name(instance_name): + return mock + + conn = connection.LibvirtConnection(False) + self.stubs.Set(conn, '_lookup_by_name', fake_lookup_by_name) + instance = {"name": "instancename", "id": "instanceid"} + conn.destroy(instance, []) + class HostStateTestCase(test.TestCase): diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index c2a13f6a79aa..53a059052fe1 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -310,6 +310,17 @@ class LibvirtConnection(driver.ComputeDriver): locals()) raise + try: + # NOTE(derekh): we can switch to undefineFlags and + # VIR_DOMAIN_UNDEFINE_MANAGED_SAVE once we require 0.9.4 + if virt_dom.hasManagedSaveImage(0): + virt_dom.managedSaveRemove(0) + except libvirt.libvirtError as e: + errcode = e.get_error_code() + LOG.warning(_("Error from libvirt during saved instance " + "removal %(instance_name)s. Code=%(errcode)s" + " Error=%(e)s") % locals()) + try: # NOTE(justinsb): We remove the domain definition. We probably # would do better to keep it if cleanup=False (e.g. volumes?)