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.

Related-Bug: 2032377
Change-Id: I9b74ec977fabc0a7f8ed6f113595a3f1624f6ee6
(cherry picked from commit fb850e7f00)
This commit is contained in:
Julia Kreger 2024-04-03 12:56:57 -07:00
parent 1efa611460
commit 78c1d9a98d
5 changed files with 166 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

@ -23,6 +23,7 @@ import tempfile
from urllib import parse as urlparse
from oslo_log import log
from oslo_utils import uuidutils
from ironic.common import exception
from ironic.common.glance_service import service_utils
@ -446,6 +447,9 @@ def _prepare_iso_image(task, kernel_href, ramdisk_href,
img_handler = ImageHandler(task.node.driver)
if not is_ramdisk_boot:
publisher_id = uuidutils.generate_uuid()
with tempfile.TemporaryDirectory(dir=CONF.tempdir) as boot_file_dir:
boot_iso_tmp_file = os.path.join(boot_file_dir, 'boot.iso')
@ -456,6 +460,9 @@ def _prepare_iso_image(task, kernel_href, ramdisk_href,
kernel_params = driver_utils.get_kernel_append_params(
task.node, default=img_handler.kernel_params)
if not is_ramdisk_boot:
kernel_params += " ir_pub_id=%s" % publisher_id
if params:
kernel_params = ' '.join(
(kernel_params, ' '.join(
@ -472,14 +479,27 @@ def _prepare_iso_image(task, kernel_href, ramdisk_href,
'ramdisk_href': ramdisk_href,
'bootloader_href': bootloader_href,
'params': kernel_params})
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)
if is_ramdisk_boot:
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)
else:
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)
node_http_url = task.node.driver_info.get("external_http_url")
image_url = img_handler.publish_image(

View File

@ -568,7 +568,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)
@ -576,7 +577,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')
@ -651,7 +653,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',
@ -670,6 +673,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')
@ -809,7 +813,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)
@ -837,7 +842,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)
@ -865,7 +871,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)
@ -880,7 +887,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'),
@ -893,7 +900,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)
@ -907,7 +915,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')
@ -924,7 +933,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)
@ -949,7 +959,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

@ -379,11 +379,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')
@ -404,18 +407,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 vga=normal',
kernel_params='nofb 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(
@ -425,16 +431,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 vga=normal',
kernel_params='nofb 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/'
@ -455,18 +464,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 vga=normal',
kernel_params='nofb 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:
@ -486,17 +498,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 vga=normal',
kernel_params='nofb 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'
@ -510,15 +525,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'
@ -532,15 +551,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'
@ -555,16 +578,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 vga=normal {kernel_params}',
kernel_params=(f'nofb 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'
@ -578,16 +606,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'
@ -601,17 +633,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'
@ -625,16 +661,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'
@ -649,15 +689,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'
@ -672,9 +716,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)
@mock.patch.object(images, 'create_boot_iso', autospec=True)
@mock.patch.object(image_utils, 'prepare_remote_image', autospec=True)

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>`_.