extract_pe_section(context, output, ".initrd", context.staging / context.config.output_split_initrd)
+def make_initrd_addon(context: Context, stub: Path, output: Path) -> None:
+ make_cpio(context.root, context.workspace / "initrd", sandbox=context.sandbox)
+ maybe_compress(
+ context,
+ context.config.compress_output,
+ context.workspace / "initrd",
+ context.workspace / "initrd",
+ )
+ arguments: list[PathString] = ["--initrd", workdir(context.workspace / "initrd")]
+ options: list[PathString] = [
+ "--ro-bind", context.workspace / "initrd", workdir(context.workspace / "initrd")
+ ] # fmt: skip
+
+ with complete_step(f"Generating initrd PE addon {output}"):
+ run_ukify(
+ context,
+ stub,
+ output,
+ arguments=arguments,
+ options=options,
+ )
+
+
def compressor_command(context: Context, compression: Compression) -> list[PathString]:
"""Returns a command suitable for compressing archives."""
return True
-def save_uki_components(
+def save_esp_components(
context: Context,
) -> tuple[Optional[Path], Optional[str], Optional[Path], list[Path]]:
+ if context.config.output_format == OutputFormat.initrd_addon:
+ stub = systemd_addon_stub_binary(context)
+ if not stub.exists():
+ die(f"sd-stub not found at /{stub.relative_to(context.root)} in the image")
+
+ return shutil.copy2(stub, context.workspace), None, None, []
+
if context.config.output_format not in (OutputFormat.uki, OutputFormat.esp):
return None, None, None, []
run_hwdb(context)
# These might be removed by the next steps, so let's save them for later if needed.
- stub, kver, kimg, microcode = save_uki_components(context)
+ stub, kver, kimg, microcode = save_esp_components(context)
remove_packages(context)
assert stub and kver and kimg
make_uki(context, stub, kver, kimg, microcode, context.staging / context.config.output_split_uki)
make_esp(context, context.staging / context.config.output_split_uki)
+ elif context.config.output_format == OutputFormat.initrd_addon:
+ assert stub
+ make_initrd_addon(context, stub, context.staging / context.config.output_with_format)
elif context.config.output_format.is_extension_or_portable_image():
make_extension_or_portable_image(context, context.staging / context.config.output_with_format)
elif context.config.output_format == OutputFormat.directory:
tar = enum.auto()
uki = enum.auto()
oci = enum.auto()
+ initrd_addon = enum.auto()
def extension(self) -> str:
return {
- OutputFormat.confext: ".raw",
- OutputFormat.cpio: ".cpio",
- OutputFormat.disk: ".raw",
- OutputFormat.esp: ".raw",
- OutputFormat.portable: ".raw",
- OutputFormat.sysext: ".raw",
- OutputFormat.tar: ".tar",
- OutputFormat.uki: ".efi",
+ OutputFormat.confext: ".raw",
+ OutputFormat.cpio: ".cpio",
+ OutputFormat.disk: ".raw",
+ OutputFormat.esp: ".raw",
+ OutputFormat.portable: ".raw",
+ OutputFormat.sysext: ".raw",
+ OutputFormat.tar: ".tar",
+ OutputFormat.uki: ".efi",
+ OutputFormat.initrd_addon: ".efi",
}.get(self, "") # fmt: skip
def use_outer_compression(self) -> bool:
)
def is_extension_image(self) -> bool:
- return self in (OutputFormat.sysext, OutputFormat.confext)
+ return self in (OutputFormat.sysext, OutputFormat.confext, OutputFormat.initrd_addon)
def is_extension_or_portable_image(self) -> bool:
return self.is_extension_image() or self == OutputFormat.portable
partition table), `uki` (a unified kernel image with the OS image in
the `.initrd` PE section), `esp` (`uki` but wrapped in a disk image
with only an ESP partition), `oci` (a directory compatible with the
- OCI image specification), `sysext`, `confext`, `portable` or `none`
- (the OS image is solely intended as a build image to produce another
- artifact).
+ OCI image specification), `sysext`, `confext`, `portable`,
+ `initrd-addon` or `none` (the OS image is solely intended as a build
+ image to produce another artifact).
If the `disk` output format is used, the disk image is generated using
`systemd-repart`. The repart partition definition files to use can be
import pytest
+from mkosi.config import OutputFormat
+
from . import Image, ImageConfig
pytestmark = pytest.mark.integration
-def test_sysext(config: ImageConfig) -> None:
+@pytest.mark.parametrize("format", [f for f in OutputFormat if f.is_extension_image()])
+def test_extension(config: ImageConfig, format: OutputFormat) -> None:
with Image(config) as image:
image.build(["--clean-package-metadata=no", "--format=directory"])
"--directory",
"",
"--incremental=no",
- "--base-tree",
- Path(image.output_dir) / "image",
+ "--base-tree", Path(image.output_dir) / "image",
"--overlay",
"--package=dnsmasq",
- "--format=disk",
+ f"--format={format}",
]
- )
+ ) # fmt: skip