From a10130f8d5bbd03319e62adb2ba033ef647dbc3e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 20 Sep 2023 16:08:27 +0200 Subject: [PATCH] Add support for RHEL UBI The repository naming matches what is visible in the standard ubi container image (registry.access.redhat.com/ubi8/ubi). This is the first time that I'm doing anything more complicated wit UBIs, but I hope this is a sensible beginning. --- mkosi/config.py | 2 ++ mkosi/distributions/__init__.py | 2 ++ mkosi/distributions/centos.py | 12 ++++---- mkosi/distributions/rhel_ubi.py | 54 +++++++++++++++++++++++++++++++++ mkosi/resources/mkosi.md | 17 ++++++----- tests/test_config.py | 2 +- 6 files changed, 74 insertions(+), 15 deletions(-) create mode 100644 mkosi/distributions/rhel_ubi.py diff --git a/mkosi/config.py b/mkosi/config.py index d4e4c89da..0405d81ae 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -325,6 +325,8 @@ def config_default_mirror(namespace: argparse.Namespace) -> Optional[str]: return "https://odcs.fedoraproject.org/composes/production/latest-Fedora-ELN/compose" elif namespace.distribution == Distribution.gentoo: return "https://distfiles.gentoo.org" + elif namespace.distribution == Distribution.rhel_ubi: + return "https://cdn-ubi.redhat.com/content/public/ubi/dist/" return None diff --git a/mkosi/distributions/__init__.py b/mkosi/distributions/__init__.py index 71a9ae570..66842f02d 100644 --- a/mkosi/distributions/__init__.py +++ b/mkosi/distributions/__init__.py @@ -75,6 +75,7 @@ class Distribution(StrEnum): opensuse = enum.auto() mageia = enum.auto() centos = enum.auto() + rhel_ubi = enum.auto() openmandriva = enum.auto() rocky = enum.auto() alma = enum.auto() @@ -88,6 +89,7 @@ class Distribution(StrEnum): Distribution.fedora, Distribution.mageia, Distribution.centos, + Distribution.rhel_ubi, Distribution.openmandriva, Distribution.rocky, Distribution.alma, diff --git a/mkosi/distributions/centos.py b/mkosi/distributions/centos.py index 8f7669b9b..fcf9c4945 100644 --- a/mkosi/distributions/centos.py +++ b/mkosi/distributions/centos.py @@ -93,7 +93,7 @@ class Installer(DistributionInstaller): release = int(state.config.release) if release <= 7: - die("CentOS 7 or earlier variants are not supported") + die(f"{cls.pretty_name()} 7 or earlier variants are not supported") setup_dnf(state, cls.repositories(state.config, release)) (state.pkgmngr / "etc/dnf/vars/stream").write_text(f"{state.config.release}-stream\n") @@ -103,8 +103,8 @@ class Installer(DistributionInstaller): # Make sure glibc-minimal-langpack is installed instead of glibc-all-langpacks. cls.install_packages(state, ["filesystem", "glibc-minimal-langpack"], apivfs=False) - # On Fedora, the default rpmdb has moved to /usr/lib/sysimage/rpm so if that's the case we need to - # move it back to /var/lib/rpm on CentOS. + # On Fedora, the default rpmdb has moved to /usr/lib/sysimage/rpm so if that's the case we + # need to move it back to /var/lib/rpm on CentOS. move_rpm_db(state.root) @classmethod @@ -115,8 +115,8 @@ class Installer(DistributionInstaller): def remove_packages(cls, state: MkosiState, packages: Sequence[str]) -> None: invoke_dnf(state, "remove", packages) - @staticmethod - def architecture(arch: Architecture) -> str: + @classmethod + def architecture(cls, arch: Architecture) -> str: a = { Architecture.x86_64 : "x86_64", Architecture.ppc64_le : "ppc64le", @@ -125,7 +125,7 @@ class Installer(DistributionInstaller): }.get(arch) if not a: - die(f"Architecture {a} is not supported by CentOS") + die(f"Architecture {a} is not supported by {cls.pretty_name()}") return a diff --git a/mkosi/distributions/rhel_ubi.py b/mkosi/distributions/rhel_ubi.py new file mode 100644 index 000000000..32c84dbcd --- /dev/null +++ b/mkosi/distributions/rhel_ubi.py @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: LGPL-2.1+ + +from typing import Iterable + +from mkosi.config import MkosiConfig +from mkosi.distributions import centos +from mkosi.installer.dnf import Repo + + +class Installer(centos.Installer): + @classmethod + def pretty_name(cls) -> str: + return "RHEL UBI" + + @staticmethod + def gpgurls() -> tuple[str, ...]: + return ("https://access.redhat.com/security/data/fd431d51.txt",) + + @classmethod + def repository_variants(cls, config: MkosiConfig, repo: str) -> Iterable[Repo]: + if config.local_mirror: + yield Repo(repo, f"baseurl={config.local_mirror}", cls.gpgurls()) + else: + v = config.release + yield Repo( + f"ubi-{v}-{repo}-rpms", + f"baseurl={centos.join_mirror(config, f'ubi{v}/{v}/$basearch/{repo}/os')}", + cls.gpgurls(), + ) + yield Repo( + f"ubi-{v}-{repo}-debug-rpms", + f"baseurl={centos.join_mirror(config, f'ubi{v}/{v}/$basearch/{repo}/debug')}", + cls.gpgurls(), + enabled=False, + ) + yield Repo( + f"ubi-{v}-{repo}-source", + f"baseurl={centos.join_mirror(config, f'ubi{v}/{v}/$basearch/{repo}/source')}", + cls.gpgurls(), + enabled=False, + ) + if repo == "codeready-builder": + yield Repo( + f"ubi-{v}-{repo}", + f"baseurl={centos.join_mirror(config, f'ubi{v}/{v}/$basearch/{repo}/os')}", + cls.gpgurls(), + enabled=False, + ) + + @classmethod + def repositories(cls, config: MkosiConfig, release: int) -> Iterable[Repo]: + yield from cls.repository_variants(config, "baseos") + yield from cls.repository_variants(config, "appstream") + yield from cls.repository_variants(config, "codeready-builder") diff --git a/mkosi/resources/mkosi.md b/mkosi/resources/mkosi.md index f61e00c92..db0b28e89 100644 --- a/mkosi/resources/mkosi.md +++ b/mkosi/resources/mkosi.md @@ -382,7 +382,7 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`, : The distribution to install in the image. Takes one of the following arguments: `fedora`, `debian`, `ubuntu`, `arch`, `opensuse`, `mageia`, - `centos`, `openmandriva`, `rocky`, `alma`. If not + `centos`, `rhel-ubi`, `openmandriva`, `rocky`, `alma`. If not specified, defaults to the distribution of the host. `Release=`, `--release=`, `-r` @@ -1204,6 +1204,8 @@ distributions: * *CentOS* +* *RHEL UBI* + * *OpenMandriva* * *Rocky Linux* @@ -1216,13 +1218,12 @@ distributions: In theory, any distribution may be used on the host for building images containing any other distribution, as long as the necessary tools are -available. Specifically, any distribution that packages `apt` may be -used to build *Debian* or *Ubuntu* images. Any distribution that -packages `dnf` may be used to build *CentOS*, *Alma Linux*, *Rocky -Linux*, *Fedora Linux*, *OpenSUSE*, *Mageia* or *OpenMandriva* images. -Any distro that packages `pacman` may be used to build *Arch Linux* -images. Any distribution that packages `zypper` may be used to build -*openSUSE* images. +available. +Specifically, +any distribution that packages `apt` may be used to build *Debian* or *Ubuntu* images. +Any distribution that packages `dnf` may be used to build images for any of the rpm-based distributions. +Any distro that packages `pacman` may be used to build *Arch Linux* images. +Any distribution that packages `zypper` may be used to build *openSUSE* images. Currently, *Fedora Linux* packages all relevant tools as of Fedora 28. diff --git a/tests/test_config.py b/tests/test_config.py index 6678aa309..d2ce5de6f 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -194,7 +194,7 @@ def test_parse_load_verb(tmp_path: Path) -> None: def test_os_distribution(tmp_path: Path) -> None: with chdir(tmp_path): for dist in Distribution: - _, [config] = parse_config(["-d", dist.name]) + _, [config] = parse_config(["-d", dist.value]) assert config.distribution == dist with pytest.raises(tuple((argparse.ArgumentError, SystemExit))): -- 2.47.3