Skip to content

Commit

Permalink
Merge pull request #2695 from AdamWill/live-gpt-test
Browse files Browse the repository at this point in the history
xorriso: respect efiparttable and gpt_hybrid_mbr
  • Loading branch information
Conan-Kudo authored Dec 13, 2024
2 parents b1da972 + 75c9939 commit 8b14c13
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 23 deletions.
11 changes: 9 additions & 2 deletions doc/source/image_description/elements.rst
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ efifatimagesize="nonNegativeInteger":
efiparttable="msdos|gpt":
For images with an EFI firmware specifies the partition
table type to use. If not set defaults to the GPT partition
table type
table type for disk images, MBR (msdos) for ISO images.

dosparttable_extended_layout="true|false":
For oem disk images, specifies to make use of logical partitions
Expand Down Expand Up @@ -889,7 +889,14 @@ force_mbr="true|false":
partitions

gpt_hybrid_mbr="true|false":
For GPT disk types only: Create a hybrid GPT/MBR partition table
For disk types, create a hybrid GPT/MBR partition table with an
'accurate' MBR table that will have no 'bootable' flagged partition
For ISO types, create a hybrid GPT/MBR partition table where the
MBR partition table contains a whole-disk 'protective' partition
and a second bootable-flagged partition (intended to make the image
bootable in both UEFI and BIOS modes on as much hardware as possible)
In both cases, only has any effect if the EFI partition table
type is GPT

