From a0a2305f40d337622e237a12b82a9223e99e9df6 Mon Sep 17 00:00:00 2001 From: Carl George Date: Oct 07 2021 18:28:23 +0000 Subject: Add support for epel9-next This modifies the assert_valid_epel_package function to check the CentOS Stream compose metadata to determine if a package name is valid for EPEL or not. A similar change was made to fedscm-admin. https://pagure.io/fedscm-admin/pull-request/72 Signed-off-by: Carl George --- diff --git a/fedpkg/utils.py b/fedpkg/utils.py index 4671b50..a95ee86 100644 --- a/fedpkg/utils.py +++ b/fedpkg/utils.py @@ -339,43 +339,78 @@ def assert_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 = ('https://infrastructure.fedoraproject.org/repo/json/pkg_el{0}.json' - .format(version)) - error_msg = ('The connection to infrastructure.fedoraproject.org failed ' - 'while trying to determine if this is a valid EPEL package.') - try: - rv = requests.get(url, timeout=60) - except ConnectionError as error: - error_msg += ' The error was: {0}'.format(str(error)) - raise rpkgError(error_msg) - if not rv.ok: - raise rpkgError(error_msg + ' The status code was: {0}'.format( - rv.status_code)) + # 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' + error_msg = ('The connection to composes.stream.centos.org failed while ' + 'trying to determine if this is a valid EPEL package.') + try: + rv = requests.get(url, timeout=60) + except ConnectionError as error: + error_msg += ' The error was: {0}'.format(str(error)) + raise rpkgError(error_msg) + if not rv.ok: + raise rpkgError(error_msg + ' The status code was: {0}'.format( + rv.status_code)) - rv_json = rv.json() - # 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']) - - error_msg_two = ( - 'This package is already an EL package and is built on all supported ' - 'arches, therefore, it cannot be in EPEL. If this is a mistake or you ' - 'have an exception, please contact the Release Engineering team.') - 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): - raise rpkgError(error_msg_two) + rv_json = rv.json() + 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() + } + error_msg_two = ( + 'This package is already an EL package, therefore it cannot be in ' + 'EPEL. If this is a mistake or you have an exception, please ' + 'contact the Release Engineering team.') + if name in pkg_names: + raise rpkgError(error_msg_two) + + else: + url = ('https://infrastructure.fedoraproject.org/repo/json/pkg_el{0}.json' + .format(version)) + error_msg = ('The connection to infrastructure.fedoraproject.org failed ' + 'while trying to determine if this is a valid EPEL package.') + try: + rv = requests.get(url, timeout=60) + except ConnectionError as error: + error_msg += ' The error was: {0}'.format(str(error)) + raise rpkgError(error_msg) + + if not rv.ok: + raise rpkgError(error_msg + ' The status code was: {0}'.format( + rv.status_code)) + + rv_json = rv.json() + # 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']) + + error_msg_two = ( + 'This package is already an EL package and is built on all supported ' + 'arches, therefore, it cannot be in EPEL. If this is a mistake or you ' + 'have an exception, please contact the Release Engineering team.') + 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): + raise rpkgError(error_msg_two) def assert_new_tests_repo(name, dist_git_url):