]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Add initrd-addon output format 3280/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 17 Dec 2024 08:46:24 +0000 (09:46 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 17 Dec 2024 11:30:09 +0000 (12:30 +0100)
Similar to how we can produce sysext and confext extensions, let's also
support building initrd addons.

mkosi/__init__.py
mkosi/config.py
mkosi/resources/man/mkosi.1.md
tests/test_extension.py [moved from tests/test_sysext.py with 61% similarity]

index dc981a08a3b71204bf82782cf99705ab28f91f3c..7b77a774fe52a99c890b290973c2a769962d19d1 100644 (file)
@@ -2147,6 +2147,29 @@ def make_uki(
         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."""
 
@@ -3062,9 +3085,16 @@ def reuse_cache(context: Context) -> bool:
     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, []
 
@@ -3690,7 +3720,7 @@ def build_image(context: Context) -> 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)
 
@@ -3737,6 +3767,9 @@ def build_image(context: Context) -> None:
         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:
index 71036d770cc84b41cd0f319b683e738b100fc111..fc4e92e7d01065739e62313c2af3869b76a258a7 100644 (file)
@@ -189,17 +189,19 @@ class OutputFormat(StrEnum):
     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:
@@ -213,7 +215,7 @@ class OutputFormat(StrEnum):
         )
 
     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
index 1ae006a6991e80142ac4ea28cc1ed2432c44811f..0d5d8f0b5d0001ebc2181d1b1b8743971a0cab7c 100644 (file)
@@ -518,9 +518,9 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
     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
similarity index 61%
rename from tests/test_sysext.py
rename to tests/test_extension.py
index c8c3b73000157b8e4b3a344a0073d3bbb58772c6..14624f5f22f676d5438bd173e8896ba55a0be998 100644 (file)
@@ -4,12 +4,15 @@ from pathlib import Path
 
 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"])
 
@@ -19,10 +22,9 @@ def test_sysext(config: ImageConfig) -> None:
                     "--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