From: Daan De Meyer Date: Sat, 16 Dec 2023 21:58:21 +0000 (+0100) Subject: Split out rpm.py and hook up rpm logic with zypper as well X-Git-Tag: v20~55^2~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dfb0b5759ca8cc892b0c0fd3b328e4756d8889e1;p=thirdparty%2Fmkosi.git Split out rpm.py and hook up rpm logic with zypper as well We have a bunch of rpm related logic that's required when using dnf and zypper so let's split out rpm.py and hook up everything in both dnf and zypper. --- diff --git a/mkosi/distributions/alma.py b/mkosi/distributions/alma.py index 8d5c75139..f35bdd7ae 100644 --- a/mkosi/distributions/alma.py +++ b/mkosi/distributions/alma.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: LGPL-2.1+ from mkosi.distributions import centos, join_mirror -from mkosi.installer.dnf import RpmRepository, find_rpm_gpgkey +from mkosi.installer.rpm import RpmRepository, find_rpm_gpgkey from mkosi.state import MkosiState diff --git a/mkosi/distributions/centos.py b/mkosi/distributions/centos.py index 1a23a118f..5a168b3f5 100644 --- a/mkosi/distributions/centos.py +++ b/mkosi/distributions/centos.py @@ -12,7 +12,8 @@ from mkosi.distributions import ( PackageType, join_mirror, ) -from mkosi.installer.dnf import RpmRepository, find_rpm_gpgkey, invoke_dnf, setup_dnf +from mkosi.installer.dnf import invoke_dnf, setup_dnf +from mkosi.installer.rpm import RpmRepository, find_rpm_gpgkey from mkosi.log import complete_step, die from mkosi.state import MkosiState from mkosi.tree import rmtree diff --git a/mkosi/distributions/fedora.py b/mkosi/distributions/fedora.py index 3ea860c54..7e7502aad 100644 --- a/mkosi/distributions/fedora.py +++ b/mkosi/distributions/fedora.py @@ -9,7 +9,8 @@ from mkosi.distributions import ( PackageType, join_mirror, ) -from mkosi.installer.dnf import RpmRepository, find_rpm_gpgkey, invoke_dnf, setup_dnf +from mkosi.installer.dnf import invoke_dnf, setup_dnf +from mkosi.installer.rpm import RpmRepository, find_rpm_gpgkey from mkosi.log import die from mkosi.state import MkosiState diff --git a/mkosi/distributions/mageia.py b/mkosi/distributions/mageia.py index c2a0c895e..39b5ac623 100644 --- a/mkosi/distributions/mageia.py +++ b/mkosi/distributions/mageia.py @@ -10,7 +10,8 @@ from mkosi.distributions import ( PackageType, join_mirror, ) -from mkosi.installer.dnf import RpmRepository, find_rpm_gpgkey, invoke_dnf, setup_dnf +from mkosi.installer.dnf import invoke_dnf, setup_dnf +from mkosi.installer.rpm import RpmRepository, find_rpm_gpgkey from mkosi.log import die from mkosi.state import MkosiState diff --git a/mkosi/distributions/openmandriva.py b/mkosi/distributions/openmandriva.py index a1ec839f2..d47db247e 100644 --- a/mkosi/distributions/openmandriva.py +++ b/mkosi/distributions/openmandriva.py @@ -10,7 +10,8 @@ from mkosi.distributions import ( PackageType, join_mirror, ) -from mkosi.installer.dnf import RpmRepository, find_rpm_gpgkey, invoke_dnf, setup_dnf +from mkosi.installer.dnf import invoke_dnf, setup_dnf +from mkosi.installer.rpm import RpmRepository, find_rpm_gpgkey from mkosi.log import die from mkosi.state import MkosiState diff --git a/mkosi/distributions/opensuse.py b/mkosi/distributions/opensuse.py index 8bc84ce2b..cad67dc34 100644 --- a/mkosi/distributions/opensuse.py +++ b/mkosi/distributions/opensuse.py @@ -7,7 +7,8 @@ from collections.abc import Sequence from mkosi.config import Architecture from mkosi.distributions import Distribution, DistributionInstaller, PackageType -from mkosi.installer.dnf import RpmRepository, invoke_dnf, setup_dnf +from mkosi.installer.dnf import invoke_dnf, setup_dnf +from mkosi.installer.rpm import RpmRepository from mkosi.installer.zypper import invoke_zypper, setup_zypper from mkosi.log import die from mkosi.state import MkosiState diff --git a/mkosi/distributions/rhel.py b/mkosi/distributions/rhel.py index 5964af4ca..290a9ac6b 100644 --- a/mkosi/distributions/rhel.py +++ b/mkosi/distributions/rhel.py @@ -5,7 +5,7 @@ from pathlib import Path from typing import Any, Optional from mkosi.distributions import centos, join_mirror -from mkosi.installer.dnf import RpmRepository, find_rpm_gpgkey +from mkosi.installer.rpm import RpmRepository, find_rpm_gpgkey from mkosi.log import die from mkosi.state import MkosiState diff --git a/mkosi/distributions/rhel_ubi.py b/mkosi/distributions/rhel_ubi.py index 54d1ba394..f789cf006 100644 --- a/mkosi/distributions/rhel_ubi.py +++ b/mkosi/distributions/rhel_ubi.py @@ -3,7 +3,7 @@ from collections.abc import Iterable from mkosi.distributions import centos, join_mirror -from mkosi.installer.dnf import RpmRepository, find_rpm_gpgkey +from mkosi.installer.rpm import RpmRepository, find_rpm_gpgkey from mkosi.state import MkosiState diff --git a/mkosi/distributions/rocky.py b/mkosi/distributions/rocky.py index bb8252e71..f35607e33 100644 --- a/mkosi/distributions/rocky.py +++ b/mkosi/distributions/rocky.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: LGPL-2.1+ from mkosi.distributions import centos, join_mirror -from mkosi.installer.dnf import RpmRepository, find_rpm_gpgkey +from mkosi.installer.rpm import RpmRepository, find_rpm_gpgkey from mkosi.state import MkosiState diff --git a/mkosi/installer/__init__.py b/mkosi/installer/__init__.py index afaced1b5..e77f0425e 100644 --- a/mkosi/installer/__init__.py +++ b/mkosi/installer/__init__.py @@ -4,8 +4,9 @@ import os from mkosi.config import ConfigFeature from mkosi.installer.apt import apt_cmd -from mkosi.installer.dnf import dnf_cmd, rpm_cmd +from mkosi.installer.dnf import dnf_cmd from mkosi.installer.pacman import pacman_cmd +from mkosi.installer.rpm import rpm_cmd from mkosi.installer.zypper import zypper_cmd from mkosi.run import apivfs_cmd from mkosi.state import MkosiState diff --git a/mkosi/installer/dnf.py b/mkosi/installer/dnf.py index 69abc6a6c..72b3ecc5f 100644 --- a/mkosi/installer/dnf.py +++ b/mkosi/installer/dnf.py @@ -1,39 +1,15 @@ # SPDX-License-Identifier: LGPL-2.1+ -import os import shutil -import subprocess import textwrap from collections.abc import Iterable -from pathlib import Path -from typing import NamedTuple, Optional -from mkosi.run import apivfs_cmd, bwrap, run +from mkosi.installer.rpm import RpmRepository, fixup_rpmdb_location, setup_rpm +from mkosi.run import apivfs_cmd, bwrap from mkosi.state import MkosiState -from mkosi.tree import copy_tree, rmtree from mkosi.types import PathString from mkosi.util import sort_packages -class RpmRepository(NamedTuple): - id: str - url: str - gpgurls: tuple[str, ...] - enabled: bool = True - sslcacert: Optional[Path] = None - sslclientkey: Optional[Path] = None - sslclientcert: Optional[Path] = None - - -def find_rpm_gpgkey(state: MkosiState, key: str, url: str) -> str: - for gpgdir in ("usr/share/distribution-gpg-keys", "etc/pki/rpm-gpg"): - for root in (state.pkgmngr, state.root, Path("/")): - gpgpath = next((root / Path(gpgdir)).rglob(key), None) - if gpgpath: - return f"file://{gpgpath}" - - return url - - def dnf_executable(state: MkosiState) -> str: # Allow the user to override autodetection with an environment variable dnf = state.config.environment.get("MKOSI_DNF") @@ -86,13 +62,7 @@ def setup_dnf(state: MkosiState, repositories: Iterable[RpmRepository], filelist f.write("\n") - macros = state.pkgmngr / "usr/lib/rpm/macros.d" - macros.mkdir(parents=True, exist_ok=True) - if not (macros / "macros.lang").exists() and state.config.locale: - (macros / "macros.lang").write_text(f"%_install_langs {state.config.locale}") - - rpmconfigdir = Path(run(["rpm", "--eval", "%{_rpmconfigdir}"], stdout=subprocess.PIPE).stdout.strip()) - copy_tree(rpmconfigdir, state.pkgmngr / "usr/lib/rpm", clobber=False, use_subvolumes=state.config.use_subvolumes) + setup_rpm(state) def dnf_cmd(state: MkosiState) -> list[PathString]: @@ -151,24 +121,3 @@ def invoke_dnf(state: MkosiState, command: str, packages: Iterable[str], apivfs: for p in (state.root / "var/log").iterdir(): if any(p.name.startswith(prefix) for prefix in ("dnf", "hawkey", "yum")): p.unlink() - - -def fixup_rpmdb_location(root: Path) -> None: - # On Debian, rpm/dnf ship with a patch to store the rpmdb under ~/ so it needs to be copied back in the - # right location, otherwise the rpmdb will be broken. See: https://bugs.debian.org/1004863. We also - # replace it with a symlink so that any further rpm operations immediately use the correct location. - rpmdb_home = root / "root/.rpmdb" - if not rpmdb_home.exists() or rpmdb_home.is_symlink(): - return - - # Take into account the new location in F36 - rpmdb = root / "usr/lib/sysimage/rpm" - if not rpmdb.exists(): - rpmdb = root / "var/lib/rpm" - rmtree(rpmdb) - shutil.move(rpmdb_home, rpmdb) - rpmdb_home.symlink_to(os.path.relpath(rpmdb, start=rpmdb_home.parent)) - - -def rpm_cmd(state: MkosiState) -> list[PathString]: - return ["env", "HOME=/", f"RPM_CONFIGDIR={state.pkgmngr / 'usr/lib/rpm'}", "rpm", "--root", state.root] diff --git a/mkosi/installer/rpm.py b/mkosi/installer/rpm.py new file mode 100644 index 000000000..abdc3b823 --- /dev/null +++ b/mkosi/installer/rpm.py @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: LGPL-2.1+ + +import os +import shutil +import subprocess +from pathlib import Path +from typing import NamedTuple, Optional + +from mkosi.run import run +from mkosi.state import MkosiState +from mkosi.tree import copy_tree, rmtree +from mkosi.types import PathString + + +class RpmRepository(NamedTuple): + id: str + url: str + gpgurls: tuple[str, ...] + enabled: bool = True + sslcacert: Optional[Path] = None + sslclientkey: Optional[Path] = None + sslclientcert: Optional[Path] = None + + +def find_rpm_gpgkey(state: MkosiState, key: str, url: str) -> str: + for gpgdir in ("usr/share/distribution-gpg-keys", "etc/pki/rpm-gpg"): + for root in (state.pkgmngr, state.root, Path("/")): + gpgpath = next((root / Path(gpgdir)).rglob(key), None) + if gpgpath: + return f"file://{gpgpath}" + + return url + + +def setup_rpm(state: MkosiState) -> None: + macros = state.pkgmngr / "usr/lib/rpm/macros.d" + macros.mkdir(parents=True, exist_ok=True) + if not (macros / "macros.lang").exists() and state.config.locale: + (macros / "macros.lang").write_text(f"%_install_langs {state.config.locale}") + + rpmconfigdir = Path(run(["rpm", "--eval", "%{_rpmconfigdir}"], stdout=subprocess.PIPE).stdout.strip()) + copy_tree(rpmconfigdir, state.pkgmngr / "usr/lib/rpm", clobber=False, use_subvolumes=state.config.use_subvolumes) + + +def fixup_rpmdb_location(root: Path) -> None: + # On Debian, rpm/dnf ship with a patch to store the rpmdb under ~/ so it needs to be copied back in the + # right location, otherwise the rpmdb will be broken. See: https://bugs.debian.org/1004863. We also + # replace it with a symlink so that any further rpm operations immediately use the correct location. + rpmdb_home = root / "root/.rpmdb" + if not rpmdb_home.exists() or rpmdb_home.is_symlink(): + return + + # Take into account the new location in F36 + rpmdb = root / "usr/lib/sysimage/rpm" + if not rpmdb.exists(): + rpmdb = root / "var/lib/rpm" + rmtree(rpmdb) + shutil.move(rpmdb_home, rpmdb) + rpmdb_home.symlink_to(os.path.relpath(rpmdb, start=rpmdb_home.parent)) + + +def rpm_cmd(state: MkosiState) -> list[PathString]: + return ["env", "HOME=/", f"RPM_CONFIGDIR={state.pkgmngr / 'usr/lib/rpm'}", "rpm", "--root", state.root] diff --git a/mkosi/installer/zypper.py b/mkosi/installer/zypper.py index 6197aab93..0c95fd5fa 100644 --- a/mkosi/installer/zypper.py +++ b/mkosi/installer/zypper.py @@ -3,7 +3,7 @@ import textwrap from collections.abc import Sequence from mkosi.config import yes_no -from mkosi.installer.dnf import RpmRepository, fixup_rpmdb_location +from mkosi.installer.rpm import RpmRepository, fixup_rpmdb_location, setup_rpm from mkosi.run import apivfs_cmd, bwrap from mkosi.state import MkosiState from mkosi.types import PathString @@ -51,11 +51,14 @@ def setup_zypper(state: MkosiState, repos: Sequence[RpmRepository]) -> None: f.write("gpgkey=" if i == 0 else len("gpgkey=") * " ") f.write(f"{url}\n") + setup_rpm(state) + def zypper_cmd(state: MkosiState) -> list[PathString]: return [ "env", f"ZYPP_CONF={state.pkgmngr / 'etc/zypp/zypp.conf'}", + f"RPM_CONFIGDIR={state.pkgmngr / 'usr/lib/rpm'}", "zypper", f"--root={state.root}", f"--cache-dir={state.cache_dir / 'zypp'}",