Repository: systemd/mkosi

Issue:
RFE: Add Alma Linux Support 
Hot off the heels of adding Rocky Linux (#811), it should be straight forward to add support for Alma Linux.

I am happy to work on this one also


https://almalinux.org/




Discussion:
Sure, I see no problem, at least for now both have a claim to CentOS old niche.

Resolving patch:
diff --git a/mkosi/__init__.py b/mkosi/__init__.py
--- a/mkosi/__init__.py
+++ b/mkosi/__init__.py
@@ -1375,6 +1375,8 @@ def mount_cache(args: CommandLineArguments, root: Path) -> Generator[None, None,
             Distribution.centos_epel,
             Distribution.rocky,
             Distribution.rocky_epel,
+            Distribution.alma,
+            Distribution.alma_epel,
         ):
             # We mount both the YUM and the DNF cache in this case, as
             # YUM might just be redirected to DNF even if we invoke
@@ -2264,6 +2266,51 @@ def install_rocky_repos(args: CommandLineArguments, root: Path, epel_release: in
     return ["AppStream", "BaseOS", "extras", "plus"]
 
 
+def install_alma_repos(args: CommandLineArguments, root: Path, epel_release: int) -> List[str]:
+    # Repos for Alma Linux 8 and later
+    gpgpath = Path("/etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux")
+    gpgurl = "https://repo.almalinux.org/almalinux/RPM-GPG-KEY-AlmaLinux"
+    epel_gpgpath = Path(f"/etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-{epel_release}")
+    epel_gpgurl = f"https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-{epel_release}"
+
+    if args.mirror:
+        appstream_url = f"baseurl={args.mirror}/almalinux/{args.release}/AppStream/x86_64/os"
+        baseos_url = f"baseurl={args.mirror}/almalinux/{args.release}/BaseOS/x86_64/os"
+        extras_url = f"baseurl={args.mirror}/almalinux/{args.release}/extras/x86_64/os"
+        powertools_url = f"baseurl={args.mirror}/almalinux/{args.release}/PowerTools/x86_64/os"
+        ha_url = f"baseurl={args.mirror}/almalinux/{args.release}/HighAvailability/x86_64/os"
+        epel_url = f"baseurl={args.mirror}/epel/{epel_release}/Everything/x86_64"
+    else:
+        appstream_url = (
+            f"mirrorlist=https://mirrors.almalinux.org/mirrorlist/{args.release}/appstream"
+        )
+        baseos_url = f"mirrorlist=https://mirrors.almalinux.org/mirrorlist/{args.release}/baseos"
+        extras_url = f"mirrorlist=https://mirrors.almalinux.org/mirrorlist/{args.release}/extras"
+        powertools_url = f"mirrorlist=https://mirrors.almalinux.org/mirrorlist/{args.release}/powertools"
+        ha_url = f"mirrorlist=https://mirrors.almalinux.org/mirrorlist/{args.release}/ha"
+        epel_url = f"mirrorlist=https://mirrors.fedoraproject.org/mirrorlist?repo=epel-{epel_release}&arch=x86_64"
+
+    setup_dnf(
+        args,
+        root,
+        repos=[
+            Repo("AppStream", f"AlmaLinux-{args.release} - AppStream", appstream_url, gpgpath, gpgurl),
+            Repo("BaseOS", f"AlmaLinux-{args.release} - Base", baseos_url, gpgpath, gpgurl),
+            Repo("extras", f"AlmaLinux-{args.release} - Extras", extras_url, gpgpath, gpgurl),
+            Repo("Powertools", f"AlmaLinux-{args.release} - Powertools", powertools_url, gpgpath, gpgurl),
+            Repo("HighAvailability", f"AlmaLinux-{args.release} - HighAvailability", ha_url, gpgpath, gpgurl),
+            Repo(
+                "epel",
+                f"name=Extra Packages for Enterprise Linux {epel_release} - $basearch",
+                epel_url,
+                epel_gpgpath,
+                epel_gpgurl,
+            ),
+        ],
+    )
+
+    return ["AppStream", "BaseOS", "extras", "Powertools", "HighAvailability"]
+
 def install_centos_new(args: CommandLineArguments, root: Path, epel_release: int) -> List[str]:
     # Repos for CentOS 8 and later
 
@@ -2396,6 +2443,36 @@ def install_rocky(args: CommandLineArguments, root: Path, do_run_build_script: b
 
 
 
+@complete_step("Installing Alma Linux…")
+def install_alma(args: CommandLineArguments, root: Path, do_run_build_script: bool) -> None:
+    epel_release = int(args.release.split(".")[0])
+    default_repos = install_alma_repos(args, root, epel_release)
+
+    packages = {*args.packages}
+    add_packages(args, packages, "almalinux-release", "systemd")
+    if not do_run_build_script and args.bootable:
+        add_packages(args, packages, "kernel", "dracut", "binutils")
+        configure_dracut(args, root)
+        add_packages(args, packages, "systemd-udev", conditional="systemd")
+
+    if do_run_build_script:
+        packages.update(args.build_packages)
+
+    repos = args.repositories or default_repos
+
+    if args.distribution == Distribution.alma_epel:
+        repos += ["epel"]
+        add_packages(args, packages, "epel-release")
+
+    if do_run_build_script:
+        packages.update(args.build_packages)
+
+    if not do_run_build_script and args.distribution == Distribution.alma_epel and args.network_veth:
+        add_packages(args, packages, "systemd-networkd", conditional="systemd")
+
+    invoke_dnf_or_yum(args, root, repos, packages, do_run_build_script)
+
+
 def debootstrap_knows_arg(arg: str) -> bool:
     return bytes("invalid option", "UTF-8") not in run(["debootstrap", arg], stdout=PIPE, check=False).stdout
 
@@ -2833,6 +2910,8 @@ def install_distribution(args: CommandLineArguments, root: Path, do_run_build_sc
         Distribution.openmandriva: install_openmandriva,
         Distribution.rocky: install_rocky,
         Distribution.rocky_epel: install_rocky,
+        Distribution.alma: install_alma,
+        Distribution.alma_epel: install_alma,
     }
 
     disable_kernel_install(args, root)
@@ -5722,6 +5801,8 @@ def load_args(args: argparse.Namespace) -> CommandLineArguments:
             args.release = "8"
         elif args.distribution in (Distribution.rocky, Distribution.rocky_epel):
             args.release = "8"
+        elif args.distribution in (Distribution.alma, Distribution.alma_epel):
+            args.release = "8"
         elif args.distribution == Distribution.mageia:
             args.release = "7"
         elif args.distribution == Distribution.debian:
@@ -5776,6 +5857,11 @@ def load_args(args: argparse.Namespace) -> CommandLineArguments:
         if epel_release == 8 and args.output_format == OutputFormat.gpt_btrfs:
             die(f"Sorry, Rocky {epel_release} does not support btrfs")
 
+    if args.distribution in (Distribution.alma, Distribution.alma_epel):
+        epel_release = int(args.release.split(".")[0])
+        if epel_release == 8 and args.output_format == OutputFormat.gpt_btrfs:
+            die(f"Sorry, Alma {epel_release} does not support btrfs")
+
     # Remove once https://github.com/clearlinux/clr-boot-manager/pull/238 is merged and available.
     if args.distribution == Distribution.clear and args.output_format == OutputFormat.gpt_btrfs:
         die("Sorry, Clear Linux does not support btrfs")
@@ -5803,6 +5889,8 @@ def load_args(args: argparse.Namespace) -> CommandLineArguments:
             args.mirror = "http://download.opensuse.org"
         elif args.distribution in (Distribution.rocky, Distribution.rocky_epel):
             args.mirror = None
+        elif args.distribution in (Distribution.alma, Distribution.alma_epel):
+            args.mirror = None
 
     if args.minimize and not args.output_format.can_minimize():
         die("Minimal file systems only supported for ext4 and btrfs.")
@@ -6210,6 +6298,8 @@ def print_summary(args: CommandLineArguments) -> None:
         Distribution.mageia,
         Distribution.rocky,
         Distribution.rocky_epel,
+        Distribution.alma,
+        Distribution.alma_epel,
     ):
         MkosiPrinter.info("        With Documentation: " + yes_no(args.with_docs))
 
diff --git a/mkosi/backend.py b/mkosi/backend.py
--- a/mkosi/backend.py
+++ b/mkosi/backend.py
@@ -103,6 +103,8 @@ class Distribution(enum.Enum):
     openmandriva = 10, PackageType.rpm
     rocky = 11, PackageType.rpm
     rocky_epel = 12, PackageType.rpm
+    alma = 13, PackageType.rpm
+    alma_epel = 14, PackageType.rpm
 
     def __new__(cls, number: int, package_type: PackageType) -> Distribution:
         # This turns the list above into enum entries with .package_type attributes.


Test patch: