Skip to content

Commit

Permalink
Make _rebase_with_qemu_img() generic
Browse files Browse the repository at this point in the history
Move volume_delete related logic away from this method, in order to make
it generic and usable elsewhere.

Change-Id: I17357d85f845d4160cb7c7784772530a1e92af76
Related-Bug: #1732428
(cherry picked from commit ce22034)
  • Loading branch information
Alexandre Arents authored and lyarwood committed Mar 16, 2021
1 parent 8cbb355 commit 2e89699
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 24 deletions.
19 changes: 19 additions & 0 deletions nova/tests/unit/virt/libvirt/test_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -25142,6 +25142,25 @@ def test_cache_image_existing(self, mock_fetch, mock_utime, mock_exists,
mock_et.assert_not_called()
mock_isdir.assert_not_called()

@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."""
Expand Down
42 changes: 18 additions & 24 deletions nova/virt/libvirt/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -2934,32 +2934,15 @@ def _wait_for_snapshot():
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.

: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
def _rebase_with_qemu_img(source_path, rebase_base):
"""Rebase a disk using qemu-img.
: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
Expand All @@ -2974,7 +2957,7 @@ def _rebase_with_qemu_img(guest, device, active_disk_object,
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,
Expand Down Expand Up @@ -3123,7 +3106,18 @@ def _get_snap_dev(filename, backing_store):
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:
Expand Down

0 comments on commit 2e89699

Please sign in to comment.