Skip to content

Commit

Permalink
Merge pull request #2438 from OSInside/move_bootloader_to_context_man…
Browse files Browse the repository at this point in the history
…ager

Move BootLoaderConfig to context manager
  • Loading branch information
dcermak authored Jan 26, 2024
2 parents b707be0 + 14e8482 commit b29e491
Show file tree
Hide file tree
Showing 8 changed files with 393 additions and 225 deletions.
6 changes: 4 additions & 2 deletions kiwi/bootloader/config/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ def __init__(self, xml_state, root_dir, boot_dir=None, custom_args={}):
self.root_filesystem_is_overlay = xml_state.build_type.get_overlayroot()
self.post_init(custom_args)

def __enter__(self):
return self

def post_init(self, custom_args):
"""
Post initialization method
Expand Down Expand Up @@ -658,8 +661,7 @@ def _get_location(self, device, persistency_type=''):
'node': f'/dev/disk/{persistency_type}/{location}'
}

def __del__(self):
log.info('Cleaning up %s instance', type(self).__name__)
def __exit__(self, exc_type, exc_value, traceback):
for volume_mount in reversed(self.volumes_mount):
volume_mount.umount()
if self.device_mount:
Expand Down
16 changes: 8 additions & 8 deletions kiwi/builder/disk.py
Original file line number Diff line number Diff line change
Expand Up @@ -825,10 +825,10 @@ def _build_main_system(

# write bootloader meta data to system image
if self.bootloader != 'custom':
bootloader_config = self._bootloader_instance(disk)
self._write_bootloader_meta_data_to_system_image(
device_map, disk, system, bootloader_config
)
with self._bootloader_instance(disk) as bootloader_config:
self._write_bootloader_meta_data_to_system_image(
device_map, disk, system, bootloader_config
)

# call edit_boot_config script
partition_id_map = disk.get_public_partition_id_map()
Expand Down Expand Up @@ -878,10 +878,10 @@ def _build_main_system(

# install boot loader
if self.bootloader != 'custom':
bootloader_config = self._bootloader_instance(disk)
self._install_bootloader(
device_map, disk, system, bootloader_config
)
with self._bootloader_instance(disk) as bootloader_config:
self._install_bootloader(
device_map, disk, system, bootloader_config
)

# call edit_boot_install script
boot_device = device_map['root']
Expand Down
101 changes: 55 additions & 46 deletions kiwi/builder/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,57 +207,42 @@ def create_install_iso(self) -> None:
log.info(
'Setting up install image bootloader configuration'
)
if self.firmware.efi_mode():
# setup bootloader config to boot the ISO via EFI
# This also embedds an MBR and the respective BIOS modules
# for compat boot. The complete bootloader setup will be
# based on grub
bootloader_config = BootLoaderConfig.new(
self.bootloader, self.xml_state, root_dir=self.root_dir,
boot_dir=self.media_dir.name, custom_args={
'grub_directory_name':
Defaults.get_grub_boot_directory_name(self.root_dir),
'grub_load_command':
'configfile'
}
with self._bootloader_instance() as bootloader_config:
if self.firmware.efi_mode():
bootloader_config.setup_install_boot_images(
mbrid=self.mbrid,
lookup_path=self.boot_image_task.boot_root_directory
)

IsoToolsBase.setup_media_loader_directory(
self.boot_image_task.boot_root_directory,
self.media_dir.name,
bootloader_config.get_boot_theme()
)
bootloader_config.setup_install_boot_images(
mbrid=self.mbrid,
lookup_path=self.boot_image_task.boot_root_directory
if self.firmware.bios_mode():
Iso(self.media_dir.name).setup_isolinux_boot_path()
bootloader_config.write_meta_data()
bootloader_config.setup_install_image_config(
mbrid=self.mbrid
)
else:
# setup bootloader config to boot the ISO via isolinux.
# This allows for booting on x86 platforms in BIOS mode
# only.
bootloader_config = BootLoaderConfig.new(
'isolinux', self.xml_state, root_dir=self.root_dir,
boot_dir=self.media_dir.name
)
IsoToolsBase.setup_media_loader_directory(
self.boot_image_task.boot_root_directory, self.media_dir.name,
bootloader_config.get_boot_theme()
)
if self.firmware.bios_mode():
Iso(self.media_dir.name).setup_isolinux_boot_path()
bootloader_config.write_meta_data()
bootloader_config.setup_install_image_config(
mbrid=self.mbrid
)
bootloader_config.write()
bootloader_config.write()

# create initrd for install image
log.info('Creating install image boot image')
self._create_iso_install_kernel_and_initrd()
# create initrd for install image
log.info('Creating install image boot image')
self._create_iso_install_kernel_and_initrd()

# the system image initrd is stored to allow kexec
self._copy_system_image_initrd_to_iso_image()
# the system image initrd is stored to allow kexec
self._copy_system_image_initrd_to_iso_image()

if self.firmware.efi_mode():
efi_loader = Temporary(
prefix='efi-loader.', path=self.target_dir
).new_file()
bootloader_config._create_embedded_fat_efi_image(efi_loader.name)
self.custom_iso_args['meta_data']['efi_loader'] = efi_loader.name
if self.firmware.efi_mode():
efi_loader = Temporary(
prefix='efi-loader.', path=self.target_dir
).new_file()
bootloader_config._create_embedded_fat_efi_image(
efi_loader.name
)
self.custom_iso_args['meta_data']['efi_loader'] = \
efi_loader.name

# create iso filesystem from media_dir
log.info('Creating ISO filesystem')
Expand Down Expand Up @@ -376,6 +361,30 @@ def create_install_pxe_archive(self) -> None:
archive.create(self.pxe_dir.name)
self.boot_image_task.cleanup()

def _bootloader_instance(self):
if self.firmware.efi_mode():
# setup bootloader config to boot the ISO via EFI
# This also embedds an MBR and the respective BIOS modules
# for compat boot. The complete bootloader setup will be
# based on grub
return BootLoaderConfig.new(
self.bootloader, self.xml_state, root_dir=self.root_dir,
boot_dir=self.media_dir.name, custom_args={
'grub_directory_name':
Defaults.get_grub_boot_directory_name(self.root_dir),
'grub_load_command':
'configfile'
}
)
else:
# setup bootloader config to boot the ISO via isolinux.
# This allows for booting on x86 platforms in BIOS mode
# only.
return BootLoaderConfig.new(
'isolinux', self.xml_state, root_dir=self.root_dir,
boot_dir=self.media_dir.name
)

def _create_pxe_install_kernel_and_initrd(self) -> None:
kernelname = 'pxeboot.{0}.kernel'.format(self.pxename)
initrdname = 'pxeboot.{0}.initrd'.format(self.pxename)
Expand Down
166 changes: 89 additions & 77 deletions kiwi/builder/live.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
# project
from kiwi.utils.temporary import Temporary
from kiwi.bootloader.config import BootLoaderConfig
from kiwi.bootloader.config.base import BootLoaderConfigBase
from kiwi.filesystem import FileSystem
from kiwi.filesystem.isofs import FileSystemIsoFs
from kiwi.filesystem.setup import FileSystemSetup
Expand Down Expand Up @@ -146,93 +147,80 @@ def create(self) -> Result:
log.info(
'Setting up live image bootloader configuration'
)
if self.firmware.efi_mode():
# setup bootloader config to boot the ISO via EFI
# This also embedds an MBR and the respective BIOS modules
# for compat boot. The complete bootloader setup will be
# based on grub
bootloader_config = BootLoaderConfig.new(
self.bootloader, self.xml_state, root_dir=self.root_dir,
boot_dir=self.media_dir.name, custom_args={
'grub_directory_name':
Defaults.get_grub_boot_directory_name(self.root_dir),
'grub_load_command':
'configfile'
}
with self._create_bootloader_instance() as bootloader_config:
if self.firmware.efi_mode():
bootloader_config.setup_live_boot_images(
mbrid=self.mbrid, lookup_path=self.root_dir
)

IsoToolsBase.setup_media_loader_directory(
self.boot_image.boot_root_directory, self.media_dir.name,
bootloader_config.get_boot_theme()
)
bootloader_config.setup_live_boot_images(
mbrid=self.mbrid, lookup_path=self.root_dir
if self.firmware.bios_mode():
Iso(self.media_dir.name).setup_isolinux_boot_path()
bootloader_config.write_meta_data()
bootloader_config.setup_live_image_config(
mbrid=self.mbrid
)
else:
# setup bootloader config to boot the ISO via isolinux.
# This allows for booting on x86 platforms in BIOS mode
# only.
bootloader_config = BootLoaderConfig.new(
'isolinux', self.xml_state, root_dir=self.root_dir,
boot_dir=self.media_dir.name
bootloader_config.write()

# call custom editbootconfig script if present
self.system_setup.call_edit_boot_config_script(
filesystem='iso:{0}'.format(self.media_dir.name),
boot_part_id=1,
working_directory=self.root_dir
)
IsoToolsBase.setup_media_loader_directory(
self.boot_image.boot_root_directory, self.media_dir.name,
bootloader_config.get_boot_theme()
)
if self.firmware.bios_mode():
Iso(self.media_dir.name).setup_isolinux_boot_path()
bootloader_config.write_meta_data()
bootloader_config.setup_live_image_config(
mbrid=self.mbrid
)
bootloader_config.write()

# call custom editbootconfig script if present
self.system_setup.call_edit_boot_config_script(
filesystem='iso:{0}'.format(self.media_dir.name), boot_part_id=1,
working_directory=self.root_dir
)
# prepare dracut initrd call
self.boot_image.prepare()

# prepare dracut initrd call
self.boot_image.prepare()
# create dracut initrd for live image
log.info('Creating live ISO boot image')
live_dracut_modules = Defaults.get_live_dracut_modules_from_flag(
self.live_type
)
live_dracut_modules.append('pollcdrom')
for dracut_module in live_dracut_modules:
self.boot_image.include_module(dracut_module)
self.boot_image.omit_module('multipath')
self.boot_image.write_system_config_file(
config={
'modules': live_dracut_modules,
'omit_modules': ['multipath']
},
config_file=self.root_dir + '/etc/dracut.conf.d/02-livecd.conf'
)
self.boot_image.create_initrd(self.mbrid)
if self.bootloader == 'systemd_boot':
# make sure the initrd name follows the dracut
# naming conventions
boot_names = self.boot_image.get_boot_names()
if self.boot_image.initrd_filename:
Command.run(
[
'mv', self.boot_image.initrd_filename,
self.root_dir + ''.join(
['/boot/', boot_names.initrd_name]
)
]
)

# create dracut initrd for live image
log.info('Creating live ISO boot image')
live_dracut_modules = Defaults.get_live_dracut_modules_from_flag(
self.live_type
)
live_dracut_modules.append('pollcdrom')
for dracut_module in live_dracut_modules:
self.boot_image.include_module(dracut_module)
self.boot_image.omit_module('multipath')
self.boot_image.write_system_config_file(
config={
'modules': live_dracut_modules,
'omit_modules': ['multipath']
},
config_file=self.root_dir + '/etc/dracut.conf.d/02-livecd.conf'
)
self.boot_image.create_initrd(self.mbrid)
if self.bootloader == 'systemd_boot':
# make sure the initrd name follows the dracut naming conventions
boot_names = self.boot_image.get_boot_names()
if self.boot_image.initrd_filename:
Command.run(
[
'mv', self.boot_image.initrd_filename,
self.root_dir + ''.join(
['/boot/', boot_names.initrd_name]
)
]
# create EFI FAT image
if self.firmware.efi_mode():
efi_loader = Temporary(
prefix='efi-loader.', path=self.target_dir
).new_file()
bootloader_config._create_embedded_fat_efi_image(
efi_loader.name
)

# create EFI FAT image
if self.firmware.efi_mode():
efi_loader = Temporary(
prefix='efi-loader.', path=self.target_dir
).new_file()
bootloader_config._create_embedded_fat_efi_image(efi_loader.name)
custom_iso_args['meta_data']['efi_loader'] = efi_loader.name
custom_iso_args['meta_data']['efi_loader'] = efi_loader.name

# setup kernel file(s) and initrd in ISO boot layout
if self.bootloader != 'systemd_boot':
log.info('Setting up kernel file(s) and boot image in ISO boot layout')
log.info(
'Setting up kernel file(s) and boot image in ISO boot layout'
)
self._setup_live_iso_kernel_and_initrd()

# calculate size and decide if we need UDF
Expand Down Expand Up @@ -359,6 +347,30 @@ def create(self) -> Result:
)
return self.result

def _create_bootloader_instance(self) -> BootLoaderConfigBase:
if self.firmware.efi_mode():
# setup bootloader config to boot the ISO via EFI
# This also embedds an MBR and the respective BIOS modules
# for compat boot. The complete bootloader setup will be
# based on grub
return BootLoaderConfig.new(
self.bootloader, self.xml_state, root_dir=self.root_dir,
boot_dir=self.media_dir.name, custom_args={
'grub_directory_name':
Defaults.get_grub_boot_directory_name(self.root_dir),
'grub_load_command':
'configfile'
}
)
else:
# setup bootloader config to boot the ISO via isolinux.
# This allows for booting on x86 platforms in BIOS mode
# only.
return BootLoaderConfig.new(
'isolinux', self.xml_state, root_dir=self.root_dir,
boot_dir=self.media_dir.name
)

def _setup_live_iso_kernel_and_initrd(self) -> None:
"""
Copy kernel and initrd from the root tree into the iso boot structure
Expand Down
Loading

0 comments on commit b29e491

Please sign in to comment.