From: Daan De Meyer Date: Sun, 2 Jul 2023 15:34:23 +0000 (+0200) Subject: opensuse: Add back support for zypper X-Git-Tag: v15~99 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=317570e55aa6bdcd0897c414cd8870848ffbb3bc;p=thirdparty%2Fmkosi.git opensuse: Add back support for zypper Let's add back support for zypper to build opensuse images. If both zypper and dnf are installed, let's prefer using zypper. --- diff --git a/action.yaml b/action.yaml index d7038b0c7..f0d97a32b 100644 --- a/action.yaml +++ b/action.yaml @@ -46,7 +46,8 @@ runs: squashfs-tools \ swtpm \ systemd-container \ - xfsprogs + xfsprogs \ + zypper sudo pacman-key --init sudo pacman-key --populate archlinux diff --git a/mkosi/distributions/opensuse.py b/mkosi/distributions/opensuse.py index d28ed0ed2..ae0447ca6 100644 --- a/mkosi/distributions/opensuse.py +++ b/mkosi/distributions/opensuse.py @@ -1,13 +1,16 @@ # SPDX-License-Identifier: LGPL-2.1+ +import shutil +import textwrap import urllib.request import xml.etree.ElementTree as ElementTree from collections.abc import Sequence from mkosi.architecture import Architecture from mkosi.distributions import DistributionInstaller -from mkosi.distributions.fedora import Repo, invoke_dnf, setup_dnf +from mkosi.distributions.fedora import Repo, fixup_rpmdb_location, invoke_dnf, setup_dnf from mkosi.log import die +from mkosi.run import bwrap from mkosi.state import MkosiState @@ -41,16 +44,25 @@ class OpensuseInstaller(DistributionInstaller): release_url = f"{state.config.mirror}/distribution/leap/{release}/repo/oss/" updates_url = f"{state.config.mirror}/update/leap/{release}/oss/" - repos = [Repo("repo-oss", f"baseurl={release_url}", fetch_gpgurls(release_url))] + zypper = shutil.which("zypper") + + repos = [Repo("repo-oss", f"baseurl={release_url}", fetch_gpgurls(release_url) if not zypper else [])] if updates_url is not None: - repos += [Repo("repo-update", f"baseurl={updates_url}", fetch_gpgurls(updates_url))] + repos += [Repo("repo-update", f"baseurl={updates_url}", fetch_gpgurls(updates_url) if not zypper else [])] - setup_dnf(state, repos) - invoke_dnf(state, "install", packages, apivfs=apivfs) + if zypper: + setup_zypper(state, repos) + invoke_zypper(state, "install", packages, apivfs=apivfs) + else: + setup_dnf(state, repos) + invoke_dnf(state, "install", packages, apivfs=apivfs) @classmethod def remove_packages(cls, state: MkosiState, packages: Sequence[str]) -> None: - invoke_dnf(state, "remove", packages) + if shutil.which("zypper"): + invoke_zypper(state, "remove", packages, ["--clean-deps"]) + else: + invoke_dnf(state, "remove", packages) @staticmethod def architecture(arch: Architecture) -> str: @@ -64,6 +76,71 @@ class OpensuseInstaller(DistributionInstaller): return a +def setup_zypper(state: MkosiState, repos: Sequence[Repo]) -> None: + config = state.pkgmngr / "etc/zypp/zypp.conf" + if not config.exists(): + config.parent.mkdir(exist_ok=True, parents=True) + with config.open("w") as f: + f.write( + textwrap.dedent( + f"""\ + [main] + rpm.install.excludedocs = {"no" if state.config.with_docs else "yes"} + solver.onlyRequires = yes + """ + ) + ) + + repofile = state.pkgmngr / f"etc/zypp/repos.d/{state.config.distribution}.repo" + if not repofile.exists(): + repofile.parent.mkdir(exist_ok=True, parents=True) + with repofile.open("w") as f: + for repo in repos: + f.write( + textwrap.dedent( + f"""\ + [{repo.id}] + name={repo.id} + {repo.url} + gpgcheck=1 + enabled={int(repo.enabled)} + autorefresh=0 + keeppackages=1 + """ + ) + ) + + for i, url in enumerate(repo.gpgurls): + f.write("gpgkey=" if i == 0 else len("gpgkey=") * " ") + f.write(f"{url}\n") + + +def invoke_zypper( + state: MkosiState, + verb: str, + packages: Sequence[str], + options: Sequence[str] = (), + apivfs: bool = True, +) -> None: + cmdline = [ + "zypper", + f"--root={state.root}", + f"--cache-dir={state.cache_dir}", + f"--reposd-dir={state.pkgmngr / 'etc/zypp/repos.d'}", + "--gpg-auto-import-keys" if state.config.repository_key_check else "--no-gpg-checks", + "--non-interactive", + verb, + *options, + *packages, + ] + + env = dict(ZYPP_CONF=str(state.pkgmngr / "etc/zypp/zypp.conf"), KERNEL_INSTALL_BYPASS="1") | state.environment + + bwrap(cmdline, apivfs=state.root if apivfs else None, env=env) + + fixup_rpmdb_location(state.root) + + def fetch_gpgurls(repourl: str) -> list[str]: gpgurls = [f"{repourl}/repodata/repomd.xml.key"]