diff --git a/ironic_lib/disk_utils.py b/ironic_lib/disk_utils.py index cfcf6674..a2e3134b 100644 --- a/ironic_lib/disk_utils.py +++ b/ironic_lib/disk_utils.py @@ -501,7 +501,8 @@ def work_on_disk(dev, root_mb, swap_mb, ephemeral_mb, ephemeral_format, no ephemeral partition will be created. :param ephemeral_format: The type of file system to format the ephemeral partition. - :param image_path: Path for the instance's disk image. + :param image_path: Path for the instance's disk image. If ``None``, + the root partition is prepared but not populated. :param node_uuid: node's uuid. Used for logging. :param preserve_ephemeral: If True, no filesystem is written to the ephemeral block device, preserving whatever content it had (if the @@ -526,6 +527,7 @@ def work_on_disk(dev, root_mb, swap_mb, ephemeral_mb, ephemeral_format, 'root uuid': UUID of root partition 'efi system partition uuid': UUID of the uefi system partition (if boot mode is uefi). + `partitions`: mapping of partition types to their device paths. NOTE: If key exists but value is None, it means partition doesn't exist. """ @@ -595,9 +597,13 @@ def work_on_disk(dev, root_mb, swap_mb, ephemeral_mb, ephemeral_format, if configdrive_file: utils.unlink_without_raise(configdrive_file) - populate_image(image_path, root_part, conv_flags=conv_flags) - LOG.info("Image for %(node)s successfully populated", - {'node': node_uuid}) + if image_path is not None: + populate_image(image_path, root_part, conv_flags=conv_flags) + LOG.info("Image for %(node)s successfully populated", + {'node': node_uuid}) + else: + LOG.debug("Root partition for %s was created, but not populated", + node_uuid) if swap_part: utils.mkfs(fs='swap', path=swap_part, label='swap1') @@ -631,7 +637,7 @@ def work_on_disk(dev, root_mb, swap_mb, ephemeral_mb, ephemeral_format, with excutils.save_and_reraise_exception(): LOG.error("Failed to detect %s", part) - return uuids_to_return + return dict(partitions=part_dict, **uuids_to_return) def list_opts(): diff --git a/ironic_lib/tests/test_disk_utils.py b/ironic_lib/tests/test_disk_utils.py index 6d2ddfc6..2c311b47 100644 --- a/ironic_lib/tests/test_disk_utils.py +++ b/ironic_lib/tests/test_disk_utils.py @@ -200,6 +200,40 @@ class WorkOnDiskTestCase(base.IronicLibTestCase): cpu_arch="") mock_unlink.assert_called_once_with('fake-path') + @mock.patch.object(utils, 'mkfs', lambda fs, path, label=None: None) + @mock.patch.object(disk_utils, 'block_uuid', lambda p: 'uuid') + @mock.patch.object(disk_utils, 'populate_image', autospec=True) + def test_without_image(self, mock_populate): + ephemeral_part = '/dev/fake-part1' + swap_part = '/dev/fake-part2' + root_part = '/dev/fake-part3' + ephemeral_mb = 256 + ephemeral_format = 'exttest' + + self.mock_mp.return_value = {'ephemeral': ephemeral_part, + 'swap': swap_part, + 'root': root_part} + self.mock_ibd.return_value = True + calls = [mock.call(root_part), + mock.call(swap_part), + mock.call(ephemeral_part)] + res = disk_utils.work_on_disk(self.dev, self.root_mb, + self.swap_mb, ephemeral_mb, + ephemeral_format, + None, self.node_uuid) + self.assertEqual(self.mock_ibd.call_args_list, calls) + self.mock_mp.assert_called_once_with(self.dev, self.root_mb, + self.swap_mb, ephemeral_mb, + self.configdrive_mb, + self.node_uuid, commit=True, + boot_option="netboot", + boot_mode="bios", + disk_label=None, + cpu_arch="") + self.assertEqual(root_part, res['partitions']['root']) + self.assertEqual('uuid', res['root uuid']) + self.assertFalse(mock_populate.called) + @mock.patch.object(utils, 'mkfs', lambda fs, path, label=None: None) @mock.patch.object(disk_utils, 'block_uuid', lambda p: 'uuid') @mock.patch.object(disk_utils, 'populate_image', lambda image_path,