Merge "libvirt: Don't re-resize disks in finish_migration()"
This commit is contained in:
@@ -15692,19 +15692,6 @@ class LibvirtDriverTestCase(test.NoDBTestCase):
|
||||
self.drvr._wait_for_running({'name': 'else',
|
||||
'uuid': 'other_uuid'})
|
||||
|
||||
def test_disk_size_from_instance_disk_info(self):
|
||||
flavor_data = {'root_gb': 10, 'ephemeral_gb': 20, 'swap_gb': 30}
|
||||
inst = objects.Instance(flavor=objects.Flavor(**flavor_data))
|
||||
self.assertEqual(10 * units.Gi,
|
||||
self.drvr._disk_size_from_instance(inst, 'disk'))
|
||||
|
||||
self.assertEqual(20 * units.Gi,
|
||||
self.drvr._disk_size_from_instance(inst,
|
||||
'disk.local'))
|
||||
|
||||
self.assertEqual(0,
|
||||
self.drvr._disk_size_from_instance(inst, 'disk.swap'))
|
||||
|
||||
@mock.patch('nova.utils.execute')
|
||||
def test_disk_raw_to_qcow2(self, mock_execute):
|
||||
path = '/test/disk'
|
||||
@@ -15727,40 +15714,6 @@ class LibvirtDriverTestCase(test.NoDBTestCase):
|
||||
'-O', 'raw', path, _path_raw),
|
||||
mock.call('mv', _path_raw, path)])
|
||||
|
||||
@mock.patch('nova.virt.disk.api.extend')
|
||||
def test_disk_resize_raw(self, mock_extend):
|
||||
image = imgmodel.LocalFileImage("/test/disk",
|
||||
imgmodel.FORMAT_RAW)
|
||||
|
||||
self.drvr._disk_resize(image, 50)
|
||||
mock_extend.assert_called_once_with(image, 50)
|
||||
|
||||
@mock.patch('nova.virt.disk.api.can_resize_image')
|
||||
@mock.patch('nova.virt.disk.api.is_image_extendable')
|
||||
@mock.patch('nova.virt.disk.api.extend')
|
||||
def test_disk_resize_qcow2(
|
||||
self, mock_extend, mock_can_resize, mock_is_image_extendable):
|
||||
|
||||
with test.nested(
|
||||
mock.patch.object(
|
||||
self.drvr, '_disk_qcow2_to_raw'),
|
||||
mock.patch.object(
|
||||
self.drvr, '_disk_raw_to_qcow2'))\
|
||||
as (mock_disk_qcow2_to_raw, mock_disk_raw_to_qcow2):
|
||||
|
||||
mock_can_resize.return_value = True
|
||||
mock_is_image_extendable.return_value = True
|
||||
|
||||
imageqcow2 = imgmodel.LocalFileImage("/test/disk",
|
||||
imgmodel.FORMAT_QCOW2)
|
||||
imageraw = imgmodel.LocalFileImage("/test/disk",
|
||||
imgmodel.FORMAT_RAW)
|
||||
self.drvr._disk_resize(imageqcow2, 50)
|
||||
|
||||
mock_disk_qcow2_to_raw.assert_called_once_with(imageqcow2.path)
|
||||
mock_extend.assert_called_once_with(imageraw, 50)
|
||||
mock_disk_raw_to_qcow2.assert_called_once_with(imageqcow2.path)
|
||||
|
||||
@mock.patch.object(libvirt_driver.LibvirtDriver, '_inject_data')
|
||||
@mock.patch.object(libvirt_driver.LibvirtDriver, 'get_info')
|
||||
@mock.patch.object(libvirt_driver.LibvirtDriver,
|
||||
@@ -15812,11 +15765,10 @@ class LibvirtDriverTestCase(test.NoDBTestCase):
|
||||
mock_create_domain_and_network.return_value = \
|
||||
libvirt_guest.Guest('fake_dom')
|
||||
|
||||
with mock.patch.object(self.drvr, '_disk_resize') as mock_disk_resize:
|
||||
self.drvr.finish_migration(
|
||||
context.get_admin_context(), migration, instance,
|
||||
disk_info, [], image_meta,
|
||||
resize_instance, bdi, power_on)
|
||||
self.drvr.finish_migration(
|
||||
context.get_admin_context(), migration, instance,
|
||||
disk_info, [], image_meta,
|
||||
resize_instance, bdi, power_on)
|
||||
|
||||
# Assert that we converted the root, ephemeral, and swap disks
|
||||
instance_path = libvirt_utils.get_instance_path(instance)
|
||||
@@ -15827,21 +15779,6 @@ class LibvirtDriverTestCase(test.NoDBTestCase):
|
||||
# Implicitly assert that we did not convert the config disk
|
||||
self.assertEqual(len(convert_calls), mock_raw_to_qcow2.call_count)
|
||||
|
||||
if resize_instance:
|
||||
# Assert that we're calling _disk_resize on all local disks
|
||||
def local_file(name):
|
||||
return imgmodel.LocalFileImage(backend.disks[name].path, 'raw')
|
||||
|
||||
resize_calls = [
|
||||
mock.call(local_file('disk'),
|
||||
instance.flavor.root_gb * units.Gi),
|
||||
mock.call(local_file('disk.local'),
|
||||
instance.flavor.ephemeral_gb * units.Gi),
|
||||
mock.call(local_file('disk.swap'), 0),
|
||||
mock.call(local_file('disk.config'), 0),
|
||||
]
|
||||
mock_disk_resize.assert_has_calls(resize_calls, any_order=True)
|
||||
|
||||
disks = backend.disks
|
||||
|
||||
# Assert that we called cache() on kernel, ramdisk, disk,
|
||||
|
||||
@@ -7217,27 +7217,6 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
LOG.info(_LI("Instance running successfully."), instance=instance)
|
||||
raise loopingcall.LoopingCallDone()
|
||||
|
||||
@staticmethod
|
||||
def _disk_size_from_instance(instance, disk_name):
|
||||
"""Determines the disk size from instance properties
|
||||
|
||||
Returns the disk size by using the disk name to determine whether it
|
||||
is a root or an ephemeral disk, then by checking properties of the
|
||||
instance returns the size converted to bytes.
|
||||
|
||||
Returns 0 if the disk name not match (disk, disk.local).
|
||||
"""
|
||||
if disk_name == 'disk':
|
||||
size = instance.flavor.root_gb
|
||||
elif disk_name == 'disk.local':
|
||||
size = instance.flavor.ephemeral_gb
|
||||
# N.B. We don't handle ephemeral disks named disk.ephN here,
|
||||
# which is almost certainly a bug. It's not clear what this function
|
||||
# should return if an instance has multiple ephemeral disks.
|
||||
else:
|
||||
size = 0
|
||||
return size * units.Gi
|
||||
|
||||
@staticmethod
|
||||
def _disk_raw_to_qcow2(path):
|
||||
"""Converts a raw disk to qcow2."""
|
||||
@@ -7254,41 +7233,6 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
'-O', 'raw', path, path_raw)
|
||||
utils.execute('mv', path_raw, path)
|
||||
|
||||
def _disk_resize(self, image, size):
|
||||
"""Attempts to resize a disk to size
|
||||
|
||||
:param image: an instance of nova.virt.image.model.Image
|
||||
|
||||
Attempts to resize a disk by checking the capabilities and
|
||||
preparing the format, then calling disk.api.extend.
|
||||
|
||||
Note: Currently only support disk extend.
|
||||
"""
|
||||
|
||||
if not isinstance(image, imgmodel.LocalFileImage):
|
||||
LOG.debug("Skipping resize of non-local image")
|
||||
return
|
||||
|
||||
# If we have a non partitioned image that we can extend
|
||||
# then ensure we're in 'raw' format so we can extend file system.
|
||||
converted = False
|
||||
if (size and
|
||||
image.format == imgmodel.FORMAT_QCOW2 and
|
||||
disk_api.can_resize_image(image.path, size) and
|
||||
disk_api.is_image_extendable(image)):
|
||||
self._disk_qcow2_to_raw(image.path)
|
||||
converted = True
|
||||
image = imgmodel.LocalFileImage(image.path,
|
||||
imgmodel.FORMAT_RAW)
|
||||
|
||||
if size:
|
||||
disk_api.extend(image, size)
|
||||
|
||||
if converted:
|
||||
# back to qcow2 (no backing_file though) so that snapshot
|
||||
# will be available
|
||||
self._disk_raw_to_qcow2(image.path)
|
||||
|
||||
def finish_migration(self, context, migration, instance, disk_info,
|
||||
network_info, image_meta, resize_instance,
|
||||
block_device_info=None, power_on=True):
|
||||
@@ -7314,21 +7258,13 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
context, instance,
|
||||
network_info=network_info)
|
||||
|
||||
# Resize root disk and a single ephemeral disk called disk.local
|
||||
# Also convert raw disks to qcow2 if migrating to host which uses
|
||||
# Convert raw disks to qcow2 if migrating to host which uses
|
||||
# qcow2 from host which uses raw.
|
||||
# TODO(mbooth): Handle resize of multiple ephemeral disks, and
|
||||
# ephemeral disks not called disk.local.
|
||||
disk_info = jsonutils.loads(disk_info)
|
||||
for info in disk_info:
|
||||
path = info['path']
|
||||
disk_name = os.path.basename(path)
|
||||
|
||||
size = self._disk_size_from_instance(instance, disk_name)
|
||||
if resize_instance:
|
||||
image = imgmodel.LocalFileImage(path, info['type'])
|
||||
self._disk_resize(image, size)
|
||||
|
||||
# NOTE(mdbooth): The code below looks wrong, but is actually
|
||||
# required to prevent a security hole when migrating from a host
|
||||
# with use_cow_images=False to one with use_cow_images=True.
|
||||
|
||||
Reference in New Issue
Block a user