]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
apt: Switch to deb822 format
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 26 Jan 2024 12:09:07 +0000 (13:09 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 26 Jan 2024 15:01:42 +0000 (16:01 +0100)
mkosi/distributions/debian.py
mkosi/distributions/ubuntu.py
mkosi/installer/apt.py

index 1001eb8d69e79a2be9ed9aae857316137c476f13..9fe70b0ca222ce78232743e3a8e467ac4c231657 100644 (file)
@@ -2,14 +2,14 @@
 
 import shutil
 import tempfile
-from collections.abc import Sequence
+from collections.abc import Iterable, Sequence
 from pathlib import Path
 
 from mkosi.archive import extract_tar
 from mkosi.config import Architecture
 from mkosi.context import Context
 from mkosi.distributions import Distribution, DistributionInstaller, PackageType
-from mkosi.installer.apt import createrepo_apt, invoke_apt, setup_apt
+from mkosi.installer.apt import AptRepository, createrepo_apt, invoke_apt, setup_apt
 from mkosi.log import die
 from mkosi.run import run
 from mkosi.sandbox import finalize_passwd_mounts
@@ -38,41 +38,61 @@ class Installer(DistributionInstaller):
         return Distribution.debian
 
     @staticmethod
-    def repositories(context: Context, local: bool = True) -> list[str]:
-        archives = ("deb", "deb-src")
-        components = ' '.join(("main", *context.config.repositories))
+    def repositories(context: Context, local: bool = True) -> Iterable[AptRepository]:
+        types = ("deb", "deb-src")
+        components = ("main", *context.config.repositories)
 
         if context.config.local_mirror and local:
-            return [f"deb [trusted=yes] {context.config.local_mirror} {context.config.release} {components}"]
+            yield AptRepository(
+                types=("deb",),
+                url=context.config.local_mirror,
+                suite=context.config.release,
+                components=("main",),
+                signedby=None,
+            )
+            return
 
         mirror = context.config.mirror or "http://deb.debian.org/debian"
-        signedby = "[signed-by=/usr/share/keyrings/debian-archive-keyring.gpg]"
+        signedby = "/usr/share/keyrings/debian-archive-keyring.gpg"
 
-        repos = [
-            f"{archive} {signedby} {mirror} {context.config.release} {components}"
-            for archive in archives
-        ]
+        yield AptRepository(
+            types=types,
+            url=mirror,
+            suite=context.config.release,
+            components=components,
+            signedby=signedby,
+        )
 
         # Debug repos are typically not mirrored.
         url = "http://deb.debian.org/debian-debug"
-        repos += [f"deb {signedby} {url} {context.config.release}-debug {components}"]
-
-        if context.config.release in ("unstable", "sid"):
-            return repos
 
-        repos += [
-            f"{archive} {signedby} {mirror} {context.config.release}-updates {components}"
-            for archive in archives
-        ]
+        yield AptRepository(
+            types=types,
+            url=url,
+            suite=f"{context.config.release}-debug",
+            components=components,
+            signedby=signedby,
+        )
 
-        # Security updates repos are never mirrored.
-        url = "http://security.debian.org/debian-security "
-        repos += [
-            f"{archive} {signedby} {url} {context.config.release}-security {components}"
-            for archive in archives
-        ]
-
-        return repos
+        if context.config.release in ("unstable", "sid"):
+            return
+
+        yield AptRepository(
+            types=types,
+            url=mirror,
+            suite=f"{context.config.release}-updates",
+            components=components,
+            signedby=signedby,
+        )
+
+        yield AptRepository(
+            types=types,
+            # Security updates repos are never mirrored.
+            url="http://security.debian.org/debian-security",
+            suite=f"{context.config.release}-security",
+            components=components,
+            signedby=signedby,
+        )
 
     @classmethod
     def setup(cls, context: Context) -> None:
@@ -217,12 +237,12 @@ class Installer(DistributionInstaller):
         return a
 
 
-def install_apt_sources(context: Context, repos: Sequence[str]) -> None:
+def install_apt_sources(context: Context, repos: Iterable[AptRepository]) -> None:
     if not (context.root / "usr/bin/apt").exists():
         return
 
-    sources = context.root / "etc/apt/sources.list"
+    sources = context.root / f"etc/apt/sources.list.d/{context.config.release}.sources"
     if not sources.exists():
         with sources.open("w") as f:
             for repo in repos:
-                f.write(f"{repo}\n")
+                f.write(str(repo))
index 3b01c05c0d956cd1ca9c394fdc50ac02789ac705..7313f31bafe7e3574d9195af3c830da348387ff0 100644 (file)
@@ -1,8 +1,11 @@
 # SPDX-License-Identifier: LGPL-2.1+
 
+from collections.abc import Iterable
+
 from mkosi.config import Architecture
 from mkosi.context import Context
 from mkosi.distributions import debian
+from mkosi.installer.apt import AptRepository
 
 
 class Installer(debian.Installer):
@@ -15,33 +18,46 @@ class Installer(debian.Installer):
         return "lunar"
 
     @staticmethod
-    def repositories(context: Context, local: bool = True) -> list[str]:
-        if context.config.local_mirror and local:
-            return [f"deb [trusted=yes] {context.config.local_mirror} {context.config.release} main"]
+    def repositories(context: Context, local: bool = True) -> Iterable[AptRepository]:
+        types = ("deb", "deb-src")
 
-        archives = ("deb", "deb-src")
+        # From kinetic onwards, the usr-is-merged package is available in universe and is required by
+        # mkosi to set up a proper usr-merged system so we add the universe repository unconditionally.
+        components = ["main"] + (["universe"] if context.config.release not in ("focal", "jammy") else [])
+        components = (*components, *context.config.repositories)
+
+        if context.config.local_mirror and local:
+            yield AptRepository(
+                types=("deb",),
+                url=context.config.local_mirror,
+                suite=context.config.release,
+                components=("main",),
+                signedby=None,
+            )
+            return
 
         if context.config.architecture in (Architecture.x86, Architecture.x86_64):
             mirror = context.config.mirror or "http://archive.ubuntu.com/ubuntu"
         else:
             mirror = context.config.mirror or "http://ports.ubuntu.com"
 
-        signedby = "[signed-by=/usr/share/keyrings/ubuntu-archive-keyring.gpg]"
-
-        # From kinetic onwards, the usr-is-merged package is available in universe and is required by
-        # mkosi to set up a proper usr-merged system so we add the universe repository unconditionally.
-        components = ["main"] + (["universe"] if context.config.release not in ("focal", "jammy") else [])
-        components = ' '.join((*components, *context.config.repositories))
+        signedby = "/usr/share/keyrings/ubuntu-archive-keyring.gpg"
 
-        repos = [
-            f"{archive} {signedby} {mirror} {context.config.release} {components}"
-            for archive in archives
-        ]
+        yield AptRepository(
+            types=types,
+            url=mirror,
+            suite=context.config.release,
+            components=components,
+            signedby=signedby,
+        )
 
-        repos += [
-            f"{archive} {signedby} {mirror} {context.config.release}-updates {components}"
-            for archive in archives
-        ]
+        yield AptRepository(
+            types=types,
+            url=mirror,
+            suite=f"{context.config.release}-updates",
+            components=components,
+            signedby=signedby,
+        )
 
         # Security updates repos are never mirrored. But !x86 are on the ports server.
         if context.config.architecture in [Architecture.x86, Architecture.x86_64]:
@@ -49,9 +65,11 @@ class Installer(debian.Installer):
         else:
             mirror = "http://ports.ubuntu.com/"
 
-        repos += [
-            f"{archive} {signedby} {mirror} {context.config.release}-security {components}"
-            for archive in archives
-        ]
+        yield AptRepository(
+            types=types,
+            url=mirror,
+            suite=f"{context.config.release}-security",
+            components=components,
+            signedby=signedby,
+        )
 
-        return repos
index 44a7b509bfcfd5e01e70ddc6bb26d6f69938d967..cc98d38570e77b0bcb7a60bed793cb35f60f6c86 100644 (file)
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: LGPL-2.1+
 import textwrap
-from collections.abc import Sequence
+from collections.abc import Iterable, Sequence
+from typing import NamedTuple, Optional
 
 from mkosi.context import Context
 from mkosi.installer import finalize_package_manager_mounts
@@ -11,7 +12,27 @@ from mkosi.types import PathString
 from mkosi.util import sort_packages, umask
 
 
-def setup_apt(context: Context, repos: Sequence[str]) -> None:
+class AptRepository(NamedTuple):
+    types: tuple[str, ...]
+    url: str
+    suite: str
+    components: tuple[str, ...]
+    signedby: Optional[str]
+
+    def __str__(self) -> str:
+        return textwrap.dedent(
+            f"""\
+            Types: {" ".join(self.types)}
+            URIs: {self.url}
+            Suites: {self.suite}
+            Components: {" ".join(self.components)}
+            {"Signed-By" if self.signedby else "Trusted"}: {self.signedby or "yes"}
+
+            """
+        )
+
+
+def setup_apt(context: Context, repos: Iterable[AptRepository]) -> None:
     (context.pkgmngr / "etc/apt").mkdir(exist_ok=True, parents=True)
     (context.pkgmngr / "etc/apt/apt.conf.d").mkdir(exist_ok=True, parents=True)
     (context.pkgmngr / "etc/apt/preferences.d").mkdir(exist_ok=True, parents=True)
@@ -39,11 +60,11 @@ def setup_apt(context: Context, repos: Sequence[str]) -> None:
             )
         )
 
-    sources = context.pkgmngr / "etc/apt/sources.list"
+    sources = context.pkgmngr / "etc/apt/sources.list.d/mkosi.sources"
     if not sources.exists():
         with sources.open("w") as f:
             for repo in repos:
-                f.write(f"{repo}\n")
+                f.write(str(repo))
 
 
 def apt_cmd(context: Context, command: str) -> list[PathString]: