Recache or rebuild missing images on hard_reboot
The primary purpose of this change is to provide the ability to re-cache missing backing files on hard_reboot. The old pre_block_migration function was already performing a very similar operation. That function has been refactored to be idempotent and renamed to _create_images_and_backing. The pre_block_migration function is a wrapper, with some additional checking, around the renamed function. Image backend was also adjusted to look for either a missing backing file or disk image, recaching or creating accordingly. It should also be idempotent, never clobbering existing images. Change-Id: Icf4c488d6db59e732b463d08d0606b428ee1e7b9
This commit is contained in:
@@ -486,7 +486,8 @@ class HyperVAPITestCase(test.TestCase):
|
|||||||
constants.HYPERV_VM_STATE_REBOOT)
|
constants.HYPERV_VM_STATE_REBOOT)
|
||||||
|
|
||||||
self._mox.ReplayAll()
|
self._mox.ReplayAll()
|
||||||
self._conn.reboot(self._instance_data, network_info, None)
|
self._conn.reboot(self._context, self._instance_data, network_info,
|
||||||
|
None)
|
||||||
self._mox.VerifyAll()
|
self._mox.VerifyAll()
|
||||||
|
|
||||||
def test_destroy(self):
|
def test_destroy(self):
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ class _ImageTestCase(object):
|
|||||||
|
|
||||||
def test_cache(self):
|
def test_cache(self):
|
||||||
self.mox.StubOutWithMock(os.path, 'exists')
|
self.mox.StubOutWithMock(os.path, 'exists')
|
||||||
os.path.exists(self.PATH).AndReturn(False)
|
|
||||||
os.path.exists(self.TEMPLATE_DIR).AndReturn(False)
|
os.path.exists(self.TEMPLATE_DIR).AndReturn(False)
|
||||||
|
os.path.exists(self.PATH).AndReturn(False)
|
||||||
os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
|
os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
|
||||||
fn = self.mox.CreateMockAnything()
|
fn = self.mox.CreateMockAnything()
|
||||||
fn(target=self.TEMPLATE_PATH)
|
fn(target=self.TEMPLATE_PATH)
|
||||||
@@ -72,7 +72,9 @@ class _ImageTestCase(object):
|
|||||||
|
|
||||||
def test_cache_image_exists(self):
|
def test_cache_image_exists(self):
|
||||||
self.mox.StubOutWithMock(os.path, 'exists')
|
self.mox.StubOutWithMock(os.path, 'exists')
|
||||||
|
os.path.exists(self.TEMPLATE_DIR).AndReturn(True)
|
||||||
os.path.exists(self.PATH).AndReturn(True)
|
os.path.exists(self.PATH).AndReturn(True)
|
||||||
|
os.path.exists(self.TEMPLATE_PATH).AndReturn(True)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
image = self.image_class(self.INSTANCE, self.NAME)
|
image = self.image_class(self.INSTANCE, self.NAME)
|
||||||
@@ -82,8 +84,8 @@ class _ImageTestCase(object):
|
|||||||
|
|
||||||
def test_cache_base_dir_exists(self):
|
def test_cache_base_dir_exists(self):
|
||||||
self.mox.StubOutWithMock(os.path, 'exists')
|
self.mox.StubOutWithMock(os.path, 'exists')
|
||||||
os.path.exists(self.PATH).AndReturn(False)
|
|
||||||
os.path.exists(self.TEMPLATE_DIR).AndReturn(True)
|
os.path.exists(self.TEMPLATE_DIR).AndReturn(True)
|
||||||
|
os.path.exists(self.PATH).AndReturn(False)
|
||||||
os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
|
os.path.exists(self.TEMPLATE_PATH).AndReturn(False)
|
||||||
fn = self.mox.CreateMockAnything()
|
fn = self.mox.CreateMockAnything()
|
||||||
fn(target=self.TEMPLATE_PATH)
|
fn(target=self.TEMPLATE_PATH)
|
||||||
@@ -98,8 +100,8 @@ class _ImageTestCase(object):
|
|||||||
|
|
||||||
def test_cache_template_exists(self):
|
def test_cache_template_exists(self):
|
||||||
self.mox.StubOutWithMock(os.path, 'exists')
|
self.mox.StubOutWithMock(os.path, 'exists')
|
||||||
os.path.exists(self.PATH).AndReturn(False)
|
|
||||||
os.path.exists(self.TEMPLATE_DIR).AndReturn(True)
|
os.path.exists(self.TEMPLATE_DIR).AndReturn(True)
|
||||||
|
os.path.exists(self.PATH).AndReturn(False)
|
||||||
os.path.exists(self.TEMPLATE_PATH).AndReturn(True)
|
os.path.exists(self.TEMPLATE_PATH).AndReturn(True)
|
||||||
fn = self.mox.CreateMockAnything()
|
fn = self.mox.CreateMockAnything()
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
@@ -195,7 +197,6 @@ class Qcow2TestCase(_ImageTestCase, test.TestCase):
|
|||||||
def test_create_image_with_size(self):
|
def test_create_image_with_size(self):
|
||||||
fn = self.prepare_mocks()
|
fn = self.prepare_mocks()
|
||||||
fn(target=self.TEMPLATE_PATH)
|
fn(target=self.TEMPLATE_PATH)
|
||||||
self.mox.StubOutWithMock(os.path, 'exists')
|
|
||||||
imagebackend.libvirt_utils.create_cow_image(self.TEMPLATE_PATH,
|
imagebackend.libvirt_utils.create_cow_image(self.TEMPLATE_PATH,
|
||||||
self.PATH)
|
self.PATH)
|
||||||
imagebackend.disk.extend(self.PATH, self.SIZE)
|
imagebackend.disk.extend(self.PATH, self.SIZE)
|
||||||
|
|||||||
@@ -4206,7 +4206,7 @@ class LibvirtDriverTestCase(test.TestCase):
|
|||||||
|
|
||||||
self.counter = 0
|
self.counter = 0
|
||||||
|
|
||||||
def fake_get_instance_disk_info(instance):
|
def fake_get_instance_disk_info(instance, xml=None):
|
||||||
return '[]'
|
return '[]'
|
||||||
|
|
||||||
def fake_destroy(instance):
|
def fake_destroy(instance):
|
||||||
@@ -4251,7 +4251,7 @@ class LibvirtDriverTestCase(test.TestCase):
|
|||||||
'disk_size':'83886080'}]
|
'disk_size':'83886080'}]
|
||||||
disk_info_text = jsonutils.dumps(disk_info)
|
disk_info_text = jsonutils.dumps(disk_info)
|
||||||
|
|
||||||
def fake_get_instance_disk_info(instance):
|
def fake_get_instance_disk_info(instance, xml=None):
|
||||||
return disk_info_text
|
return disk_info_text
|
||||||
|
|
||||||
def fake_destroy(instance):
|
def fake_destroy(instance):
|
||||||
|
|||||||
@@ -104,6 +104,13 @@ class _FakeDriverBackendTestCase(object):
|
|||||||
def fake_make_drive(_self, _path):
|
def fake_make_drive(_self, _path):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def fake_get_instance_disk_info(_self, instance, xml=None):
|
||||||
|
return '[]'
|
||||||
|
|
||||||
|
self.stubs.Set(nova.virt.libvirt.driver.LibvirtDriver,
|
||||||
|
'get_instance_disk_info',
|
||||||
|
fake_get_instance_disk_info)
|
||||||
|
|
||||||
self.stubs.Set(nova.virt.libvirt.driver.disk,
|
self.stubs.Set(nova.virt.libvirt.driver.disk,
|
||||||
'extend', fake_extend)
|
'extend', fake_extend)
|
||||||
|
|
||||||
@@ -227,7 +234,8 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
|
|||||||
def test_reboot(self):
|
def test_reboot(self):
|
||||||
reboot_type = "SOFT"
|
reboot_type = "SOFT"
|
||||||
instance_ref, network_info = self._get_running_instance()
|
instance_ref, network_info = self._get_running_instance()
|
||||||
self.connection.reboot(instance_ref, network_info, reboot_type)
|
self.connection.reboot(self.ctxt, instance_ref, network_info,
|
||||||
|
reboot_type)
|
||||||
|
|
||||||
@catch_notimplementederror
|
@catch_notimplementederror
|
||||||
def test_get_host_ip_addr(self):
|
def test_get_host_ip_addr(self):
|
||||||
|
|||||||
@@ -199,14 +199,16 @@ class VMwareAPIVMTestCase(test.TestCase):
|
|||||||
info = self.conn.get_info({'name': 1})
|
info = self.conn.get_info({'name': 1})
|
||||||
self._check_vm_info(info, power_state.RUNNING)
|
self._check_vm_info(info, power_state.RUNNING)
|
||||||
reboot_type = "SOFT"
|
reboot_type = "SOFT"
|
||||||
self.conn.reboot(self.instance, self.network_info, reboot_type)
|
self.conn.reboot(self.context, self.instance, self.network_info,
|
||||||
|
reboot_type)
|
||||||
info = self.conn.get_info({'name': 1})
|
info = self.conn.get_info({'name': 1})
|
||||||
self._check_vm_info(info, power_state.RUNNING)
|
self._check_vm_info(info, power_state.RUNNING)
|
||||||
|
|
||||||
def test_reboot_non_existent(self):
|
def test_reboot_non_existent(self):
|
||||||
self._create_instance_in_the_db()
|
self._create_instance_in_the_db()
|
||||||
self.assertRaises(exception.InstanceNotFound, self.conn.reboot,
|
self.assertRaises(exception.InstanceNotFound, self.conn.reboot,
|
||||||
self.instance, self.network_info, 'SOFT')
|
self.context, self.instance, self.network_info,
|
||||||
|
'SOFT')
|
||||||
|
|
||||||
def test_reboot_not_poweredon(self):
|
def test_reboot_not_poweredon(self):
|
||||||
self._create_vm()
|
self._create_vm()
|
||||||
@@ -216,7 +218,8 @@ class VMwareAPIVMTestCase(test.TestCase):
|
|||||||
info = self.conn.get_info({'name': 1})
|
info = self.conn.get_info({'name': 1})
|
||||||
self._check_vm_info(info, power_state.SUSPENDED)
|
self._check_vm_info(info, power_state.SUSPENDED)
|
||||||
self.assertRaises(exception.InstanceRebootFailure, self.conn.reboot,
|
self.assertRaises(exception.InstanceRebootFailure, self.conn.reboot,
|
||||||
self.instance, self.network_info, 'SOFT')
|
self.context, self.instance, self.network_info,
|
||||||
|
'SOFT')
|
||||||
|
|
||||||
def test_suspend(self):
|
def test_suspend(self):
|
||||||
self._create_vm()
|
self._create_vm()
|
||||||
|
|||||||
@@ -954,12 +954,12 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
|
|||||||
def test_reboot_hard(self):
|
def test_reboot_hard(self):
|
||||||
instance = self._create_instance()
|
instance = self._create_instance()
|
||||||
conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
|
conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
|
||||||
conn.reboot(instance, None, "HARD")
|
conn.reboot(self.context, instance, None, "HARD")
|
||||||
|
|
||||||
def test_reboot_soft(self):
|
def test_reboot_soft(self):
|
||||||
instance = self._create_instance()
|
instance = self._create_instance()
|
||||||
conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
|
conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
|
||||||
conn.reboot(instance, None, "SOFT")
|
conn.reboot(self.context, instance, None, "SOFT")
|
||||||
|
|
||||||
def test_reboot_halted(self):
|
def test_reboot_halted(self):
|
||||||
session = xenapi_conn.XenAPISession('test_url', 'root', 'test_pass',
|
session = xenapi_conn.XenAPISession('test_url', 'root', 'test_pass',
|
||||||
@@ -967,7 +967,7 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
|
|||||||
instance = self._create_instance(spawn=False)
|
instance = self._create_instance(spawn=False)
|
||||||
conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
|
conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
|
||||||
xenapi_fake.create_vm(instance['name'], 'Halted')
|
xenapi_fake.create_vm(instance['name'], 'Halted')
|
||||||
conn.reboot(instance, None, "SOFT")
|
conn.reboot(self.context, instance, None, "SOFT")
|
||||||
vm_ref = vm_utils.lookup(session, instance['name'])
|
vm_ref = vm_utils.lookup(session, instance['name'])
|
||||||
vm = xenapi_fake.get_record('VM', vm_ref)
|
vm = xenapi_fake.get_record('VM', vm_ref)
|
||||||
self.assertEquals(vm['power_state'], 'Running')
|
self.assertEquals(vm['power_state'], 'Running')
|
||||||
@@ -976,8 +976,8 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
|
|||||||
instance = self._create_instance(spawn=False)
|
instance = self._create_instance(spawn=False)
|
||||||
conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
|
conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
|
||||||
xenapi_fake.create_vm(instance['name'], 'Unknown')
|
xenapi_fake.create_vm(instance['name'], 'Unknown')
|
||||||
self.assertRaises(xenapi_fake.Failure, conn.reboot, instance,
|
self.assertRaises(xenapi_fake.Failure, conn.reboot, self.context,
|
||||||
None, "SOFT")
|
instance, None, "SOFT")
|
||||||
|
|
||||||
def _test_maintenance_mode(self, find_host, find_aggregate):
|
def _test_maintenance_mode(self, find_host, find_aggregate):
|
||||||
real_call_xenapi = self.conn._session.call_xenapi
|
real_call_xenapi = self.conn._session.call_xenapi
|
||||||
|
|||||||
Reference in New Issue
Block a user