Inject a randomized publisher id

To serve as a mechanism to allow an interlocking device identification
this patch injects a publisher id value into ISO images *and* the kernel
command line for any software running from the ISO image to match
the ISO in use to the location of data housed locally from within the
image.

Some differences exist with this patch due to refactoring changes in
I8567a10b77cdc3785686b79defcdafd75af53df0 where the basic flow and
logic was simplified just enough to require the logic to change
a little bit. Furthermore, even going to 2023.1, some default
configuration options were also removed as they were centered
around GRUB v1.

Related-Bug: 2032377
Change-Id: I9b74ec977fabc0a7f8ed6f113595a3f1624f6ee6
(cherry picked from commit fb850e7f00)
(cherry picked from commit 78c1d9a98d)
(cherry picked from commit c71e124f9c)
This commit is contained in:
Julia Kreger 2024-04-03 12:56:57 -07:00
parent e62fd36381
commit 1060a570b7
5 changed files with 164 additions and 62 deletions

View File

@ -175,7 +175,8 @@ def _label(files_info):
def create_isolinux_image_for_bios(
output_file, kernel, ramdisk, kernel_params=None, inject_files=None):
output_file, kernel, ramdisk, kernel_params=None, inject_files=None,
publisher_id=None):
"""Creates an isolinux image on the specified file.
Copies the provided kernel, ramdisk to a directory, generates the isolinux
@ -191,6 +192,8 @@ def create_isolinux_image_for_bios(
as the kernel cmdline.
:param inject_files: Mapping of local source file paths to their location
on the final ISO image.
:param publisher_id: A value to set as the publisher identifier string
in the ISO image to be generated.
:raises: ImageCreationFailed, if image creation failed while copying files
or while running command to generate iso.
"""
@ -237,9 +240,12 @@ def create_isolinux_image_for_bios(
isolinux_cfg = os.path.join(tmpdir, ISOLINUX_CFG)
utils.write_to_file(isolinux_cfg, cfg)
# Set a publisher ID value to a string.
pub_id = str(publisher_id)
try:
utils.execute('mkisofs', '-r', '-V', _label(files_info),
'-J', '-l', '-no-emul-boot',
'-J', '-l', '-publisher', pub_id, '-no-emul-boot',
'-boot-load-size', '4', '-boot-info-table',
'-b', ISOLINUX_BIN, '-o', output_file, tmpdir)
except processutils.ProcessExecutionError as e:
@ -249,7 +255,7 @@ def create_isolinux_image_for_bios(
def create_esp_image_for_uefi(
output_file, kernel, ramdisk, deploy_iso=None, esp_image=None,
kernel_params=None, inject_files=None):
kernel_params=None, inject_files=None, publisher_id=None):
"""Creates an ESP image on the specified file.
Copies the provided kernel, ramdisk and EFI system partition image (ESP) to
@ -271,6 +277,8 @@ def create_esp_image_for_uefi(
as the kernel cmdline.
:param inject_files: Mapping of local source file paths to their location
on the final ISO image.
:param publisher_id: A value to set as the publisher identifier string
in the ISO image to be generated.
:raises: ImageCreationFailed, if image creation failed while copying files
or while running command to generate iso.
"""
@ -337,10 +345,18 @@ def create_esp_image_for_uefi(
utils.write_to_file(grub_cfg, grub_conf)
# Create the boot_iso.
if publisher_id:
args = ('mkisofs', '-r', '-V', _label(files_info),
'-l', '-publisher', publisher_id, '-e', e_img_rel_path,
'-no-emul-boot', '-o', output_file,
tmpdir)
else:
args = ('mkisofs', '-r', '-V', _label(files_info),
'-l', '-e', e_img_rel_path,
'-no-emul-boot', '-o', output_file,
tmpdir)
try:
utils.execute('mkisofs', '-r', '-V', _label(files_info),
'-l', '-e', e_img_rel_path, '-no-emul-boot',
'-o', output_file, tmpdir)
utils.execute(*args)
except processutils.ProcessExecutionError as e:
LOG.exception("Creating ISO image failed.")
@ -498,7 +514,7 @@ def get_temp_url_for_glance_image(context, image_uuid):
def create_boot_iso(context, output_filename, kernel_href,
ramdisk_href, deploy_iso_href=None, esp_image_href=None,
root_uuid=None, kernel_params=None, boot_mode=None,
inject_files=None):
inject_files=None, publisher_id=None):
"""Creates a bootable ISO image for a node.
Given the hrefs for kernel, ramdisk, root partition's UUID and
@ -524,6 +540,8 @@ def create_boot_iso(context, output_filename, kernel_href,
:boot_mode: the boot mode in which the deploy is to happen.
:param inject_files: Mapping of local source file paths to their location
on the final ISO image.
:param publisher_id: A value to set as the publisher identifier string
in the ISO image to be generated.
:raises: ImageCreationFailed, if creating boot ISO failed.
"""
with utils.tempdir() as tmpdir:
@ -560,12 +578,14 @@ def create_boot_iso(context, output_filename, kernel_href,
create_esp_image_for_uefi(
output_filename, kernel_path, ramdisk_path,
deploy_iso=deploy_iso_path, esp_image=esp_image_path,
kernel_params=params, inject_files=inject_files)
kernel_params=params, inject_files=inject_files,
publisher_id=publisher_id)
else:
create_isolinux_image_for_bios(
output_filename, kernel_path, ramdisk_path,
kernel_params=params, inject_files=inject_files)
kernel_params=params, inject_files=inject_files,
publisher_id=publisher_id)
IMAGE_TYPE_PARTITION = 'partition'

