class Firmware(StrEnum):
auto = enum.auto()
linux = enum.auto()
+ linux_noinitrd = enum.auto()
uefi = enum.auto()
uefi_secure_boot = enum.auto()
bios = enum.auto()
def is_uefi(self) -> bool:
return self in (Firmware.uefi, Firmware.uefi_secure_boot)
+ def is_linux(self) -> bool:
+ return self in (Firmware.linux, Firmware.linux_noinitrd)
+
class ConsoleMode(StrEnum):
interactive = enum.auto()
yield Path(file.name)
+@contextlib.contextmanager
+def finalize_initrd(config: Config) -> Iterator[Optional[Path]]:
+ with contextlib.ExitStack() as stack:
+ if (config.output_dir_or_cwd() / config.output_split_initrd).exists():
+ yield config.output_dir_or_cwd() / config.output_split_initrd
+ elif config.initrds:
+ initrd = config.output_dir_or_cwd() / f"initrd-{uuid.uuid4().hex}"
+ join_initrds(config, config.initrds, initrd)
+ stack.callback(lambda: initrd.unlink())
+ yield initrd
+ else:
+ yield None
+
+
@contextlib.contextmanager
def finalize_state(config: Config, cid: int) -> Iterator[None]:
(INVOKING_USER.runtime_dir() / "machine").mkdir(parents=True, exist_ok=True)
if (
config.output_format in (OutputFormat.cpio, OutputFormat.uki, OutputFormat.esp)
- and config.firmware not in (Firmware.auto, Firmware.linux)
+ and not config.firmware.is_linux()
and not config.firmware.is_uefi()
+ and config.firmware != Firmware.auto
):
die(f"{config.output_format} images cannot be booted with the '{config.firmware}' firmware")
firmware = finalize_firmware(config, kernel, kerneltype)
if not kernel and (
- firmware == Firmware.linux
+ firmware.is_linux()
or config.output_format in (OutputFormat.cpio, OutputFormat.directory, OutputFormat.uki)
):
if firmware.is_uefi():
if config.output_format == OutputFormat.cpio:
cmdline += ["-initrd", fname]
- elif kernel and kerneltype != KernelType.uki and "-initrd" not in args.cmdline:
- if (config.output_dir_or_cwd() / config.output_split_initrd).exists():
- cmdline += ["-initrd", config.output_dir_or_cwd() / config.output_split_initrd]
- elif config.initrds:
- initrd = config.output_dir_or_cwd() / f"initrd-{uuid.uuid4().hex}"
- join_initrds(config, config.initrds, initrd)
- stack.callback(lambda: initrd.unlink())
- cmdline += ["-initrd", initrd]
+ elif (
+ kernel
+ and kerneltype != KernelType.uki
+ and "-initrd" not in args.cmdline
+ and firmware != Firmware.linux_noinitrd
+ and (initrd := stack.enter_context(finalize_initrd(config)))
+ ):
+ cmdline += ["-initrd", initrd]
if config.output_format in (OutputFormat.disk, OutputFormat.esp):
blockdev = [
`Firmware=`, `--firmware=`
: Configures the virtual machine firmware to use. Takes one of `uefi`,
- `uefi-secure-boot`, `bios`, `linux`, or `auto`. Defaults to `auto`.
- When set to `uefi`, the OVMF firmware without secure boot support
- is used. When set to `uefi-secure-boot`, the OVMF firmware with
- secure boot support is used. When set to `bios`, the default SeaBIOS
- firmware is used. When set to `linux`, direct kernel boot is used.
- See the `Linux=` option for more details on which kernel image is
- used with direct kernel boot. When set to `auto`, `uefi-secure-boot`
- is used if possible and `linux` otherwise.
+ `uefi-secure-boot`, `bios`, `linux`, `linux-noinitrd` or `auto`.
+ Defaults to `auto`. When set to `uefi`, the OVMF firmware without
+ secure boot support is used. When set to `uefi-secure-boot`, the
+ OVMF firmware with secure boot support is used. When set to `bios`,
+ the default SeaBIOS firmware is used. When set to `linux`, direct
+ kernel boot is used. See the `Linux=` option for more details on
+ which kernel image is used with direct kernel boot.
+ `linux-noinitrd` is identical to `linux` except that no initrd is
+ used. When set to `auto`, `uefi-secure-boot` is used if possible and
+ `linux` otherwise.
`FirmwareVariables=`, `--firmware-variables=`
: Configures the path to the the virtual machine firmware variables file
copy_ephemeral,
finalize_credentials,
finalize_firmware,
+ finalize_initrd,
finalize_kernel_command_line_extra,
finalize_register,
)
kernel = config.expand_linux_specifiers() if config.linux else None
firmware = finalize_firmware(config, kernel)
- if not kernel and firmware == Firmware.linux:
+ if not kernel and firmware.is_linux():
kernel = config.output_dir_or_cwd() / config.output_split_kernel
if not kernel.exists():
die(
if kernel:
cmdline += ["--linux", kernel]
+ if firmware != Firmware.linux_noinitrd and (
+ initrd := stack.enter_context(finalize_initrd(config))
+ ):
+ cmdline += ["--initrd", initrd]
+
if config.output_format == OutputFormat.directory:
cmdline += ["--directory", fname]