From: Daan De Meyer Date: Mon, 17 Apr 2023 20:14:43 +0000 (+0200) Subject: Add back --bootable option X-Git-Tag: v15~241 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee57d6cb51d7853165d99ffd2a99151523d0d007;p=thirdparty%2Fmkosi.git Add back --bootable option There are valid scenarios where one might want to install a kernel without wanting a bootable image, so let's add back the --bootable= option as a feature option. It defaults to "auto" which is the current behavior, but can also be explicitly enabled or disabled. If enabled, we'll fail if we can't produce a bootable image. If disabled, we won't generate a bootable image even if all the necessary components are available. --- diff --git a/NEWS.md b/NEWS.md index bd0e4b689..a48d49de5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -68,9 +68,9 @@ - Removed `--qcow2` option in favor of supporting only raw disk images as the disk image output format. - Removed `--bmap` option as it can be trivially added manually by utilizing a finalize script. - The `never` value for `--with-network` was spun of into its own custom option `--cache-only`. -- Removed `--bootable` in favor of automatically generating a bootable image if all the necessary packages - are installed. Documentation was added in docs/bootable.ld on how a bootable image can be generated on - mainstream distros. +- `--bootable` now defaults to `auto`. When set to `auto`, mkosi will generate a bootable image only if all + the necessary packages are installed. Documentation was added in docs/bootable.md on how a bootable image + can be generated on mainstream distros. - The RPM db is no longer rebuilt in bdb format on CentOS Stream 8. To be able to install packages on a CentOS Stream 8 image with a RPM db in sqlite format, rewrite the db in bdb format using `rpm --rebuilddb --define _db_backend bdb`. diff --git a/mkosi.md b/mkosi.md index bc26f197b..739177b36 100644 --- a/mkosi.md +++ b/mkosi.md @@ -369,6 +369,19 @@ a boolean argument: either "1", "yes", or "true" to enable, or "0", +`Bootable=`, `--bootable=` + +: Takes a boolean or `auto`. Enables or disable generating of a bootable + image. If enabled, mkosi will install systemd-boot, run kernel-install, + generate unified kernel images for installed kernels and add an ESP + partition when the disk image output is used. If systemd-boot is not + installed or no kernel images can be found, the build will fail. `auto` + behaves as if the option was enabled, but the build won't fail if either + no kernel images or systemd-boot can't be found. If disabled, systemd-boot + won't be installed even if found inside the image, kernel-install won't be + executed, no unified kernel images will be generated and no ESP partition + will be added to the image if the disk output format is used. + `KernelCommandLine=`, `--kernel-command-line=` : Use the specified kernel command line when building images. By default diff --git a/mkosi/__init__.py b/mkosi/__init__.py index f144ca654..0541fe45c 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -463,11 +463,17 @@ def run_finalize_script(state: MkosiState) -> None: def install_boot_loader(state: MkosiState) -> None: - if state.for_cache: + if state.for_cache or state.config.bootable is False: + return + + if state.config.output_format == OutputFormat.cpio and state.config.bootable is None: return directory = state.root / "usr/lib/systemd/boot/efi" - if not directory.exists(): + if not directory.exists() or not any(directory.iterdir()): + if state.config.bootable is True: + die("A bootable image was requested but systemd-boot was not found at " + f"{directory.relative_to(state.root)}") return if state.config.secure_boot: @@ -712,12 +718,14 @@ def install_unified_kernel(state: MkosiState, roothash: Optional[str]) -> None: # benefit that they can be signed like normal EFI binaries, and can encode everything necessary to boot a # specific root device, including the root hash. - # The roothash is specific to the final image so we cannot cache this step. - if state.for_cache: + if state.for_cache or state.config.bootable is False: return - with complete_step("Generating combined kernel + initrd boot file…"): - for kver, kimg in gen_kernel_images(state): + if state.config.output_format == OutputFormat.cpio and state.config.bootable is None: + return + + for kver, kimg in gen_kernel_images(state): + with complete_step(f"Generating unified kernel image for {kimg}"): image_id = state.config.image_id or f"mkosi-{state.config.distribution}" # See https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT/#boot-counting @@ -791,9 +799,12 @@ def install_unified_kernel(state: MkosiState, roothash: Optional[str]) -> None: run(cmd) - if not state.staging.joinpath(state.staging / state.config.output_split_kernel.name).exists(): + if not state.staging.joinpath(state.config.output_split_kernel.name).exists(): copy_path(boot_binary, state.staging / state.config.output_split_kernel.name) + if state.config.bootable is True and not state.staging.joinpath(state.config.output_split_kernel.name).exists(): + die("A bootable image was requested but no kernel was found") + def compress_output(config: MkosiConfig, src: Path, uid: int, gid: int) -> None: compress = should_compress_output(config) @@ -1600,6 +1611,9 @@ def run_kernel_install(state: MkosiState, cached: bool) -> None: if state.config.initrds: return + if state.config.bootable is False: + return + # CentOS Stream 8 has an old version of kernel-install that unconditionally writes initrds to # /boot//, so let's detect that and move them to the correct location. @@ -1720,8 +1734,14 @@ def invoke_repart(state: MkosiState, skip: Sequence[str] = [], split: bool = Fal definitions.mkdir() bootdir = state.root.joinpath("boot/EFI/BOOT") - if bootdir.exists() and any(bootdir.iterdir()) and any(gen_kernel_images(state)): - # If we have at least one kernel images and a bootloader, let's generate an ESP partition. + # If Bootable=auto and we have at least one UKI and a bootloader, let's generate an ESP partition. + add = (state.config.bootable is True or + (state.config.bootable is None and + bootdir.exists() and + any(bootdir.iterdir()) and + any(gen_kernel_images(state)))) + + if add: definitions.joinpath("00-esp.conf").write_text( dedent( """\ diff --git a/mkosi/backend.py b/mkosi/backend.py index 24cc4910c..8f5c1adb4 100644 --- a/mkosi/backend.py +++ b/mkosi/backend.py @@ -269,6 +269,7 @@ class MkosiConfig: kernel_command_line_extra: list[str] acl: bool pager: bool + bootable: Optional[bool] # QEMU-specific options qemu_gui: bool diff --git a/mkosi/config.py b/mkosi/config.py index 4233d1c06..68761d784 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -498,6 +498,11 @@ class MkosiConfigParser: parse=config_parse_boolean, default=True, ), + MkosiConfigSetting( + dest="bootable", + section="Content", + parse=config_parse_feature, + ), MkosiConfigSetting( dest="password", section="Content", @@ -1066,7 +1071,12 @@ class MkosiConfigParser: dest="with_tests", action=action, ) - + group.add_argument( + "--bootable", + metavar="FEATURE", + help="Generate ESP partition with systemd-boot and UKIs for installed kernels", + action=action, + ) group.add_argument("--password", help="Set the root password", action=action) group.add_argument( "--password-is-hashed",