View File

@ -24,6 +24,7 @@ from urllib import parse as urlparse
from ironic_lib import utils as ironic_utils
from oslo_log import log
from oslo_utils import uuidutils
from ironic.common import exception
from ironic.common.glance_service import service_utils
@ -494,6 +495,10 @@ def _prepare_iso_image(task, kernel_href, ramdisk_href,
img_handler = ImageHandler(task.node.driver)
boot_mode = boot_mode_utils.get_boot_mode(task.node)
if not is_ramdisk_boot:
publisher_id = uuidutils.generate_uuid()
else:
publisher_id = None
with tempfile.TemporaryDirectory(dir=CONF.tempdir) as boot_file_dir:
@ -516,6 +521,7 @@ def _prepare_iso_image(task, kernel_href, ramdisk_href,
else:
kernel_params = driver_utils.get_kernel_append_params(
task.node, default=img_handler.kernel_params)
kernel_params += " ir_pub_id=%s" % publisher_id
if params:
kernel_params = ' '.join(
@ -533,6 +539,18 @@ def _prepare_iso_image(task, kernel_href, ramdisk_href,
'ramdisk_href': ramdisk_href,
'bootloader_href': bootloader_href,
'params': kernel_params})
if publisher_id:
images.create_boot_iso(
task.context, boot_iso_tmp_file,
kernel_href, ramdisk_href,
esp_image_href=bootloader_href,
root_uuid=root_uuid,
kernel_params=kernel_params,
boot_mode=boot_mode,
inject_files=inject_files,
publisher_id=publisher_id)
else:
images.create_boot_iso(
task.context, boot_iso_tmp_file,
kernel_href, ramdisk_href,

View File

@ -570,7 +570,8 @@ class FsImageTestCase(base.TestCase):
'path/to/kernel',
'path/to/ramdisk',
deploy_iso='path/to/deploy_iso',
kernel_params=params)
kernel_params=params,
publisher_id='1-23-4')
get_iso_files_mock.assert_called_once_with('path/to/deploy_iso',
'mountdir')
create_root_fs_mock.assert_called_once_with('tmpdir', files_info)
@ -578,7 +579,8 @@ class FsImageTestCase(base.TestCase):
grub_options)
write_to_file_mock.assert_any_call(grub_file, grubcfg)
execute_mock.assert_called_once_with(
'mkisofs', '-r', '-V', 'VMEDIA_BOOT_ISO', '-l', '-e',
'mkisofs', '-r', '-V', 'VMEDIA_BOOT_ISO', '-l',
'-publisher', '1-23-4', '-e',
'path/to/efiboot.img', '-no-emul-boot', '-o', 'tgt_file', 'tmpdir')
rmtree_mock.assert_called_once_with('mountdir')
@ -653,7 +655,8 @@ class FsImageTestCase(base.TestCase):
'path/to/kernel',
'path/to/ramdisk',
kernel_params=params,
inject_files=inject_files)
inject_files=inject_files,
publisher_id='1-23-4')
files_info = {
'path/to/kernel': 'vmlinuz',
@ -672,6 +675,7 @@ class FsImageTestCase(base.TestCase):
execute_mock.assert_called_once_with(
'mkisofs', '-r', '-V',
"VMEDIA_BOOT_ISO", '-J', '-l',
'-publisher', '1-23-4',
'-no-emul-boot', '-boot-load-size',
'4', '-boot-info-table', '-b', 'isolinux/isolinux.bin',
'-o', 'tgt_file', 'tmpdir')
@ -811,7 +815,8 @@ class FsImageTestCase(base.TestCase):
create_isolinux_mock.assert_called_once_with(
'output_file', 'tmpdir/kernel', 'tmpdir/ramdisk',
deploy_iso='tmpdir/iso',
esp_image=None, kernel_params=params, inject_files=None)
esp_image=None, kernel_params=params, inject_files=None,
publisher_id=None)
@mock.patch.object(images, 'create_esp_image_for_uefi', autospec=True)
@mock.patch.object(images, 'fetch', autospec=True)
@ -839,7 +844,8 @@ class FsImageTestCase(base.TestCase):
create_isolinux_mock.assert_called_once_with(
'output_file', 'tmpdir/kernel', 'tmpdir/ramdisk',
deploy_iso=None, esp_image='tmpdir/esp',
kernel_params=params, inject_files=None)
kernel_params=params, inject_files=None,
publisher_id=None)
@mock.patch.object(images, 'create_esp_image_for_uefi', autospec=True)
@mock.patch.object(images, 'fetch', autospec=True)
@ -867,7 +873,8 @@ class FsImageTestCase(base.TestCase):
create_isolinux_mock.assert_called_once_with(
'output_file', 'tmpdir/kernel', 'tmpdir/ramdisk',
deploy_iso='tmpdir/iso',
esp_image=None, kernel_params=params, inject_files=None)
esp_image=None, kernel_params=params, inject_files=None,
publisher_id=None)
@mock.patch.object(images, 'create_esp_image_for_uefi', autospec=True)
@mock.patch.object(images, 'fetch', autospec=True)
@ -882,7 +889,7 @@ class FsImageTestCase(base.TestCase):
'ctx', 'output_file', 'http://kernel-href', 'http://ramdisk-href',
esp_image_href='http://efiboot-href',
root_uuid='root-uuid', kernel_params='kernel-params',
boot_mode='uefi')
boot_mode='uefi', publisher_id='1-23-4')
expected_calls = [mock.call('ctx', 'http://kernel-href',
'tmpdir/kernel'),
@ -895,7 +902,8 @@ class FsImageTestCase(base.TestCase):
create_isolinux_mock.assert_called_once_with(
'output_file', 'tmpdir/kernel', 'tmpdir/ramdisk',
deploy_iso=None, esp_image='tmpdir/esp',
kernel_params=params, inject_files=None)
kernel_params=params, inject_files=None,
publisher_id='1-23-4')
@mock.patch.object(images, 'create_isolinux_image_for_bios', autospec=True)
@mock.patch.object(images, 'fetch', autospec=True)
@ -909,7 +917,8 @@ class FsImageTestCase(base.TestCase):
images.create_boot_iso('ctx', 'output_file', 'kernel-uuid',
'ramdisk-uuid', 'deploy_iso-uuid',
'efiboot-uuid', 'root-uuid',
'kernel-params', 'bios')
'kernel-params', 'bios',
publisher_id='1-23-4')
fetch_images_mock.assert_any_call(
'ctx', 'kernel-uuid', 'tmpdir/kernel')
@ -926,7 +935,8 @@ class FsImageTestCase(base.TestCase):
params = ['root=UUID=root-uuid', 'kernel-params']
create_isolinux_mock.assert_called_once_with(
'output_file', 'tmpdir/kernel', 'tmpdir/ramdisk',
kernel_params=params, inject_files=None)
kernel_params=params, inject_files=None,
publisher_id='1-23-4')
@mock.patch.object(images, 'create_isolinux_image_for_bios', autospec=True)
@mock.patch.object(images, 'fetch', autospec=True)
@ -951,7 +961,8 @@ class FsImageTestCase(base.TestCase):
params = ['root=UUID=root-uuid', 'kernel-params']
create_isolinux_mock.assert_called_once_with(
'output_file', 'tmpdir/kernel', 'tmpdir/ramdisk',
kernel_params=params, inject_files=None)
kernel_params=params, inject_files=None,
publisher_id=None)
@mock.patch.object(image_service, 'get_image_service', autospec=True)
def test_get_glance_image_properties_no_such_prop(self,

View File

@ -558,11 +558,14 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
mock_unpublish.assert_called_once_with(mock.ANY, object_name)
@mock.patch.object(uuidutils, 'generate_uuid', autospec=True)
@mock.patch.object(image_utils.ImageHandler, 'publish_image',
autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_uefi(
self, mock_create_boot_iso, mock_publish_image):
self, mock_create_boot_iso, mock_publish_image,
mock_generate_uuid):
mock_generate_uuid.return_value = '1-23-4'
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
task.node.instance_info.update(deploy_boot_mode='uefi')
@ -583,18 +586,21 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
mock_create_boot_iso.assert_called_once_with(
mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
boot_mode='uefi', esp_image_href='http://bootloader/img',
kernel_params='nofb nomodeset vga=normal',
kernel_params='nofb nomodeset vga=normal ir_pub_id=1-23-4',
root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
inject_files=None)
inject_files=None, publisher_id='1-23-4')
self.assertEqual(expected_url, url)
@mock.patch.object(uuidutils, 'generate_uuid', autospec=True)
@mock.patch.object(image_utils.ImageHandler, 'publish_image',
autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_default_boot_mode(
self, mock_create_boot_iso, mock_publish_image):
self, mock_create_boot_iso, mock_publish_image,
mock_generate_uuid):
self.config(default_boot_mode='uefi', group='deploy')
mock_generate_uuid.return_value = '1-23-4'
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
image_utils._prepare_iso_image(
@ -604,16 +610,19 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
mock_create_boot_iso.assert_called_once_with(
mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
boot_mode='uefi', esp_image_href=None,
kernel_params='nofb nomodeset vga=normal',
kernel_params='nofb nomodeset vga=normal ir_pub_id=1-23-4',
root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
inject_files=None)
inject_files=None, publisher_id='1-23-4')
@mock.patch.object(uuidutils, 'generate_uuid', autospec=True)
@mock.patch.object(image_utils.ImageHandler, 'publish_image',
autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_with_node_external_http_url(
self, mock_create_boot_iso, mock_publish_image):
self, mock_create_boot_iso, mock_publish_image,
mock_generate_uuid):
self.config(default_boot_mode='uefi', group='deploy')
mock_generate_uuid.return_value = '1-23-4'
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
override_url = 'https://node.external/'
@ -634,18 +643,21 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
mock_create_boot_iso.assert_called_once_with(
mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
boot_mode='uefi', esp_image_href='http://bootloader/img',
kernel_params=mock.ANY,
kernel_params='nofb nomodeset vga=normal ir_pub_id=1-23-4',
root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
inject_files=None)
inject_files=None, publisher_id='1-23-4')
self.assertEqual(expected_url, url)
@mock.patch.object(uuidutils, 'generate_uuid', autospec=True)
@mock.patch.object(image_utils.ImageHandler, 'publish_image',
autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_bios(
self, mock_create_boot_iso, mock_publish_image):
self, mock_create_boot_iso, mock_publish_image,
mock_generate_uuid):
self.config(default_boot_mode='bios', group='deploy')
mock_generate_uuid.return_value = '1-23-4'
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
@ -665,17 +677,20 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
mock_create_boot_iso.assert_called_once_with(
mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
boot_mode='bios', esp_image_href=None,
kernel_params='nofb nomodeset vga=normal',
kernel_params='nofb nomodeset vga=normal ir_pub_id=1-23-4',
root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
inject_files=None)
inject_files=None, publisher_id='1-23-4')
self.assertEqual(expected_url, url)
@mock.patch.object(uuidutils, 'generate_uuid', autospec=True)
@mock.patch.object(image_utils.ImageHandler, 'publish_image',
autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_kernel_params(
self, mock_create_boot_iso, mock_publish_image):
self, mock_create_boot_iso, mock_publish_image,
mock_generate_uuid):
mock_generate_uuid.return_value = '1-23-4'
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
kernel_params = 'network-config=base64-cloudinit-blob'
@ -689,15 +704,19 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
mock_create_boot_iso.assert_called_once_with(
mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
boot_mode='uefi', esp_image_href=None,
kernel_params=kernel_params,
kernel_params=f'{kernel_params} ir_pub_id=1-23-4',
root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
inject_files=None)
inject_files=None, publisher_id='1-23-4')
self.assertEqual(1, mock_generate_uuid.call_count)
@mock.patch.object(uuidutils, 'generate_uuid', autospec=True)
@mock.patch.object(image_utils.ImageHandler, 'publish_image',
autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_kernel_params_driver_info(
self, mock_create_boot_iso, mock_publish_image):
self, mock_create_boot_iso, mock_publish_image,
mock_generate_uuid):
mock_generate_uuid.return_value = '1-23-4'
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
kernel_params = 'network-config=base64-cloudinit-blob'
@ -711,15 +730,19 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
mock_create_boot_iso.assert_called_once_with(
mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
boot_mode='uefi', esp_image_href=None,
kernel_params=kernel_params,
kernel_params=f'{kernel_params} ir_pub_id=1-23-4',
root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
inject_files=None)
inject_files=None, publisher_id='1-23-4')
self.assertEqual(1, mock_generate_uuid.call_count)
@mock.patch.object(uuidutils, 'generate_uuid', autospec=True)
@mock.patch.object(image_utils.ImageHandler, 'publish_image',
autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_kernel_params_defaults(
self, mock_create_boot_iso, mock_publish_image):
self, mock_create_boot_iso, mock_publish_image,
mock_generate_uuid):
mock_generate_uuid.return_value = '1-23-4'
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
kernel_params = 'network-config=base64-cloudinit-blob'
@ -734,16 +757,21 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
mock_create_boot_iso.assert_called_once_with(
mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
boot_mode='uefi', esp_image_href=None,
kernel_params=f'nofb nomodeset vga=normal {kernel_params}',
kernel_params=(f'nofb nomodeset vga=normal {kernel_params} '
'ir_pub_id=1-23-4'),
root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
inject_files=None)
inject_files=None, publisher_id='1-23-4')
self.assertEqual(1, mock_generate_uuid.call_count)
@mock.patch.object(uuidutils, 'generate_uuid', autospec=True)
@mock.patch.object(image_utils.ImageHandler, 'publish_image',
autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_kernel_params_driver_info_bios(
self, mock_create_boot_iso, mock_publish_image):
self, mock_create_boot_iso, mock_publish_image,
mock_generate_uuid):
self.config(default_boot_mode='bios', group='deploy')
mock_generate_uuid.return_value = '1-23-4'
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
kernel_params = 'network-config=base64-cloudinit-blob'
@ -757,16 +785,20 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
mock_create_boot_iso.assert_called_once_with(
mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
boot_mode='bios', esp_image_href=None,
kernel_params=kernel_params,
kernel_params=f'{kernel_params} ir_pub_id=1-23-4',
root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
inject_files=None)
inject_files=None,
publisher_id='1-23-4')
self.assertEqual(1, mock_generate_uuid.call_count)
@mock.patch.object(uuidutils, 'generate_uuid', autospec=True)
@mock.patch.object(deploy_utils, 'get_boot_option', lambda node: 'ramdisk')
@mock.patch.object(image_utils.ImageHandler, 'publish_image',
autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_kernel_params_for_ramdisk_uefi(
self, mock_create_boot_iso, mock_publish_image):
self, mock_create_boot_iso, mock_publish_image,
mock_generate_uuid):
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
kernel_params = 'network-config=base64-cloudinit-blob'
@ -780,17 +812,21 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
mock_create_boot_iso.assert_called_once_with(
mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
boot_mode='uefi', esp_image_href=None,
kernel_params="root=/dev/ram0 text " + kernel_params,
kernel_params=f'root=/dev/ram0 text {kernel_params}',
root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
inject_files=None)
mock_generate_uuid.assert_not_called()
@mock.patch.object(uuidutils, 'generate_uuid', autospec=True)
@mock.patch.object(deploy_utils, 'get_boot_option', lambda node: 'ramdisk')
@mock.patch.object(image_utils.ImageHandler, 'publish_image',
autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_kernel_params_for_ramdisk_bios(
self, mock_create_boot_iso, mock_publish_image):
self, mock_create_boot_iso, mock_publish_image,
mock_generate_uuid):
self.config(default_boot_mode='bios', group='deploy')
mock_generate_uuid.return_value = '1-23-4'
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
kernel_params = 'network-config=base64-cloudinit-blob'
@ -804,16 +840,20 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
mock_create_boot_iso.assert_called_once_with(
mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
boot_mode='bios', esp_image_href=None,
kernel_params="root=/dev/ram0 text " + kernel_params,
kernel_params=f'root=/dev/ram0 text {kernel_params}',
root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
inject_files=None)
mock_generate_uuid.assert_not_called()
@mock.patch.object(uuidutils, 'generate_uuid', autospec=True)
@mock.patch.object(deploy_utils, 'get_boot_option', lambda node: 'ramdisk')
@mock.patch.object(image_utils.ImageHandler, 'publish_image',
autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_kernel_params_for_ramdisk_cleaning(
self, mock_create_boot_iso, mock_publish_image):
self, mock_create_boot_iso, mock_publish_image,
mock_generate_uuid):
mock_generate_uuid.return_value = '1-23-4'
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
kernel_params = 'network-config=base64-cloudinit-blob'
@ -828,15 +868,19 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
mock_create_boot_iso.assert_called_once_with(
mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
boot_mode='uefi', esp_image_href=None,
kernel_params=kernel_params,
kernel_params=f'{kernel_params} ir_pub_id=1-23-4',
root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
inject_files=None)
inject_files=None, publisher_id='1-23-4')
self.assertEqual(1, mock_generate_uuid.call_count)
@mock.patch.object(uuidutils, 'generate_uuid', autospec=True)
@mock.patch.object(image_utils.ImageHandler, 'publish_image',
autospec=True)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
def test__prepare_iso_image_extra_params(
self, mock_create_boot_iso, mock_publish_image):
self, mock_create_boot_iso, mock_publish_image,
mock_generate_uuid):
mock_generate_uuid.return_value = '1-23-4'
with task_manager.acquire(self.context, self.node.uuid,
shared=True) as task:
kernel_params = 'network-config=base64-cloudinit-blob'
@ -851,9 +895,12 @@ class RedfishImageUtilsTestCase(db_base.DbTestCase):
mock_create_boot_iso.assert_called_once_with(
mock.ANY, mock.ANY, 'http://kernel/img', 'http://ramdisk/img',
boot_mode='uefi', esp_image_href=None,
kernel_params=kernel_params + ' foo=bar banana',
kernel_params=(f'{kernel_params} ir_pub_id=1-23-4 '
'foo=bar banana'),
root_uuid='1be26c0b-03f2-4d2e-ae87-c02d7f33c123',
inject_files=None)
inject_files=None, publisher_id='1-23-4')
self.assertEqual(1, mock_generate_uuid.call_count)
self.assertEqual(1, mock_generate_uuid.call_count)
def test__prepare_iso_image_bootable_iso(self):
with task_manager.acquire(self.context, self.node.uuid,

View File

@ -0,0 +1,6 @@
---
fixes:
- |
Adds an ISO publisher value to ISO images which are mastered as part of
cleaning/deployment/service operations in support of a fix for
`bug 2032377 <https://bugs.launchpad.net/ironic/+bug/2032377>`_.