hybridpersistent="true|false":
For the live ISO type, triggers the creation of a partition for
Expand Down
2 changes: 2 additions & 0 deletions kiwi/builder/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ def create_install_iso(self) -> None:
'mbr_id': self.mbrid.get_id(),
'application_id': self.xml_state.build_type.get_application_id(),
'efi_mode': self.firmware.efi_mode(),
'efi_partition_table': self.firmware.get_partition_table_type(),
'gpt_hybrid_mbr': self.firmware.gpt_hybrid_mbr,
'ofw_mode': self.firmware.ofw_mode(),
'legacy_bios_mode': self.firmware.legacy_bios_mode()
}
Expand Down
2 changes: 2 additions & 0 deletions kiwi/builder/live.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ def create(self) -> Result:
'mbr_id': self.mbrid.get_id(),
'application_id': self.application_id,
'efi_mode': self.firmware.efi_mode(),
'efi_partition_table': self.firmware.get_partition_table_type(),
'gpt_hybrid_mbr': self.firmware.gpt_hybrid_mbr,
'legacy_bios_mode': self.firmware.legacy_bios_mode()
}
}
Expand Down
2 changes: 1 addition & 1 deletion kiwi/filesystem/isofs.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ def create_on_file(
iso_tool.init_iso_creation_parameters(meta_data)

if efi_loader:
iso_tool.add_efi_loader_parameters(efi_loader)
iso_tool.add_efi_loader_parameters(efi_loader, meta_data)

iso_tool.create_iso(self.filename)
1 change: 1 addition & 0 deletions kiwi/firmware.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def __init__(self, xml_state):
self.firmware = xml_state.build_type.get_firmware()
self.efipart_mbytes = xml_state.build_type.get_efipartsize()
self.efi_partition_table = xml_state.build_type.get_efiparttable()
self.gpt_hybrid_mbr = xml_state.build_type.get_gpt_hybrid_mbr()
self.efi_csm = True if xml_state.build_type.get_eficsm() is None \
else xml_state.build_type.get_eficsm()

Expand Down
6 changes: 4 additions & 2 deletions kiwi/iso_tools/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import shutil
import logging
from typing import (
Dict, List, Union
Dict, List, Optional, Union
)

# project
Expand Down Expand Up @@ -72,7 +72,9 @@ def init_iso_creation_parameters(
"""
raise NotImplementedError

def add_efi_loader_parameters(self, loader_file: str) -> None:
def add_efi_loader_parameters(
self, loader_file: str, custom_args: Optional[Dict[str, Union[str, bool]]] = None
) -> None:
"""
Add ISO creation parameters to embed the EFI loader
Expand Down
28 changes: 27 additions & 1 deletion kiwi/iso_tools/xorriso.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ def init_iso_creation_parameters(
self.iso_parameters += [
'-compliance', 'untranslated_names'
]
else:
self.iso_parameters += [
# https://lists.gnu.org/archive/html/bug-xorriso/2024-11/msg00012.html
'-compliance', 'no_emul_toc'
]

if Defaults.is_x86_arch(self.arch) and legacy_bios_mode:
mbr_file = os.sep.join(
Expand Down Expand Up @@ -145,7 +150,9 @@ def init_iso_creation_parameters(
'-boot_image', 'any', 'load_size=2048'
]

def add_efi_loader_parameters(self, loader_file: str) -> None:
def add_efi_loader_parameters(
self, loader_file: str, custom_args: Optional[Dict[str, Union[str, bool]]] = None
) -> None:
"""
Add ISO creation parameters to embed the EFI loader
Expand All @@ -156,6 +163,18 @@ def add_efi_loader_parameters(self, loader_file: str) -> None:
file refer to _create_embedded_fat_efi_image() from
bootloader/config/grub2.py
"""
if custom_args:
efi_partition_table = custom_args.get('efi_partition_table', '')
legacy_bios_mode = custom_args.get('legacy_bios_mode', False)
gpt_hybrid_mbr = custom_args.get('gpt_hybrid_mbr', False)
if efi_partition_table == 'gpt':
self.iso_loaders += [
'-boot_image', 'any', 'appended_part_as=gpt',
]
if gpt_hybrid_mbr and legacy_bios_mode:
self.iso_loaders += [
'-boot_image', 'any', 'mbr_force_bootable=on',
]
self.iso_loaders += [
'-append_partition', '2', '0xef', loader_file,
'-boot_image', 'any', 'next',
Expand Down Expand Up @@ -189,3 +208,10 @@ def create_iso(
'-chmod', '0755', '/', '--'
] + self.iso_loaders + hidden_files_parameters
)
report_call = Command.run(
[
self.get_tool_name(), '-indev', filename,
'-report_system_area', 'plain'
]
)
log.debug(report_call.output)
4 changes: 2 additions & 2 deletions kiwi/schema/kiwi.rnc
Original file line number Diff line number Diff line change
Expand Up @@ -1687,7 +1687,7 @@ div {
attribute efiparttable { "msdos" | "gpt" }
>> sch:pattern [ id = "efiparttable" is-a = "image_type"
sch:param [ name = "attr" value = "efiparttable" ]
sch:param [ name = "types" value = "oem" ]
sch:param [ name = "types" value = "oem iso" ]
]
k.type.bootprofile.attribute =
## Specifies the boot profile defined in the boot image
Expand Down Expand Up @@ -2012,7 +2012,7 @@ div {
attribute gpt_hybrid_mbr { xsd:boolean }
>> sch:pattern [ id = "gpt_hybrid_mbr" is-a = "image_type"
sch:param [ name = "attr" value = "gpt_hybrid_mbr" ]
sch:param [ name = "types" value = "oem" ]
sch:param [ name = "types" value = "oem iso" ]
]
k.type.initrd_system.attribute =
## specify which initrd builder to use, default is dracut
Expand Down
4 changes: 2 additions & 2 deletions kiwi/schema/kiwi.rng
Original file line number Diff line number Diff line change
Expand Up @@ -2473,7 +2473,7 @@ table type.</a:documentation>
</attribute>
<sch:pattern id="efiparttable" is-a="image_type">
<sch:param name="attr" value="efiparttable"/>
<sch:param name="types" value="oem"/>
<sch:param name="types" value="oem iso"/>
</sch:pattern>
</define>
<define name="k.type.bootprofile.attribute">
Expand Down Expand Up @@ -2907,7 +2907,7 @@ create a hybrid GPT/MBR partition table</a:documentation>
</attribute>
<sch:pattern id="gpt_hybrid_mbr" is-a="image_type">
<sch:param name="attr" value="gpt_hybrid_mbr"/>
<sch:param name="types" value="oem"/>
<sch:param name="types" value="oem iso"/>
</sch:pattern>
</define>
<define name="k.type.initrd_system.attribute">
Expand Down
4 changes: 4 additions & 0 deletions test/unit/builder/live_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ def side_effect():
self.setup.export_package_list.return_value = '.packages'

self.firmware.bios_mode.return_value = False
self.firmware.get_partition_table_type.return_value = 'gpt'
self.firmware.gpt_hybrid_mbr = False
self.live_image.create()

self.setup.import_cdroot_files.assert_called_once_with('temp_media_dir')
Expand Down Expand Up @@ -369,6 +371,8 @@ def side_effect():
'volume_id': 'volid',
'efi_mode': 'uefi',
'efi_loader': 'kiwi-tmpfile',
'efi_partition_table': 'gpt',
'gpt_hybrid_mbr': False,
'udf': True,
'legacy_bios_mode': True
}
Expand Down
3 changes: 2 additions & 1 deletion test/unit/filesystem/isofs_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@ def test_create_on_file_EFI_enabled(self, mock_IsoTools):
self.isofs.create_on_file('myimage')
iso_tool.create_iso.assert_called_once_with('myimage')
iso_tool.add_efi_loader_parameters.assert_called_once_with(
'esp-image-file'
'esp-image-file',
{'efi_mode': 'uefi', 'efi_loader': 'esp-image-file'}
)
71 changes: 59 additions & 12 deletions test/unit/iso_tools/xorriso_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import logging
from unittest.mock import patch
from unittest.mock import (
patch, call
)
from pytest import (
raises, fixture
)
Expand Down Expand Up @@ -94,7 +96,8 @@ def test_init_iso_creation_parameters_efi(self, mock_os_path_exists):
'-preparer_id', 'preparer',
'-volid', 'vol_id',
'-joliet', 'on',
'-padding', '0'
'-padding', '0',
'-compliance', 'no_emul_toc'
]
assert self.iso_tool.iso_loaders == [
'-boot_image', 'grub',
Expand Down Expand Up @@ -133,7 +136,8 @@ def test_init_iso_creation_parameters_efi_custom_app_id(
'-preparer_id', 'preparer',
'-volid', 'vol_id',
'-joliet', 'on',
'-padding', '0'
'-padding', '0',
'-compliance', 'no_emul_toc'
]

def test_add_efi_loader_parameters(self):
Expand All @@ -147,22 +151,65 @@ def test_add_efi_loader_parameters(self):
'-boot_image', 'any', 'emul_type=no_emulation'
]

def test_add_efi_loader_parameters_gpt(self):
self.iso_tool.add_efi_loader_parameters(
'target_dir/efi-loader',
{'efi_partition_table': 'gpt'}
)
assert self.iso_tool.iso_loaders == [
'-boot_image', 'any', 'appended_part_as=gpt',
'-append_partition', '2', '0xef', 'target_dir/efi-loader',
'-boot_image', 'any', 'next',
'-boot_image', 'any',
'efi_path=--interval:appended_partition_2:all::',
'-boot_image', 'any', 'platform_id=0xef',
'-boot_image', 'any', 'emul_type=no_emulation'
]

def test_add_efi_loader_parameters_gpt_hybrid(self):
self.iso_tool.add_efi_loader_parameters(
'target_dir/efi-loader',
{
'efi_partition_table': 'gpt',
'legacy_bios_mode': True,
'gpt_hybrid_mbr': True
}
)
assert self.iso_tool.iso_loaders == [
'-boot_image', 'any', 'appended_part_as=gpt',
'-boot_image', 'any', 'mbr_force_bootable=on',
'-append_partition', '2', '0xef', 'target_dir/efi-loader',
'-boot_image', 'any', 'next',
'-boot_image', 'any',
'efi_path=--interval:appended_partition_2:all::',
'-boot_image', 'any', 'platform_id=0xef',
'-boot_image', 'any', 'emul_type=no_emulation'
]

@patch('kiwi.iso_tools.xorriso.Command.run')
@patch('kiwi.iso_tools.xorriso.Path.wipe')
@patch('kiwi.iso_tools.xorriso.Path.which')
def test_create_iso(self, mock_which, mock_wipe, mock_command):
mock_which.return_value = '/usr/bin/xorriso'
self.iso_tool.create_iso('myiso', hidden_files=['hide_me'])
mock_wipe.assert_called_once_with('myiso')
mock_command.assert_called_once_with(
[
'/usr/bin/xorriso',
'-outdev', 'myiso',
'-map', 'source-dir', '/',
'-chmod', '0755', '/', '--',
'--', '-find', 'hide_me', '-exec', 'hide', 'on'
]
)
assert mock_command.call_args_list == [
call(
[
'/usr/bin/xorriso',
'-outdev', 'myiso',
'-map', 'source-dir', '/',
'-chmod', '0755', '/', '--',
'--', '-find', 'hide_me', '-exec', 'hide', 'on'
]
),
call(
[
'/usr/bin/xorriso', '-indev', 'myiso',
'-report_system_area', 'plain'
]
)
]

def test_has_iso_hybrid_capability(self):
assert self.iso_tool.has_iso_hybrid_capability() is True

0 comments on commit 8b14c13

Please sign in to comment.