Merge "Make disk.extend() pass format to qemu-img"

This commit is contained in:
Zuul
2026-02-18 01:20:15 +00:00
committed by Gerrit Code Review
2 changed files with 46 additions and 5 deletions

View File

@@ -19,6 +19,7 @@ from unittest import mock
from oslo_concurrency import processutils
from oslo_utils import units
from nova import exception
from nova import test
from nova.virt.disk import api
from nova.virt.disk.mount import api as mount
@@ -128,7 +129,7 @@ class APITestCase(test.NoDBTestCase):
mock_can_resize.assert_called_once_with(imgfile, imgsize)
mock_exec.assert_called_once_with('qemu-img', 'resize',
imgfile, imgsize)
'-f', 'qcow2', imgfile, imgsize)
mock_extendable.assert_called_once_with(image)
mock_inst.assert_called_once_with(image, None, None)
mock_resize.assert_called_once_with(mounter.device,
@@ -154,8 +155,8 @@ class APITestCase(test.NoDBTestCase):
api.extend(image, imgsize)
mock_can_resize_image.assert_called_once_with(imgfile, imgsize)
mock_execute.assert_called_once_with('qemu-img', 'resize', imgfile,
imgsize)
mock_execute.assert_called_once_with('qemu-img', 'resize', '-f',
'qcow2', imgfile, imgsize)
self.assertFalse(mock_extendable.called)
@mock.patch.object(api, 'can_resize_image', autospec=True,
@@ -186,8 +187,34 @@ class APITestCase(test.NoDBTestCase):
api.extend(image, imgsize)
mock_exec.assert_has_calls(
[mock.call('qemu-img', 'resize', imgfile, imgsize),
[mock.call('qemu-img', 'resize', '-f', 'raw', imgfile, imgsize),
mock.call('e2label', image.path)])
mock_resize.assert_called_once_with(imgfile, run_as_root=False,
check_exit_code=[0])
mock_can_resize.assert_called_once_with(imgfile, imgsize)
@mock.patch.object(api, 'can_resize_image', autospec=True,
return_value=True)
@mock.patch.object(api, 'resize2fs', autospec=True)
@mock.patch('oslo_concurrency.processutils.execute', autospec=True)
def test_extend_vmdk_failure(self, mock_exec, mock_resize,
mock_can_resize):
imgfile = tempfile.NamedTemporaryFile()
self.addCleanup(imgfile.close)
imgsize = 10
# NOTE(danms): There is no image.model.FORMAT_VMDK, but since the
# code initializes this directly from Image.disk_format without using
# the constant (tsk), this can actually happen at runtime.
self.assertRaises(exception.InvalidImageFormat,
imgmodel.LocalFileImage, imgfile, 'vmdk')
# Patch ALL_FORMATS to include vmdk as if it got added at some point
with mock.patch('nova.virt.image.model.ALL_FORMATS',
new=['vmdk']):
image = imgmodel.LocalFileImage(imgfile, 'vmdk')
# Make sure that we still don't call qemu-img resize on the image
self.assertRaises(exception.InvalidDiskFormat,
api.extend, image, imgsize)
mock_exec.assert_not_called()

View File

@@ -123,7 +123,21 @@ def extend(image, size):
nova.privsep.libvirt.ploop_resize(image.path, size)
return
processutils.execute('qemu-img', 'resize', image.path, size)
# NOTE(danms): We should not call qemu-img without a format, and
# only qcow2 and raw are supported. So check which one we're being
# told this is supposed to be and pass that to qemu-img. Also note
# that we need to pass the qemu format string to this command, which
# may or may not be the same as the FORMAT_* constant, so be
# explicit here.
if image.format == imgmodel.FORMAT_RAW:
format = 'raw'
elif image.format == imgmodel.FORMAT_QCOW2:
format = 'qcow2'
else:
LOG.warning('Attempting to resize image %s with format %s, '
'which is not supported', image.path, image.format)
raise exception.InvalidDiskFormat(disk_format=image.format)
processutils.execute('qemu-img', 'resize', '-f', format, image.path, size)
if (image.format != imgmodel.FORMAT_RAW and
not CONF.resize_fs_using_block_device):