]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Use grub binaries from tools tree instead of from image 2271/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 11 Jan 2024 13:07:20 +0000 (14:07 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 11 Jan 2024 18:40:34 +0000 (19:40 +0100)
Let's give this another try and use grub tools from the tools tree
instead of from the image.

We also hardcode the grub prefix per distribution because if we use
grub binaries from the tools tree there might not be any installed
in the image itself which means we can't derive the prefix from the
binaries in the image.

.github/workflows/ci.yml
mkosi/__init__.py
mkosi/distributions/__init__.py
mkosi/distributions/centos.py
mkosi/distributions/fedora.py
mkosi/distributions/opensuse.py
mkosi/resources/mkosi-tools/mkosi.conf.d/10-arch.conf
mkosi/resources/mkosi-tools/mkosi.conf.d/10-centos-fedora/mkosi.conf
mkosi/resources/mkosi-tools/mkosi.conf.d/10-debian-ubuntu.conf
mkosi/resources/mkosi-tools/mkosi.conf.d/10-opensuse.conf

index a29e9571ea6232e4404286e26eb9f10f9a5a96b2..5b6aa6d43d650d1eb65225f9ee4643d184693647 100644 (file)
@@ -150,6 +150,15 @@ jobs:
         QemuKvm=no
         EOF
 
+        # Work around for https://src.fedoraproject.org/rpms/grub2/pull-request/61 by disabling obsoletes.
+        tee mkosi/resources/mkosi-tools/mkosi.local.conf <<EOF
+        [Distribution]
+        PackageManagerTrees=mkosi.pkgmngr
+        EOF
+
+        mkdir -p mkosi/resources/mkosi-tools/mkosi.pkgmngr/etc/dnf
+        echo -e "[main]\nobsoletes=0" > mkosi/resources/mkosi-tools/mkosi.pkgmngr/etc/dnf/dnf.conf
+
         # TODO: Remove once all distros have recent enough systemd that knows systemd.default_device_timeout_sec.
         mkdir -p mkosi-initrd/mkosi.extra/usr/lib/systemd/system.conf.d
         tee mkosi-initrd/mkosi.extra/usr/lib/systemd/system.conf.d/device-timeout.conf <<EOF
index a043a6b9eb599ac71a13fe635bfacf8644828ef1..56c4c859d58488947e35fc6acb697ec4a01378b7 100644 (file)
@@ -1025,17 +1025,9 @@ def find_grub_bios_directory(context: Context) -> Optional[Path]:
     return None
 
 
-def find_grub_binary(context: Context, binary: str) -> Optional[Path]:
+def find_grub_binary(binary: str, root: Path = Path("/")) -> Optional[Path]:
     assert "grub" in binary and "grub2" not in binary
-    return find_binary(binary, root=context.root) or find_binary(binary.replace("grub", "grub2"), root=context.root)
-
-
-def find_grub_prefix(context: Context) -> Optional[str]:
-    path = find_grub_binary(context, "grub-mkimage")
-    if path is None:
-        return None
-
-    return "grub2" if "grub2" in os.fspath(path) else "grub"
+    return find_binary(binary, binary.replace("grub", "grub2"), root=root)
 
 
 def want_grub_efi(context: Context) -> bool:
@@ -1089,8 +1081,7 @@ def want_grub_bios(context: Context, partitions: Sequence[Partition] = ()) -> bo
     installed = True
 
     for binary in ("grub-mkimage", "grub-bios-setup"):
-        path = find_grub_binary(context, binary)
-        if path is not None:
+        if find_grub_binary(binary, root=context.config.tools()):
             continue
 
         if context.config.bootable == ConfigFeature.enabled:
@@ -1102,11 +1093,7 @@ def want_grub_bios(context: Context, partitions: Sequence[Partition] = ()) -> bo
 
 
 def prepare_grub_config(context: Context) -> Optional[Path]:
-    prefix = find_grub_prefix(context)
-    if not prefix:
-        return None
-
-    config = context.root / "efi" / prefix / "grub.cfg"
+    config = context.root / "efi" / context.config.distribution.grub_prefix() / "grub.cfg"
     with umask(~0o700):
         config.parent.mkdir(exist_ok=True)
 
@@ -1123,9 +1110,6 @@ def prepare_grub_efi(context: Context) -> None:
     if not want_grub_efi(context):
         return
 
-    prefix = find_grub_prefix(context)
-    assert prefix
-
     # Signed EFI grub shipped by distributions reads its configuration from /EFI/<distribution>/grub.cfg in
     # the ESP so let's put a shim there to redirect to the actual configuration file.
     earlyconfig = context.root / "efi/EFI" / context.config.distribution.name / "grub.cfg"
@@ -1133,7 +1117,7 @@ def prepare_grub_efi(context: Context) -> None:
         earlyconfig.parent.mkdir(parents=True, exist_ok=True)
 
     # Read the actual config file from the root of the ESP.
-    earlyconfig.write_text(f"configfile /{prefix}/grub.cfg\n")
+    earlyconfig.write_text(f"configfile /{context.config.distribution.grub_prefix()}/grub.cfg\n")
 
     config = prepare_grub_config(context)
     assert config
@@ -1214,24 +1198,21 @@ def prepare_grub_bios(context: Context, partitions: Sequence[Partition]) -> None
     # so we're forced to reimplement its functionality. Luckily that's pretty simple, run grub-mkimage to
     # generate the required core.img and copy the relevant files to the ESP.
 
-    mkimage = find_grub_binary(context, "grub-mkimage")
+    mkimage = find_grub_binary("grub-mkimage", root=context.config.tools())
     assert mkimage
 
     directory = find_grub_bios_directory(context)
     assert directory
 
-    prefix = find_grub_prefix(context)
-    assert prefix
-
-    dst = context.root / "efi" / prefix / "i386-pc"
+    dst = context.root / "efi" / context.config.distribution.grub_prefix() / "i386-pc"
     dst.mkdir(parents=True, exist_ok=True)
 
     with tempfile.NamedTemporaryFile("w", prefix="grub-early-config") as earlyconfig:
         earlyconfig.write(
             textwrap.dedent(
                 f"""\
-                search --no-floppy --set=root --file /{prefix}/grub.cfg
-                set prefix=($root)/{prefix}
+                search --no-floppy --set=root --file /{context.config.distribution.grub_prefix()}/grub.cfg
+                set prefix=($root)/{context.config.distribution.grub_prefix()}
                 """
             )
         )
@@ -1243,7 +1224,7 @@ def prepare_grub_bios(context: Context, partitions: Sequence[Partition]) -> None
                 mkimage,
                 "--directory", directory,
                 "--config", earlyconfig.name,
-                "--prefix", f"/{prefix}",
+                "--prefix", f"/{context.config.distribution.grub_prefix()}",
                 "--output", dst / "core.img",
                 "--format", "i386-pc",
                 *(["--verbose"] if ARG_DEBUG.get() else []),
@@ -1256,7 +1237,6 @@ def prepare_grub_bios(context: Context, partitions: Sequence[Partition]) -> None
             ],
             sandbox=context.sandbox(
                 options=[
-                    "--ro-bind", context.root / "usr", "/usr",
                     "--bind", context.root, context.root,
                     "--ro-bind", earlyconfig.name, earlyconfig.name,
                 ],
@@ -1272,12 +1252,12 @@ def prepare_grub_bios(context: Context, partitions: Sequence[Partition]) -> None
     shutil.copy2(directory / "modinfo.sh", dst)
     shutil.copy2(directory / "boot.img", dst)
 
-    dst = context.root / "efi" / prefix / "fonts"
+    dst = context.root / "efi" / context.config.distribution.grub_prefix() / "fonts"
     with umask(~0o700):
         dst.mkdir(exist_ok=True)
 
-    for prefix in ("grub", "grub2"):
-        unicode = context.root / "usr/share" / prefix / "unicode.pf2"
+    for d in ("grub", "grub2"):
+        unicode = context.root / "usr/share" / d / "unicode.pf2"
         if unicode.exists():
             shutil.copy2(unicode, dst)
 
@@ -1286,12 +1266,9 @@ def install_grub_bios(context: Context, partitions: Sequence[Partition]) -> None
     if not want_grub_bios(context, partitions):
         return
 
-    setup = find_grub_binary(context, "grub-bios-setup")
+    setup = find_grub_binary("grub-bios-setup", root=context.config.tools())
     assert setup
 
-    prefix = find_grub_prefix(context)
-    assert prefix
-
     with (
         complete_step("Installing grub boot loader…"),
         tempfile.NamedTemporaryFile(mode="w") as mountinfo,
@@ -1310,13 +1287,12 @@ def install_grub_bios(context: Context, partitions: Sequence[Partition]) -> None
             [
                 "sh", "-c", f"mount --bind {mountinfo.name} /proc/$$/mountinfo && exec $0 \"$@\"",
                 setup,
-                "--directory", context.root / "efi" / prefix / "i386-pc",
+                "--directory", context.root / "efi" / context.config.distribution.grub_prefix() / "i386-pc",
                 *(["--verbose"] if ARG_DEBUG.get() else []),
                 context.staging / context.config.output_with_format,
             ],
             sandbox=context.sandbox(
                 options=[
-                    "--bind", context.root / "usr", "/usr",
                     "--bind", context.root, context.root,
                     "--bind", context.staging, context.staging,
                     "--bind", mountinfo.name, mountinfo.name,
index 4c289d5d058308b0fa536179e23992e739566f2b..2c4374ae62143752394ba27236cb48a153d1628f 100644 (file)
@@ -63,6 +63,10 @@ class DistributionInstaller:
     def default_tools_tree_distribution(cls) -> Optional["Distribution"]:
         return None
 
+    @classmethod
+    def grub_prefix(cls) -> str:
+        return "grub"
+
 
 class Distribution(StrEnum):
     # Please consult docs/distribution-policy.md and contact one
@@ -136,6 +140,9 @@ class Distribution(StrEnum):
     def default_tools_tree_distribution(self) -> Optional["Distribution"]:
         return self.installer().default_tools_tree_distribution()
 
+    def grub_prefix(self) -> str:
+        return self.installer().grub_prefix()
+
     def installer(self) -> type[DistributionInstaller]:
         modname = str(self).replace('-', '_')
         mod = importlib.import_module(f"mkosi.distributions.{modname}")
index 929146e6ac86f251016564806d1443109957d03a..e01cfb9c1c43fa757111390e4bac47e373e9946c 100644 (file)
@@ -54,6 +54,10 @@ class Installer(DistributionInstaller):
     def default_tools_tree_distribution(cls) -> Distribution:
         return Distribution.fedora
 
+    @classmethod
+    def grub_prefix(cls) -> str:
+        return "grub2"
+
     @classmethod
     def setup(cls, context: Context) -> None:
         if GenericVersion(context.config.release) <= 7:
index c62298d7617bdf4b70ac998b14a8b339837493a1..8484d18599660a2c3c6fa692782b36abf438e8b0 100644 (file)
@@ -36,6 +36,10 @@ class Installer(DistributionInstaller):
     def default_tools_tree_distribution(cls) -> Distribution:
         return Distribution.fedora
 
+    @classmethod
+    def grub_prefix(cls) -> str:
+        return "grub2"
+
     @classmethod
     def setup(cls, context: Context) -> None:
         gpgurls = (
index aba3ff934ed14ff0214e0bee691032ba01fcde46..8b5fbfae1667d267e6408176c8bbe8f8a1a480ea 100644 (file)
@@ -37,6 +37,10 @@ class Installer(DistributionInstaller):
     def default_tools_tree_distribution(cls) -> Distribution:
         return Distribution.opensuse
 
+    @classmethod
+    def grub_prefix(cls) -> str:
+        return "grub2"
+
     @classmethod
     def setup(cls, context: Context) -> None:
         release = context.config.release
index ddbd1ede32406520c1b4e08911ac45a20fada2c4..6ebc654d45b796f94e7aad875d6c98b22c3f3d51 100644 (file)
@@ -13,6 +13,7 @@ Packages=
         debian-archive-keyring
         edk2-ovmf
         erofs-utils
+        grub
         openssh
         pacman
         pesign
index 95a4512d69e0d8cde2760a84615d7e0c835c0319..c1d0422704ed8b931a643372204a524ec3800669 100644 (file)
@@ -14,6 +14,7 @@ Packages=
         debian-keyring
         distribution-gpg-keys
         dnf-plugins-core
+        grub2-tools
         openssh-clients
         policycoreutils
         python3-cryptography
index d002d98a46aedc262674f203e06751b7264dae98..a506728fc38b9a859414671ec3e62abec12cc83e 100644 (file)
@@ -13,6 +13,7 @@ Packages=
         curl
         debian-archive-keyring
         erofs-utils
+        grub2
         libtss2-dev
         makepkg
         openssh-client
index 25971a0d15de29b97fe80acfee14cb090d557918..ce4040b9905473d1e62cba7f3512a06648aee657 100644 (file)
@@ -12,6 +12,7 @@ Packages=
         dnf-plugins-core
         erofs-utils
         grep
+        grub2
         openssh-clients
         ovmf
         pesign