Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions nova/tests/unit/virt/disk/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
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
Expand Down Expand Up @@ -128,7 +129,7 @@ def test_extend_qcow_success(self, mock_exec, mock_inst, mock_resize,

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,
Expand All @@ -154,8 +155,8 @@ def test_extend_qcow_no_resize(self, mock_execute, mock_extendable,
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,
Expand Down Expand Up @@ -186,8 +187,34 @@ def test_extend_raw_success(self, mock_exec, mock_resize,
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()
16 changes: 15 additions & 1 deletion nova/virt/disk/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,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):
Expand Down