kiwi-el8/kiwi/iso_tools/base.py
Adam Williamson 75c9939f84 xorriso: respect efiparttable and gpt_hybrid_mbr
This should make the xorriso-based ISO build path respect the
'efiparttable' and 'gpt_hybrid_mbr' settings when building a
UEFI-compatible image, making it write a GPT disk label by default
instead of an MBR (msdos) one. If it's building an image that is not
UEFI-compatible it will always write an MBR label, regardless of
this setting.

If 'gpt_hybrid_mbr' is set, xorriso will write an Ubuntu-style
MBR/GPT hybrid partition table, where the MBR partition table
includes a partition with type 00 and the bootable flag, as well
as the partition with type ee required by the UEFI spec. This
mildly violates the UEFI spec but may make the image bootable on
native BIOS or CSM firmwares which refuse to boot from a disk with
no partition marked 'bootable' in the MBR. If 'gpt_hybrid_mbr' is
not set, xorriso will write a strictly UEFI-spec compliant label,
with just the 'protective MBR' required by the UEFI spec (no
bootable partition) and the correct GPT partition table. Note
this is somewhat different from what gpt_hybrid_mbr does for
disk images.

Also, we now pass -compliance no_emul_toc when building ISOs, as
recommended by upstream in
https://lists.gnu.org/archive/html/bug-xorriso/2024-11/msg00012.html
This tool is generally always going to be building ISOs intended
for write-once use, not multi-session use (and which are rarely,
these days, written to physical discs at all anyway).

Signed-off-by: Adam Williamson <awilliam@redhat.com>
2024-12-13 11:13:27 -08:00

183 lines
5.4 KiB
Python

# Copyright (c) 2015 SUSE Linux GmbH. All rights reserved.
#
# This file is part of kiwi.
#
# kiwi is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# kiwi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with kiwi. If not, see <http://www.gnu.org/licenses/>
#
import os
import shutil
import logging
from typing import (
Dict, List, Optional, Union
)
# project
from kiwi.defaults import Defaults
from kiwi.command import Command
from kiwi.utils.sync import DataSync
from kiwi.path import Path
log = logging.getLogger('kiwi')
class IsoToolsBase:
"""
**Base Class for Parameter API for iso creation tools**
"""
def __init__(self, source_dir: str) -> None:
"""
Base class for IsoTools
:param string source_dir: data source dir, usually root_dir
"""
self.arch = Defaults.get_platform_name()
self.source_dir = source_dir
self.boot_path = Defaults.get_iso_boot_path()
self.iso_parameters: List[str] = []
self.iso_loaders: List[str] = []
def get_tool_name(self) -> str:
"""
Return caller name for iso creation tool
Implementation in specialized tool class
:return: tool name
:rtype: str
"""
raise NotImplementedError
def init_iso_creation_parameters(
self, custom_args: Dict[str, Union[str, bool]] = None
) -> None:
"""
Create a set of standard parameters for the main loader
Implementation in specialized tool class
:param list custom_args: unused
"""
raise NotImplementedError
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
Implementation in specialized tool class
"""
raise NotImplementedError
def create_iso(
self, filename: str, hidden_files: List[str] = None
) -> None:
"""
Create iso file
Implementation in specialized tool class
:param str filename: unused
:param list hidden_files: unused
"""
raise NotImplementedError
def list_iso(self, isofile: str) -> None:
"""
List contents of an ISO image
:param str isofile: unused
"""
raise NotImplementedError
def has_iso_hybrid_capability(self) -> bool:
"""
Indicate if the iso tool has the capability to embed
a partition table into the iso such that it can be
used as both; an iso and a disk
Implementation in specialized tool class
"""
raise NotImplementedError
@staticmethod
def setup_media_loader_directory(
lookup_path: str, media_path: str, boot_theme: str
):
loader_data = lookup_path + '/image/loader/'
media_boot_path = os.sep.join(
[media_path, Defaults.get_iso_boot_path(), 'loader']
)
Path.wipe(loader_data)
Path.create(loader_data)
grub_image_file_names = [
Defaults.get_iso_grub_loader(),
Defaults.get_iso_grub_mbr()
]
loader_files = []
for grub_image_file_name in grub_image_file_names:
grub_file = Defaults.get_grub_path(
lookup_path, 'i386-pc/{0}'.format(grub_image_file_name),
raise_on_error=False
)
if grub_file and os.path.exists(grub_file):
loader_files.append(grub_file)
log.debug('Copying loader files to {0}'.format(loader_data))
for loader_file in loader_files:
log.debug('--> Copying {0}'.format(loader_file))
shutil.copy(loader_file, loader_data)
bash_command = ' '.join(
['cp', lookup_path + '/boot/memtest*', loader_data + '/memtest']
)
Command.run(
command=['bash', '-c', bash_command], raise_on_error=False
)
if boot_theme:
theme_path = ''.join(
[lookup_path, '/etc/bootsplash/themes/', boot_theme]
)
if os.path.exists(theme_path + '/cdrom/gfxboot.cfg'):
bash_command = ' '.join(
['cp', theme_path + '/cdrom/*', loader_data]
)
Command.run(
['bash', '-c', bash_command]
)
# don't move down one menu entry the first time a F-key is used
Command.run(
[
'gfxboot',
'--config-file', loader_data + '/gfxboot.cfg',
'--change-config', 'install::autodown=0'
]
)
if os.path.exists(theme_path + '/bootloader/message'):
Command.run(
['cp', theme_path + '/bootloader/message', loader_data]
)
Path.create(media_boot_path)
data = DataSync(
loader_data, media_boot_path
)
data.sync_data(
options=['-a']
)