- 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`.
<!-- FIXME: allow `Force=<n>` -->
+`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
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:
# 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
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)
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/<machine-id>/<kver>, so let's detect that and move them to the correct location.
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(
"""\