From c61ceac5d0d0844db85791da167cf224ce360a5f Mon Sep 17 00:00:00 2001 From: Alexandre Arents Date: Tue, 26 Nov 2019 10:26:32 +0000 Subject: [PATCH] Make _rebase_with_qemu_img() generic Move volume_delete related logic away from this method, in order to make it generic and usable elsewhere. NOTE(lyarwood): Conflict caused by I52fbbcac9dc386f24ee81b3321dd0d8355e01976 landing in stbale/ussuri. Conflicts: nova/tests/unit/virt/libvirt/test_driver.py Change-Id: I17357d85f845d4160cb7c7784772530a1e92af76 Related-Bug: #1732428 (cherry picked from commit ce2203456660083119cdbb7e73c1ad15e6e0a074) (cherry picked from commit 2e89699c3301bf801784c637b6919752fcd3503f) --- nova/tests/unit/virt/libvirt/test_driver.py | 19 ++++++++++ nova/virt/libvirt/driver.py | 40 +++++++++------------ 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index 4fec9db3862b..540baf8ef588 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -23854,6 +23854,25 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin): '''], 1) + @mock.patch('nova.virt.images.qemu_img_info', + return_value=mock.Mock(file_format="fake_fmt")) + @mock.patch('oslo_concurrency.processutils.execute') + def test_rebase_with_qemu_img(self, mock_execute, mock_qemu_img_info): + """rebasing disk image to another backing file""" + self.drvr._rebase_with_qemu_img("disk", "backing_file") + mock_qemu_img_info.assert_called_once_with("backing_file") + mock_execute.assert_called_once_with('qemu-img', 'rebase', + '-b', 'backing_file', '-F', + 'fake_fmt', 'disk') + + # Flatten disk image when no backing file is given. + mock_qemu_img_info.reset_mock() + mock_execute.reset_mock() + self.drvr._rebase_with_qemu_img("disk", None) + self.assertEqual(0, mock_qemu_img_info.call_count) + mock_execute.assert_called_once_with('qemu-img', 'rebase', + '-b', '', 'disk') + class LibvirtVolumeUsageTestCase(test.NoDBTestCase): """Test for LibvirtDriver.get_all_volume_usage.""" diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index aead8470b299..786b494140c2 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -2861,32 +2861,15 @@ class LibvirtDriver(driver.ComputeDriver): timer.start(interval=0.5).wait() @staticmethod - def _rebase_with_qemu_img(guest, device, active_disk_object, - rebase_base): - """Rebase a device tied to a guest using qemu-img. + def _rebase_with_qemu_img(source_path, rebase_base): + """Rebase a disk using qemu-img. - :param guest:the Guest which owns the device being rebased - :type guest: nova.virt.libvirt.guest.Guest - :param device: the guest block device to rebase - :type device: nova.virt.libvirt.guest.BlockDevice - :param active_disk_object: the guest block device to rebase - :type active_disk_object: nova.virt.libvirt.config.\ - LibvirtConfigGuestDisk + :param source_path: the disk source path to rebase + :type source_path: string :param rebase_base: the new parent in the backing chain :type rebase_base: None or string """ - # It's unsure how well qemu-img handles network disks for - # every protocol. So let's be safe. - active_protocol = active_disk_object.source_protocol - if active_protocol is not None: - msg = _("Something went wrong when deleting a volume snapshot: " - "rebasing a %(protocol)s network disk using qemu-img " - "has not been fully tested") % {'protocol': - active_protocol} - LOG.error(msg) - raise exception.InternalError(msg) - if rebase_base is None: # If backing_file is specified as "" (the empty string), then # the image is rebased onto no backing file (i.e. it will exist @@ -2901,7 +2884,7 @@ class LibvirtDriver(driver.ComputeDriver): b_file_fmt = images.qemu_img_info(backing_file).file_format qemu_img_extra_arg = ['-F', b_file_fmt] - qemu_img_extra_arg.append(active_disk_object.source_path) + qemu_img_extra_arg.append(source_path) # execute operation with disk concurrency semaphore with compute_utils.disk_ops_semaphore: processutils.execute("qemu-img", "rebase", "-b", backing_file, @@ -3064,7 +3047,18 @@ class LibvirtDriver(driver.ComputeDriver): else: LOG.debug('Guest is not running so doing a block rebase ' 'using "qemu-img rebase"', instance=instance) - self._rebase_with_qemu_img(guest, dev, active_disk_object, + + # It's unsure how well qemu-img handles network disks for + # every protocol. So let's be safe. + active_protocol = active_disk_object.source_protocol + if active_protocol is not None: + msg = _("Something went wrong when deleting a volume " + "snapshot: rebasing a %(protocol)s network disk " + "using qemu-img has not been fully tested" + ) % {'protocol': active_protocol} + LOG.error(msg) + raise exception.InternalError(msg) + self._rebase_with_qemu_img(active_disk_object.source_path, rebase_base) else: