From: Daan De Meyer Date: Thu, 16 Oct 2025 12:52:37 +0000 (+0200) Subject: Make sure apt sources are installed when BaseTrees= is in the mix X-Git-Tag: v26~71 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83a25324b3bdae250095440689376d4f669e01ec;p=thirdparty%2Fmkosi.git Make sure apt sources are installed when BaseTrees= is in the mix Let's make sure to install apt sources every time we install the apt package, even if BaseTrees= or volatile packages or such are in the mix. To make this work we unfortunately have to reintroduce install_packages(). While we're at it, make sure the installed apt sources don't use the configured mirror or snapshot. We only install a default set of sources and for anything custom users should install their own sources. --- diff --git a/mkosi/__init__.py b/mkosi/__init__.py index 8e6203c73..a77cdb84a 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -268,7 +268,7 @@ def install_distribution(context: Context) -> None: with complete_step( f"Installing extra packages for {context.config.distribution.installer.pretty_name()}" ): - context.config.distribution.installer.package_manager(context.config).install(context, packages) + context.config.distribution.installer.install_packages(context, packages) else: if context.config.overlay or context.config.output_format.is_extension_image(): if packages: @@ -307,9 +307,7 @@ def install_distribution(context: Context) -> None: (context.root / "boot/loader/entries.srel").write_text("type1\n") if packages: - context.config.distribution.installer.package_manager(context.config).install( - context, packages - ) + context.config.distribution.installer.install_packages(context, packages) for f in ( "var/lib/systemd/random-seed", @@ -333,9 +331,7 @@ def install_build_packages(context: Context) -> None: ), setup_build_overlay(context), ): - context.config.distribution.installer.package_manager(context.config).install( - context, context.config.build_packages - ) + context.config.distribution.installer.install_packages(context, context.config.build_packages) def install_volatile_packages(context: Context) -> None: @@ -345,7 +341,7 @@ def install_volatile_packages(context: Context) -> None: with complete_step( f"Installing volatile packages for {context.config.distribution.installer.pretty_name()}" ): - context.config.distribution.installer.package_manager(context.config).install( + context.config.distribution.installer.install_packages( context, context.config.volatile_packages, allow_downgrade=True ) diff --git a/mkosi/distribution/__init__.py b/mkosi/distribution/__init__.py index 65753f325..2b8b632bd 100644 --- a/mkosi/distribution/__init__.py +++ b/mkosi/distribution/__init__.py @@ -3,6 +3,7 @@ import enum import importlib import urllib.parse +from collections.abc import Sequence from pathlib import Path from typing import TYPE_CHECKING, Optional @@ -101,6 +102,22 @@ class DistributionInstaller: def install(cls, context: "Context") -> None: raise NotImplementedError + @classmethod + def install_packages( + cls, + context: "Context", + packages: Sequence[str], + *, + apivfs: bool = True, + allow_downgrade: bool = False, + ) -> None: + return cls.package_manager(context.config).install( + context, + packages, + apivfs=apivfs, + allow_downgrade=allow_downgrade, + ) + @classmethod def filesystem(cls) -> str: return "ext4" diff --git a/mkosi/distribution/arch.py b/mkosi/distribution/arch.py index a01ea6636..1fc31014f 100644 --- a/mkosi/distribution/arch.py +++ b/mkosi/distribution/arch.py @@ -62,7 +62,7 @@ class Installer(DistributionInstaller, distribution=Distribution.arch): @classmethod def install(cls, context: Context) -> None: - Pacman.install(context, ["filesystem"], apivfs=False) + cls.install_packages(context, ["filesystem"], apivfs=False) @classmethod def repositories(cls, context: Context) -> Iterable[PacmanRepository]: diff --git a/mkosi/distribution/azure.py b/mkosi/distribution/azure.py index 4c036f143..a440cc347 100644 --- a/mkosi/distribution/azure.py +++ b/mkosi/distribution/azure.py @@ -34,7 +34,7 @@ class Installer(fedora.Installer, distribution=Distribution.azure): @classmethod def install(cls, context: Context) -> None: - Dnf.install(context, ["filesystem", "azurelinux-release"], apivfs=False) + cls.install_packages(context, ["filesystem", "azurelinux-release"], apivfs=False) @classmethod def repositories(cls, context: Context) -> Iterable[RpmRepository]: diff --git a/mkosi/distribution/centos.py b/mkosi/distribution/centos.py index 7c8e89652..57176a30a 100644 --- a/mkosi/distribution/centos.py +++ b/mkosi/distribution/centos.py @@ -79,7 +79,7 @@ class Installer(DistributionInstaller, distribution=Distribution.centos): @classmethod def install(cls, context: Context) -> None: - Dnf.install(context, ["basesystem"], apivfs=False) + cls.install_packages(context, ["basesystem"], apivfs=False) @classmethod def architecture(cls, arch: Architecture) -> str: diff --git a/mkosi/distribution/debian.py b/mkosi/distribution/debian.py index 9d1e1a520..ca95dd426 100644 --- a/mkosi/distribution/debian.py +++ b/mkosi/distribution/debian.py @@ -1,9 +1,8 @@ # SPDX-License-Identifier: LGPL-2.1-or-later -import itertools import json import tempfile -from collections.abc import Iterable +from collections.abc import Iterable, Sequence from pathlib import Path from typing import cast @@ -40,11 +39,13 @@ class Installer(DistributionInstaller, distribution=Distribution.debian): return Apt @classmethod - def repositories(cls, context: Context, local: bool = True) -> Iterable[AptRepository]: + def repositories(cls, context: Context, for_image: bool = False) -> Iterable[AptRepository]: types = ("deb", "deb-src") components = ("main", *context.config.repositories) + mirror = None if for_image else context.config.mirror + snapshot = None if for_image else context.config.snapshot - if context.config.local_mirror and local: + if context.config.local_mirror and not for_image: yield AptRepository( types=("deb",), url=context.config.local_mirror, @@ -54,15 +55,15 @@ class Installer(DistributionInstaller, distribution=Distribution.debian): ) return - if context.config.mirror: - mirror = context.config.mirror - elif context.config.snapshot: + if mirror: + pass + elif snapshot: mirror = "https://snapshot.debian.org" else: mirror = "http://deb.debian.org" - if context.config.snapshot: - url = join_mirror(mirror, f"archive/debian/{context.config.snapshot}") + if snapshot: + url = join_mirror(mirror, f"archive/debian/{snapshot}") else: url = join_mirror(mirror, "debian") @@ -77,8 +78,8 @@ class Installer(DistributionInstaller, distribution=Distribution.debian): ) # Debug repos are typically not mirrored. - if context.config.snapshot: - url = join_mirror(mirror, f"archive/debian-debug/{context.config.snapshot}") + if snapshot: + url = join_mirror(mirror, f"archive/debian-debug/{snapshot}") else: url = join_mirror(mirror, "debian-debug") @@ -93,7 +94,7 @@ class Installer(DistributionInstaller, distribution=Distribution.debian): if context.config.release in ("unstable", "sid"): return - if not context.config.snapshot: + if not snapshot: yield AptRepository( types=types, url=join_mirror(mirror, "debian"), @@ -103,8 +104,8 @@ class Installer(DistributionInstaller, distribution=Distribution.debian): ) # Security updates repos are never mirrored. - if context.config.snapshot: - url = join_mirror(mirror, f"archive/debian-security/{context.config.snapshot}") + if snapshot: + url = join_mirror(mirror, f"archive/debian-security/{snapshot}") else: url = join_mirror(mirror, "debian-security") @@ -210,15 +211,25 @@ class Installer(DistributionInstaller, distribution=Distribution.debian): # Finally, run apt to properly install packages in the chroot without having to worry that maintainer # scripts won't find basic tools that they depend on. - Apt.install(context, [Path(deb).name.partition("_")[0].removesuffix(".deb") for deb in essential]) + cls.install_packages( + context, [Path(deb).name.partition("_")[0].removesuffix(".deb") for deb in essential] + ) fixup_os_release(context) - if ( - "apt" in itertools.chain(context.config.packages, context.config.volatile_packages) - or (context.root / "usr/bin/apt").exists() - ): - install_apt_sources(context, cls.repositories(context, local=False)) + @classmethod + def install_packages( + cls, + context: Context, + packages: Sequence[str], + *, + apivfs: bool = True, + allow_downgrade: bool = False, + ) -> None: + super().install_packages(context, packages, apivfs=apivfs, allow_downgrade=allow_downgrade) + + if "apt" in packages: + install_apt_sources(context, cls.repositories(context, for_image=True)) @classmethod def architecture(cls, arch: Architecture) -> str: diff --git a/mkosi/distribution/fedora.py b/mkosi/distribution/fedora.py index 3574fe8ac..8a8cc4fac 100644 --- a/mkosi/distribution/fedora.py +++ b/mkosi/distribution/fedora.py @@ -137,7 +137,7 @@ class Installer(DistributionInstaller, distribution=Distribution.fedora): @classmethod def install(cls, context: Context) -> None: - Dnf.install(context, ["basesystem"], apivfs=False) + cls.install_packages(context, ["basesystem"], apivfs=False) @classmethod def repositories(cls, context: Context) -> Iterable[RpmRepository]: diff --git a/mkosi/distribution/kali.py b/mkosi/distribution/kali.py index 9de806d15..d3dec56b7 100644 --- a/mkosi/distribution/kali.py +++ b/mkosi/distribution/kali.py @@ -24,11 +24,15 @@ class Installer(debian.Installer, distribution=Distribution.kali): return Distribution.kali @classmethod - def repositories(cls, context: Context, local: bool = True) -> Iterable[AptRepository]: - if context.config.snapshot: + def repositories(cls, context: Context, for_image: bool = False) -> Iterable[AptRepository]: + mirror = None if for_image else context.config.mirror + if not mirror: + mirror = "http://http.kali.org/kali" + + if context.config.snapshot and not for_image: die(f"Snapshot= is not supported for {cls.pretty_name()}") - if context.config.local_mirror and local: + if context.config.local_mirror and not for_image: yield AptRepository( types=("deb",), url=context.config.local_mirror, @@ -40,7 +44,7 @@ class Installer(debian.Installer, distribution=Distribution.kali): yield AptRepository( types=("deb", "deb-src"), - url=context.config.mirror or "http://http.kali.org/kali", + url=mirror, suite=context.config.release, components=("main", *context.config.repositories), signedby=Path("/usr/share/keyrings/kali-archive-keyring.gpg"), diff --git a/mkosi/distribution/mageia.py b/mkosi/distribution/mageia.py index 43756bef7..657af17c6 100644 --- a/mkosi/distribution/mageia.py +++ b/mkosi/distribution/mageia.py @@ -5,7 +5,6 @@ from collections.abc import Iterable from mkosi.config import Architecture from mkosi.context import Context from mkosi.distribution import Distribution, fedora, join_mirror -from mkosi.installer.dnf import Dnf from mkosi.installer.rpm import RpmRepository, find_rpm_gpgkey from mkosi.log import die @@ -25,7 +24,7 @@ class Installer(fedora.Installer, distribution=Distribution.mageia): @classmethod def install(cls, context: Context) -> None: - Dnf.install(context, ["filesystem"], apivfs=False) + cls.install_packages(context, ["filesystem"], apivfs=False) @classmethod def repositories(cls, context: Context) -> Iterable[RpmRepository]: diff --git a/mkosi/distribution/openmandriva.py b/mkosi/distribution/openmandriva.py index dd9661ed8..424a04f24 100644 --- a/mkosi/distribution/openmandriva.py +++ b/mkosi/distribution/openmandriva.py @@ -5,7 +5,6 @@ from collections.abc import Iterable from mkosi.config import Architecture from mkosi.context import Context from mkosi.distribution import Distribution, fedora, join_mirror -from mkosi.installer.dnf import Dnf from mkosi.installer.rpm import RpmRepository, find_rpm_gpgkey from mkosi.log import die @@ -25,7 +24,7 @@ class Installer(fedora.Installer, distribution=Distribution.openmandriva): @classmethod def install(cls, context: Context) -> None: - Dnf.install(context, ["filesystem"], apivfs=False) + cls.install_packages(context, ["filesystem"], apivfs=False) @classmethod def repositories(cls, context: Context) -> Iterable[RpmRepository]: diff --git a/mkosi/distribution/opensuse.py b/mkosi/distribution/opensuse.py index 58f96f9b1..44e4c3a68 100644 --- a/mkosi/distribution/opensuse.py +++ b/mkosi/distribution/opensuse.py @@ -57,7 +57,7 @@ class Installer(DistributionInstaller, distribution=Distribution.opensuse): if not any(p.endswith("-release") for p in context.config.packages): packages += ["openSUSE-release"] - cls.package_manager(context.config).install(context, packages, apivfs=False) + cls.install_packages(context, packages, apivfs=False) @classmethod def repositories(cls, context: Context) -> Iterable[RpmRepository]: diff --git a/mkosi/distribution/postmarketos.py b/mkosi/distribution/postmarketos.py index 267435dfc..7673e1aaa 100644 --- a/mkosi/distribution/postmarketos.py +++ b/mkosi/distribution/postmarketos.py @@ -71,7 +71,7 @@ class Installer(DistributionInstaller, distribution=Distribution.postmarketos): (context.root / "usr" / dir).mkdir(parents=True, exist_ok=True) (context.root / dir).symlink_to(f"usr/{dir}") - Apk.install(context, ["postmarketos-baselayout", "postmarketos-release"], apivfs=False) + cls.install_packages(context, ["postmarketos-baselayout", "postmarketos-release"], apivfs=False) @classmethod def repositories(cls, context: Context) -> Iterable[ApkRepository]: diff --git a/mkosi/distribution/ubuntu.py b/mkosi/distribution/ubuntu.py index c84e5fd04..2112b4e8f 100644 --- a/mkosi/distribution/ubuntu.py +++ b/mkosi/distribution/ubuntu.py @@ -28,15 +28,17 @@ class Installer(debian.Installer, distribution=Distribution.ubuntu): return Distribution.debian @classmethod - def repositories(cls, context: Context, local: bool = True) -> Iterable[AptRepository]: + def repositories(cls, context: Context, for_image: bool = False) -> Iterable[AptRepository]: types = ("deb", "deb-src") + mirror = None if for_image else context.config.mirror + snapshot = None if for_image else context.config.snapshot components = ( "main", *context.config.repositories, ) - if context.config.local_mirror and local: + if context.config.local_mirror and not for_image: yield AptRepository( types=("deb",), url=context.config.local_mirror, @@ -46,10 +48,12 @@ class Installer(debian.Installer, distribution=Distribution.ubuntu): ) return - if context.config.architecture.is_x86_variant(): - mirror = context.config.mirror or "http://archive.ubuntu.com/ubuntu" + if mirror: + pass + elif context.config.architecture.is_x86_variant(): + mirror = "http://archive.ubuntu.com/ubuntu" else: - mirror = context.config.mirror or "http://ports.ubuntu.com" + mirror = "http://ports.ubuntu.com" signedby = Path("/usr/share/keyrings/ubuntu-archive-keyring.gpg") @@ -59,7 +63,7 @@ class Installer(debian.Installer, distribution=Distribution.ubuntu): suite=context.config.release, components=components, signedby=signedby, - snapshot=context.config.snapshot, + snapshot=snapshot, ) yield AptRepository( @@ -68,7 +72,7 @@ class Installer(debian.Installer, distribution=Distribution.ubuntu): suite=f"{context.config.release}-updates", components=components, signedby=signedby, - snapshot=context.config.snapshot, + snapshot=snapshot, ) # Security updates repos are never mirrored. But !x86 are on the ports server. @@ -83,7 +87,7 @@ class Installer(debian.Installer, distribution=Distribution.ubuntu): suite=f"{context.config.release}-security", components=components, signedby=signedby, - snapshot=context.config.snapshot, + snapshot=snapshot, ) @classmethod