diff --git a/ironic/common/images.py b/ironic/common/images.py index 1707e95592..b80a47a341 100644 --- a/ironic/common/images.py +++ b/ironic/common/images.py @@ -273,8 +273,13 @@ def create_isolinux_image_for_uefi(output_file, kernel, ramdisk, grub_rel_path = CONF.grub_config_path.lstrip(' ' + os.sep) grub_cfg = os.path.join(tmpdir, grub_rel_path) + # Create an empty grub config file by copying /dev/null. + # This is to avoid write failures when actual write of + # config file happens. Write failures are caused if grub + # config path does not exist on root file system. uefi_path_info = { - esp_image: e_img_rel_path + esp_image: e_img_rel_path, + '/dev/null': grub_rel_path } else: diff --git a/ironic/tests/unit/common/test_images.py b/ironic/tests/unit/common/test_images.py index 2b84974487..86143fc96a 100644 --- a/ironic/tests/unit/common/test_images.py +++ b/ironic/tests/unit/common/test_images.py @@ -536,23 +536,25 @@ class FsImageTestCase(base.TestCase): 'path/to/efiboot.img', '-no-emul-boot', '-o', 'tgt_file', 'tmpdir') umount_mock.assert_called_once_with('mountdir') - @mock.patch.object(images, '_create_root_fs', autospec=True) @mock.patch.object(utils, 'write_to_file', autospec=True) + @mock.patch.object(images, '_create_root_fs', autospec=True) @mock.patch.object(utils, 'execute', autospec=True) @mock.patch.object(utils, 'tempdir', autospec=True) @mock.patch.object(images, '_generate_cfg', autospec=True) def test_create_isolinux_image_for_uefi_with_esp_image( self, gen_cfg_mock, tempdir_mock, execute_mock, - write_to_file_mock, create_root_fs_mock): + create_root_fs_mock, write_to_file_mock): files_info = { 'path/to/kernel': 'vmlinuz', 'path/to/ramdisk': 'initrd', 'sourceabspath/to/efiboot.img': 'boot/grub/efiboot.img', + '/dev/null': 'EFI/MYBOOT/grub.cfg', } + grub_cfg_file = '/EFI/MYBOOT/grub.cfg' + CONF.set_override('grub_config_path', grub_cfg_file) grubcfg = "grubcfg" - grub_file = 'tmpdir/boot/grub/grub.cfg' gen_cfg_mock.side_effect = (grubcfg,) params = ['a=b', 'c'] @@ -564,6 +566,7 @@ class FsImageTestCase(base.TestCase): mock_file_handle1 = mock.MagicMock(spec=file) mock_file_handle1.__enter__.return_value = 'mountdir' tempdir_mock.side_effect = mock_file_handle, mock_file_handle1 + mountdir_grub_cfg_path = 'tmpdir' + grub_cfg_file images.create_isolinux_image_for_uefi( 'tgt_file', 'path/to/kernel', 'path/to/ramdisk', @@ -572,7 +575,7 @@ class FsImageTestCase(base.TestCase): create_root_fs_mock.assert_called_once_with('tmpdir', files_info) gen_cfg_mock.assert_any_call(params, CONF.grub_config_template, grub_options) - write_to_file_mock.assert_any_call(grub_file, grubcfg) + write_to_file_mock.assert_any_call(mountdir_grub_cfg_path, grubcfg) execute_mock.assert_called_once_with( 'mkisofs', '-r', '-V', 'VMEDIA_BOOT_ISO', '-l', '-e', 'boot/grub/efiboot.img', '-no-emul-boot', '-o', 'tgt_file', diff --git a/releasenotes/notes/story-2006218-uefi-iso-creation-fails-ba0180991fdd0783.yaml b/releasenotes/notes/story-2006218-uefi-iso-creation-fails-ba0180991fdd0783.yaml new file mode 100644 index 0000000000..59fb845bb7 --- /dev/null +++ b/releasenotes/notes/story-2006218-uefi-iso-creation-fails-ba0180991fdd0783.yaml @@ -0,0 +1,9 @@ +--- +fixes: + - | + Fixes an issue in ISO creation for UEFI boot mode when efiboot.img + file is provided and the directory of location of grub.cfg file + set using config ``[DEFAULT]/grub_config_path`` is not same as + that of efiboot.img file. See `story 2006218 + `__ for details. +