]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
arch: Download archlinux-keyring with pacman
authorDaanDeMeyer <daan.j.demeyer@gmail.com>
Fri, 26 Dec 2025 09:55:24 +0000 (10:55 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 26 Dec 2025 11:48:33 +0000 (12:48 +0100)
curl-ing the Arch Linux website fails quite often due to connection
issues. Let's try downloading the archlinux-keyring package with
Pacman so we go directly to a mirror and avoid hitting the Arch
Linux website.

mkosi/__init__.py
mkosi/distribution/arch.py
mkosi/installer/pacman.py

index deac0ef333f02f110a34d7b675c66b61f1f2b7cf..dc612b0ae5155b627545bda54970bf3819d7ca8e 100644 (file)
@@ -4845,13 +4845,14 @@ def sync_repository_metadata(
             install_sandbox_trees(context.config, context.sandbox_tree)
             context.config.distribution.installer.setup(context)
 
-            context.config.distribution.installer.keyring(context)
-
             with complete_step("Syncing package manager metadata"):
                 context.config.distribution.installer.package_manager(context.config).sync(
                     context,
                     force=context.args.force > 1 or context.config.cacheonly == Cacheonly.never,
                 )
+
+            context.config.distribution.installer.keyring(context)
+
         src = metadata_dir / "cache" / subdir
         dst = last.package_cache_dir_or_default() / "cache" / subdir
 
index 3ff99e5cc5cdbd57b52f4772c802924564d711b3..abcff507c8e28263674967e9a0973d4b283522b5 100644 (file)
@@ -1,9 +1,7 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 
 import datetime
-import tempfile
 from collections.abc import Iterable
-from pathlib import Path
 
 from mkosi.archive import extract_tar
 from mkosi.config import Architecture, Config
@@ -38,22 +36,47 @@ class Installer(DistributionInstaller, distribution=Distribution.arch):
     @classmethod
     def keyring(cls, context: Context) -> None:
         if context.config.repository_key_fetch:
-            with (
-                complete_step(f"Downloading {cls.pretty_name()} keyring"),
-                tempfile.TemporaryDirectory() as d,
-            ):
-                curl(
-                    context.config,
-                    "https://archlinux.org/packages/core/any/archlinux-keyring/download",
-                    output_dir=Path(d),
+            with complete_step(f"Downloading {cls.pretty_name()} keyring"):
+                # We can't override pacman configuration options from the command line so we fall back to
+                # appending to the configuration file instead.
+                config = context.sandbox_tree / "etc/pacman.conf"
+                content = config.read_text()
+                with config.open("a") as f:
+                    f.write("\n[options]\n")
+                    f.write("SigLevel = Never\n")
+
+                # We can't download a package without a dependencies without listing them in
+                # --assume-installed. Luckily archlinux-keyring only depends on pacman.
+                Pacman.install(
+                    context,
+                    ["archlinux-keyring"],
+                    apivfs=False,
+                    options=["--downloadonly", "--assume-installed", "pacman"],
                 )
+
+                packages = sorted(
+                    p
+                    for p in (
+                        context.config.package_cache_dir_or_default()
+                        / "cache"
+                        / Pacman.subdir(context.config)
+                        / "pkg"
+                    ).glob("archlinux-keyring-*.pkg.tar*")
+                    if not p.name.endswith(".sig")
+                )
+                if not packages:
+                    die("Could not find archlinux-keyring package in cache directory after downloading it")
+
                 extract_tar(
-                    next(Path(d).iterdir()),
+                    packages[-1],
                     context.sandbox_tree,
                     dirs=["usr/share/pacman/keyrings"],
                     sandbox=context.sandbox,
                 )
 
+                # Restore the original configuration file.
+                config.write_text(content)
+
         Pacman.keyring(context)
 
     @classmethod
index a099b7fdac1588bb2ce98bead48000e3a1900201..433951d36f89eeec95853f4dd1fde19a3c78fc29 100644 (file)
@@ -65,7 +65,7 @@ class Pacman(PackageManager):
             "--ro-bind", context.repository, "/var/cache/pacman/mkosi",
         ]  # fmt: skip
 
-        if any(context.keyring_dir.iterdir()):
+        if context.keyring_dir.exists() and any(context.keyring_dir.iterdir()):
             mounts += ["--ro-bind", context.keyring_dir, "/etc/pacman.d/gnupg"]
 
         if (context.root / "var/lib/pacman/local").exists():
@@ -201,13 +201,14 @@ class Pacman(PackageManager):
         *,
         apivfs: bool = True,
         allow_downgrade: bool = False,
+        options: Sequence[str] = (),
     ) -> None:
         arguments = ["--needed", "--assume-installed", "initramfs"]
 
         if allow_downgrade:
             arguments += ["--sysupgrade", "--sysupgrade"]
 
-        arguments += [*packages]
+        arguments += [*options, *packages]
 
         cls.invoke(context, "--sync", arguments, apivfs=apivfs)