diff --git a/ironic_python_agent/disk_utils.py b/ironic_python_agent/disk_utils.py index 6f00b36f2..662067106 100644 --- a/ironic_python_agent/disk_utils.py +++ b/ironic_python_agent/disk_utils.py @@ -152,21 +152,6 @@ def get_partition_table_type(device): return 'unknown' -def _blkid(device, probe=False, fields=None): - args = [] - if probe: - args.append('-p') - if fields: - args += sum((['-s', field] for field in fields), []) - - output, err = utils.execute('blkid', device, *args, - use_standard_locale=True) - if output.strip(): - return output.split(': ', 1)[1] - else: - return "" - - def _lsblk(device, deps=True, fields=None): args = ['--pairs', '--bytes', '--ascii'] if not deps: @@ -471,22 +456,38 @@ def get_and_validate_image_format(filename, ironic_disk_format): return img_format, size -def populate_image(src, dst, conv_flags=None, - source_format=None, is_raw=False): +def populate_image(src, dst, conv_flags=None, source_format=None, is_raw=False, + sparse_size='0', out_format='raw', **convert_args): """Populate a provided destination device with the image :param src: An image already security checked in format disk_format :param dst: A location, usually a partition or block device, to write the image :param conv_flags: Conversion flags to pass to dd if provided - :param source_format: format of the image :param is_raw: Ironic indicates image is raw; do not convert! + :param sparse_size: Sparse size to pass to qemu_img + :param source_format: format of the image + :param out_format: Output format + :param convert_args: Additional arguments to optionally pass to qemu_img """ - if is_raw: - dd(src, dst, conv_flags=conv_flags) - else: - qemu_img.convert_image(src, dst, 'raw', True, - sparse_size='0', source_format=source_format) + try: + if is_raw: + # NOTE(JayF): Since we do not safety check raw images, we must use + # dd to write them to ensure maximum security. This may cause + # failures in situations where images are configured as raw but + # are actually in need of conversion. Those cases can no longer + # be transparently handled safely. + LOG.info('Writing raw image %s to device %s', src, dst) + dd(src, dst, conv_flags=conv_flags) + else: + qemu_img.convert_image(src, dst, + out_format=out_format, + run_as_root=True, + sparse_size=sparse_size, + source_format=source_format, + **convert_args) + except processutils.ProcessExecutionError as e: + raise errors.ImageWriteError(dst, e.exit_code, e.stdout, e.stderr) def block_uuid(dev): @@ -718,8 +719,6 @@ def trigger_device_rescan(device, attempts=None): return True -# NOTE(dtantsur): this function was in ironic_lib.utils before migration -# (presumably to avoid a circular dependency with disk_partitioner) def wait_for_disk_to_become_available(device): """Wait for a disk device to become available. diff --git a/ironic_python_agent/extensions/standby.py b/ironic_python_agent/extensions/standby.py index 8cbb4f83e..2730d7783 100644 --- a/ironic_python_agent/extensions/standby.py +++ b/ironic_python_agent/extensions/standby.py @@ -31,7 +31,6 @@ from ironic_python_agent import errors from ironic_python_agent.extensions import base from ironic_python_agent import hardware from ironic_python_agent import partition_utils -from ironic_python_agent import qemu_img from ironic_python_agent import utils CONF = cfg.CONF @@ -355,33 +354,12 @@ def _write_whole_disk_image(image, image_info, device, source_format=None, # FIXME(dtantsur): pass the real node UUID for logging disk_utils.destroy_disk_metadata(device, '') disk_utils.udev_settle() - - try: - if is_raw: - # TODO(JayF): We should unify all these dd/convert_image calls - # into disk_utils.populate_image(). - # NOTE(JayF): Since we do not safety check raw images, we must use - # dd to write them to ensure maximum security. This may cause - # failures in situations where images are configured as raw but - # are actually in need of conversion. Those cases can no longer - # be transparently handled safely. - LOG.info('Writing raw image %s to device %s', image, device) - disk_utils.dd(image, device) - else: - command = ['qemu-img', 'convert', - '-t', 'directsync', '-S', '0', '-O', 'host_device', - '-W'] - if source_format: - command += ['-f', source_format] - command += [image, device] - LOG.info('Writing image with command: %s', ' '.join(command)) - qemu_img.convert_image(image, device, out_format='host_device', - cache='directsync', out_of_order=True, - sparse_size='0', - source_format=source_format) - except processutils.ProcessExecutionError as e: - raise errors.ImageWriteError(device, e.exit_code, e.stdout, e.stderr) - + disk_utils.populate_image(image, device, + is_raw=is_raw, + source_format=source_format, + out_format='host_device', + cache='directsync', + out_of_order=True) disk_utils.trigger_device_rescan(device) diff --git a/ironic_python_agent/partition_utils.py b/ironic_python_agent/partition_utils.py index 555f6a271..d3acdf296 100644 --- a/ironic_python_agent/partition_utils.py +++ b/ironic_python_agent/partition_utils.py @@ -300,7 +300,7 @@ def work_on_disk(dev, root_mb, swap_mb, ephemeral_mb, ephemeral_format, if image_path is not None: disk_utils.populate_image(image_path, root_part, conv_flags=conv_flags, - source_format=source_format, is_raw=is_raw) + is_raw=is_raw, source_format=source_format) LOG.info("Image for %(node)s successfully populated", {'node': node_uuid}) else: diff --git a/ironic_python_agent/tests/unit/extensions/test_standby.py b/ironic_python_agent/tests/unit/extensions/test_standby.py index ab514853b..e70abb50c 100644 --- a/ironic_python_agent/tests/unit/extensions/test_standby.py +++ b/ironic_python_agent/tests/unit/extensions/test_standby.py @@ -311,10 +311,11 @@ class TestStandbyExtension(base.IronicAgentTest): convert_mock.assert_called_once_with(location, device, out_format='host_device', - cache='directsync', - out_of_order=True, + run_as_root=True, sparse_size='0', - source_format=source_format) + source_format=source_format, + cache='directsync', + out_of_order=True) validate_mock.assert_called_once_with(location, source_format) wipe_mock.assert_called_once_with(device, '') udev_mock.assert_called_once_with() diff --git a/ironic_python_agent/tests/unit/test_disk_utils.py b/ironic_python_agent/tests/unit/test_disk_utils.py index 450b302ce..e66752f49 100644 --- a/ironic_python_agent/tests/unit/test_disk_utils.py +++ b/ironic_python_agent/tests/unit/test_disk_utils.py @@ -536,7 +536,9 @@ class PopulateImageTestCase(base.IronicAgentTest): source_format = 'qcow2' disk_utils.populate_image('src', 'dst', source_format=source_format, is_raw=False) - mock_cg.assert_called_once_with('src', 'dst', 'raw', True, + mock_cg.assert_called_once_with('src', 'dst', + out_format='raw', + run_as_root=True, sparse_size='0', source_format=source_format) self.assertFalse(mock_dd.called)