From 8ba87481bd6c2ca814f167b1d471a76b0f4ed03f Mon Sep 17 00:00:00 2001
From: Carl George <carl@george.computer>
Date: Sep 16 2021 22:10:27 +0000
Subject: Add support for epel9-next


- add branch SLAs
- modify valid_epel_package to check CentOS compose metadata for 9+

---

diff --git a/fedscm_admin/__init__.py b/fedscm_admin/__init__.py
index e8092fd..7eeb517 100644
--- a/fedscm_admin/__init__.py
+++ b/fedscm_admin/__init__.py
@@ -40,6 +40,16 @@ STANDARD_BRANCH_SLAS = {
     'main': {
         'rawhide': '2222-01-01'
     },
+    'epel9': {
+        'stable_api': '2032-05-31',
+        'security_fixes': '2032-05-31',
+        'bug_fixes': '2032-05-31'
+    },
+    'epel9-next': {
+        'stable_api': '2027-05-31',
+        'security_fixes': '2027-05-31',
+        'bug_fixes': '2027-05-31'
+    },
     'epel8': {
         'stable_api': '2029-05-31',
         'security_fixes': '2029-05-31',
diff --git a/fedscm_admin/utils.py b/fedscm_admin/utils.py
index e3e4c08..6d4d8a4 100644
--- a/fedscm_admin/utils.py
+++ b/fedscm_admin/utils.py
@@ -763,27 +763,46 @@ def valid_epel_package(name, branch):
     """
     # Extract any digits in the branch name to determine the EL version
     version = ''.join([i for i in branch if re.match(r'\d', i)])
-    url = f'https://infrastructure.fedoraproject.org/repo/json/pkg_el{version}.json'
-    rv = requests_wrapper(
-        url, timeout=60, service_name='infrastructure.fedoraproject.org')
-    rv_json = get_request_json(rv, 'getting the list of official EL packages')
-    # Remove noarch from this because noarch is treated specially
-    all_arches = set(rv_json['arches']) - set(['noarch'])
-    # On EL6, also remove ppc and i386 as many packages will
-    # have these arches missing and cause false positives
-    if int(version) == 6:
-        all_arches = all_arches - set(['ppc', 'i386'])
-    # On EL7 and later, also remove ppc and i686 as many packages will
-    # have these arches missing and cause false positives
-    elif int(version) >= 7:
-        all_arches = all_arches - set(['ppc', 'i686'])
-    for pkg_name, pkg_info in rv_json['packages'].items():
-        # If the EL package is noarch only or is available on all supported
-        # arches, then don't allow an EPEL branch
-        if pkg_name == name:
-            pkg_arches = set(pkg_info['arch'])
-            if pkg_arches == set(['noarch']) or not (all_arches - pkg_arches):
-                return False
+
+    # Starting with epel9 and epel9-next, check against CentOS compose metadata.
+    if int(version) >= 9:
+        # Currently we only have a latest symlink.  In the future we'll need
+        # separate latest symlinks that include the major version.
+        # https://bugzilla.redhat.com/show_bug.cgi?id=2005139
+        url = 'https://composes.stream.centos.org/production/latest-CentOS-Stream/compose/metadata/rpms.json'
+        rv = requests_wrapper(url, timeout=60, service_name='composes.stream.centos.org')
+        rv_json = get_request_json(rv, 'getting the list of official EL packages')
+        pkg_names = {
+            # convert name-epoch:version-release.arch key to just the name
+            nevra.rsplit('.', maxsplit=1)[0].rsplit('-', maxsplit=2)[0]
+            # only packages from these repos are forbidden in epel
+            for repo in ['BaseOS', 'AppStream', 'CRB']
+            for arch in rv_json['payload']['rpms'][repo].keys()
+            for nevra in rv_json['payload']['rpms'][repo][arch].keys()
+        }
+        if name in pkg_names:
+            return False
+    else:
+        url = f'https://infrastructure.fedoraproject.org/repo/json/pkg_el{version}.json'
+        rv = requests_wrapper(url, timeout=60, service_name='infrastructure.fedoraproject.org')
+        rv_json = get_request_json(rv, 'getting the list of official EL packages')
+        # Remove noarch from this because noarch is treated specially
+        all_arches = set(rv_json['arches']) - set(['noarch'])
+        # On EL6, also remove ppc and i386 as many packages will
+        # have these arches missing and cause false positives
+        if int(version) == 6:
+            all_arches = all_arches - set(['ppc', 'i386'])
+        # On EL7 and later, also remove ppc and i686 as many packages will
+        # have these arches missing and cause false positives
+        elif int(version) >= 7:
+            all_arches = all_arches - set(['ppc', 'i686'])
+        for pkg_name, pkg_info in rv_json['packages'].items():
+            # If the EL package is noarch only or is available on all supported
+            # arches, then don't allow an EPEL branch
+            if pkg_name == name:
+                pkg_arches = set(pkg_info['arch'])
+                if pkg_arches == set(['noarch']) or not (all_arches - pkg_arches):
+                    return False
     return True
 
 

