diff -Naur faf-git-2884.9521ad3.orig/config/faf.conf.in faf-git-2884.9521ad3.almalinux/config/faf.conf.in --- faf-git-2884.9521ad3.orig/config/faf.conf.in 2021-01-27 00:52:48.000000000 +0300 +++ faf-git-2884.9521ad3.almalinux/config/faf.conf.in 2021-02-09 19:19:57.612625137 +0300 @@ -32,9 +32,9 @@ Directory = @localstatedir@/spool/faf CreateComponents = False # attachments accepted by this server -# allowed values: fedora-bugzilla rhel-bugzilla centos-mantisb comment email url +# allowed values: fedora-bugzilla rhel-bugzilla centos-mantisb almalinux-mantisb comment email url # or * to allow all attachments -AcceptAttachments = fedora-bugzilla rhel-bugzilla centos-mantisbt +AcceptAttachments = fedora-bugzilla rhel-bugzilla centos-mantisbt almalinux-mantisb # Allow uReports without affected package - meaning that crashing code was # not packaged diff -Naur faf-git-2884.9521ad3.orig/config/plugins/almalinux.conf faf-git-2884.9521ad3.almalinux/config/plugins/almalinux.conf --- faf-git-2884.9521ad3.orig/config/plugins/almalinux.conf 1970-01-01 03:00:00.000000000 +0300 +++ faf-git-2884.9521ad3.almalinux/config/plugins/almalinux.conf 2021-02-09 19:13:08.081175514 +0300 @@ -0,0 +1,8 @@ +[AlmaLinux] +repo-urls=https://repo.almalinux.org/almalinux/$releasever/AppStream/Source/ + https://repo.almalinux.org/almalinux/$releasever/BaseOS/Source/ + https://repo.almalinux.org/almalinux/$releasever/PowerTools/Source/ + https://repo.almalinux.org/almalinux/$releasever/HighAvailability/Source/ + +inactive-releases= +active-releases=8 diff -Naur faf-git-2884.9521ad3.orig/config/plugins/almalinuxmantisbt.conf faf-git-2884.9521ad3.almalinux/config/plugins/almalinuxmantisbt.conf --- faf-git-2884.9521ad3.orig/config/plugins/almalinuxmantisbt.conf 1970-01-01 03:00:00.000000000 +0300 +++ faf-git-2884.9521ad3.almalinux/config/plugins/almalinuxmantisbt.conf 2021-02-09 19:13:57.932844040 +0300 @@ -0,0 +1,6 @@ +[almalinux-mantisbt] +api_url=https://bugs.almalinux.org/api/soap/mantisconnect.php?wsdl +web_url=https://bugs.almalinux.org/view.php?id= +user= +password= +abbr=ALMALINUX diff -Naur faf-git-2884.9521ad3.orig/config/plugins/Makefile.am faf-git-2884.9521ad3.almalinux/config/plugins/Makefile.am --- faf-git-2884.9521ad3.orig/config/plugins/Makefile.am 2021-01-27 00:52:48.000000000 +0300 +++ faf-git-2884.9521ad3.almalinux/config/plugins/Makefile.am 2021-02-09 19:36:15.210749908 +0300 @@ -1,4 +1,6 @@ pluginconf_DATA = \ + almalinux.conf \ + almalinuxmantisbt.conf \ centos.conf \ clonebz.conf \ centosmantisbt.conf \ diff -Naur faf-git-2884.9521ad3.orig/src/pyfaf/actions/Makefile.am faf-git-2884.9521ad3.almalinux/src/pyfaf/actions/Makefile.am --- faf-git-2884.9521ad3.orig/src/pyfaf/actions/Makefile.am 2021-01-27 00:52:48.000000000 +0300 +++ faf-git-2884.9521ad3.almalinux/src/pyfaf/actions/Makefile.am 2021-02-09 19:22:53.265070056 +0300 @@ -6,6 +6,7 @@ archlist.py \ assign_release_to_builds.py \ attach_centos_bugs.py \ + attach_almalinux_bugs.py \ bugtrackerlist.py \ pull_abrt_bugs.py \ pull_bug.py \ diff -Naur faf-git-2884.9521ad3.orig/src/pyfaf/bugtrackers/Makefile.am faf-git-2884.9521ad3.almalinux/src/pyfaf/bugtrackers/Makefile.am --- faf-git-2884.9521ad3.orig/src/pyfaf/bugtrackers/Makefile.am 2021-01-27 00:52:48.000000000 +0300 +++ faf-git-2884.9521ad3.almalinux/src/pyfaf/bugtrackers/Makefile.am 2021-02-09 19:23:25.949966773 +0300 @@ -4,6 +4,7 @@ fedorabz.py \ mantisbt.py \ centosmantisbt.py \ + almalinuxmantisbt.py \ rhelbz.py bugtrackersdir = $(pythondir)/pyfaf/bugtrackers diff -Naur faf-git-2884.9521ad3.orig/src/pyfaf/opsys/Makefile.am faf-git-2884.9521ad3.almalinux/src/pyfaf/opsys/Makefile.am --- faf-git-2884.9521ad3.orig/src/pyfaf/opsys/Makefile.am 2021-01-27 00:52:48.000000000 +0300 +++ faf-git-2884.9521ad3.almalinux/src/pyfaf/opsys/Makefile.am 2021-02-09 19:20:43.440480316 +0300 @@ -1,6 +1,7 @@ opsys_PYTHON = \ __init__.py \ centos.py \ + almalinux.py \ fedora.py opsysdir = $(pythondir)/pyfaf/opsys diff -Naur faf-git-2884.9521ad3.orig/src/pyfaf/actions/attach_almalinux_bugs.py faf-git-2884.9521ad3.almalinux/src/pyfaf/actions/attach_almalinux_bugs.py --- faf-git-2884.9521ad3.orig/src/pyfaf/actions/attach_almalinux_bugs.py 1970-01-01 03:00:00.000000000 +0300 +++ faf-git-2884.9521ad3.almalinux/src/pyfaf/actions/attach_almalinux_bugs.py 2021-02-09 19:18:08.530180952 +0300 @@ -0,0 +1,71 @@ +# Copyright (C) 2015 ABRT Team +# Copyright (C) 2015 Red Hat, Inc. +# +# This file is part of faf. +# +# faf is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# faf is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with faf. If not, see . + +from pyfaf.actions import Action +from pyfaf.bugtrackers import bugtrackers +from pyfaf.queries import (get_mantis_bug, + get_report, + get_bugtracker_by_name) +from pyfaf.storage import ReportMantis + + +class AttachAlmaLinuxBugs(Action): + """ + Looks up all bugs created using ABRT on AlmaLinux MantisBT and attaches them + to reports using the bthash from URL. This is a workaround until proper + attaching is supported by the ABRT client. + """ + name = "attach-almalinux-bugs" + + def run(self, cmdline, db) -> None: + mbt = bugtrackers["almalinux-mantisbt"] + db_tracker = get_bugtracker_by_name(db, "almalinux-mantisbt") + for bug_id in mbt.list_bugs(): + self.log_info("Processing Mantis issue #{0}".format(bug_id)) + bug = mbt.mc.mc_issue_get(mbt.user, mbt.password, bug_id) + bug_dict = mbt.preprocess_bug(bug) + if bug_dict and bug_dict.get("url", False): + url = bug_dict["url"] + report_hash = url.split("/")[-1] + db_report = get_report(db, report_hash) + if db_report is None: + self.log_info("Report with hash {0} not found." + .format(report_hash)) + continue + db_mantisbug = get_mantis_bug(db, bug_id, db_tracker.id) + if db_mantisbug is None: + self.log_info("Downloading bug to storage...") + db_mantisbug = mbt.download_bug_to_storage(db, bug_id) + if db_mantisbug is None: + self.log_info("Failed to download bug.") + continue + + db_rm = (db.session.query(ReportMantis) + .filter(ReportMantis.report == db_report) + .filter(ReportMantis.mantisbug == db_mantisbug) + .first()) + if db_rm is None: + db_rm = ReportMantis() + db_rm.mantisbug = db_mantisbug + db_rm.report = db_report + db.session.add(db_rm) + db.session.flush() + self.log_info("Associated issue #{0} with report #{1}." + .format(bug_id, db_report.id)) + else: + self.log_info("Bug {0} is not a valid ABRT issue.".format(bug_id)) diff -Naur faf-git-2884.9521ad3.orig/src/pyfaf/bugtrackers/almalinuxmantisbt.py faf-git-2884.9521ad3.almalinux/src/pyfaf/bugtrackers/almalinuxmantisbt.py --- faf-git-2884.9521ad3.orig/src/pyfaf/bugtrackers/almalinuxmantisbt.py 1970-01-01 03:00:00.000000000 +0300 +++ faf-git-2884.9521ad3.almalinux/src/pyfaf/bugtrackers/almalinuxmantisbt.py 2021-02-09 19:18:51.643896419 +0300 @@ -0,0 +1,27 @@ +# Copyright (C) 2014 ABRT Team +# Copyright (C) 2014 Red Hat, Inc. +# +# This file is part of faf. +# +# faf is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# faf is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with faf. If not, see . + +from pyfaf.bugtrackers import mantisbt + +__all__ = ["AlmaLinuxMantis"] + +# see https://github.com/abrt/faf/issues/695 +# pylint: disable=abstract-method + +class AlmaLinuxMantis(mantisbt.Mantis): + name = "almalinux-mantisbt" diff -Naur faf-git-2884.9521ad3.orig/src/pyfaf/opsys/almalinux.py faf-git-2884.9521ad3.almalinux/src/pyfaf/opsys/almalinux.py --- faf-git-2884.9521ad3.orig/src/pyfaf/opsys/almalinux.py 1970-01-01 03:00:00.000000000 +0300 +++ faf-git-2884.9521ad3.almalinux/src/pyfaf/opsys/almalinux.py 2021-02-09 19:16:54.251671666 +0300 @@ -0,0 +1,245 @@ +# Copyright (C) 2013 ABRT Team +# Copyright (C) 2013 Red Hat, Inc. +# +# This file is part of faf. +# +# faf is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# faf is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with faf. If not, see . +from __future__ import absolute_import + +import re + +from typing import Dict, List + +from pyfaf.opsys import System +from pyfaf.checker import DictChecker, IntChecker, ListChecker, StringChecker +from pyfaf.common import FafError, log +from pyfaf.queries import (get_arch_by_name, + get_opsys_by_name, + get_package_by_nevra, + get_reportpackage, + get_unknown_package) +from pyfaf.storage import (Arch, + Build, + OpSys, + Package, + ReportPackage, + ReportUnknownPackage, + column_len) +from pyfaf.repos import repo_types +from pyfaf.utils.parse import str2bool, words2list +from pyfaf.storage.custom_types import to_semver + +__all__ = ["AlmaLinux"] + +# see https://github.com/abrt/faf/issues/695 +# pylint: disable=abstract-method + +class AlmaLinux(System): + name = "almalinux" + nice_name = "AlmaLinux" + + packages_checker = ListChecker( + DictChecker({ + "name": StringChecker(pattern=r"^[a-zA-Z0-9_\-\.\+~]+$", + maxlen=column_len(Package, + "name")), + "epoch": IntChecker(minval=0), + "version": StringChecker(pattern=r"^[a-zA-Z0-9_\.\+~^]+$", + maxlen=column_len(Build, "version")), + "release": StringChecker(pattern=r"^[a-zA-Z0-9_\.\+]+$", + maxlen=column_len(Build, "release")), + "architecture": StringChecker(pattern=r"^[a-zA-Z0-9_]+$", + maxlen=column_len(Arch, "name")), + }), minlen=0 + ) + + ureport_checker = DictChecker({ + # no need to check name, version and architecture twice + # the toplevel checker already did it + # "name": StringChecker(allowed=[CentOS.name]) + # "version": StringChecker() + # "architecture": StringChecker() + }) + + pkg_roles = ["affected", "related", "selinux_policy"] + + @classmethod + def install(cls, db, logger=None) -> None: + if logger is None: + logger = log.getChild(cls.__name__) + + logger.info("Adding AlmaLinux") + new = OpSys() + new.name = cls.nice_name + db.session.add(new) + db.session.flush() + + @classmethod + def installed(cls, db) -> bool: + return bool(get_opsys_by_name(db, cls.nice_name)) + + def __init__(self) -> None: + super().__init__() + self.eol = None + self.repo_urls = [] + self.allow_unpackaged = None + self.inactive_releases = None + self.active_releases = None + self.load_config_to_self("repo_urls", ["almalinux.repo-urls"], [], + callback=words2list) + self.load_config_to_self("allow_unpackaged", + ["ureport.allow-unpackaged"], False, + callback=str2bool) + self.load_config_to_self("inactive_releases", ["almalinux.inactive-releases"]) + self.load_config_to_self("active_releases", ["almalinux.active-releases"]) + + def _save_packages(self, db, db_report, packages, count=1) -> None: + for package in packages: + role = "RELATED" + if "package_role" in package: + if package["package_role"] == "affected": + role = "CRASHED" + elif package["package_role"] == "selinux_policy": + role = "SELINUX_POLICY" + + db_package = get_package_by_nevra(db, + name=package["name"], + epoch=package["epoch"], + version=package["version"], + release=package["release"], + arch=package["architecture"]) + if db_package is None: + self.log_warn("Package {0}-{1}:{2}-{3}.{4} not found in " + "storage".format(package["name"], + package["epoch"], + package["version"], + package["release"], + package["architecture"])) + + db_unknown_pkg = get_unknown_package(db, + db_report, + role, + package["name"], + package["epoch"], + package["version"], + package["release"], + package["architecture"]) + if db_unknown_pkg is None: + db_arch = get_arch_by_name(db, package["architecture"]) + if db_arch is None: + continue + + db_unknown_pkg = ReportUnknownPackage() + db_unknown_pkg.report = db_report + db_unknown_pkg.name = package["name"] + db_unknown_pkg.epoch = package["epoch"] + db_unknown_pkg.version = package["version"] + db_unknown_pkg.release = package["release"] + db_unknown_pkg.semver = to_semver(package["version"]) + db_unknown_pkg.semrel = to_semver(package["release"]) + db_unknown_pkg.arch = db_arch + db_unknown_pkg.type = role + db_unknown_pkg.count = 0 + db.session.add(db_unknown_pkg) + + db_unknown_pkg.count += count + continue + + db_reportpackage = get_reportpackage(db, db_report, db_package) + if db_reportpackage is None: + db_reportpackage = ReportPackage() + db_reportpackage.report = db_report + db_reportpackage.installed_package = db_package + db_reportpackage.count = 0 + db_reportpackage.type = role + db.session.add(db_reportpackage) + + db_reportpackage.count += count + + def validate_ureport(self, ureport) -> bool: + AlmaLinux.ureport_checker.check(ureport) + return True + + def validate_packages(self, packages) -> bool: + AlmaLinux.packages_checker.check(packages) + affected = False + for package in packages: + if "package_role" in package: + if package["package_role"] not in AlmaLinux.pkg_roles: + raise FafError("Only the following package roles are allowed: " + "{0}".format(", ".join(AlmaLinux.pkg_roles))) + if package["package_role"] == "affected": + affected = True + + if not(affected or self.allow_unpackaged): + raise FafError("uReport must contain affected package") + + return True + + def save_ureport(self, db, db_report, ureport, packages, flush=False, count=1) -> None: + self._save_packages(db, db_report, packages, count=count) + + if flush: + db.session.flush() + + def get_releases(self) -> Dict[str, Dict[str, str]]: + result = {} + + for release in re.findall(r"[\w\.]+", self.inactive_releases): + result[release] = {"status": "EOL"} + for release in re.findall(r"[\w\.]+", self.active_releases): + result[release] = {"status": "ACTIVE"} + + return result + + def get_components(self, release) -> List[str]: + if not self.repo_urls: + self.log_info("No repository URLs were found.") + return [] + + urls = [repo.replace("$releasever", release) for repo in self.repo_urls] + components = [] + if "dnf" in repo_types: + from pyfaf.repos.dnf import Dnf + dnf = Dnf(self.name, *urls) + components.extend(list(set(pkg["name"] + for pkg in dnf.list_packages(["src"])))) + else: + raise FafError("No repo type available") + return components + + #def get_component_acls(self, component, release=None): + # return {} + + def get_build_candidates(self, db) -> List[Build]: + return (db.session.query(Build) + .filter(Build.release.like("%%.el%%")) + .all()) + + def check_pkgname_match(self, packages, parser) -> None: + for package in packages: + if ("package_role" not in package or + package["package_role"].lower() != "affected"): + continue + + nvra = "{0}-{1}-{2}.{3}".format(package["name"], + package["version"], + package["release"], + package["architecture"]) + + match = parser.match(nvra) + if match is not None: + return True + + return False diff -Naur faf-git-2884.9521ad3.orig/src/pyfaf/ureport.py faf-git-2884.9521ad3.almalinux/src/pyfaf/ureport.py --- faf-git-2884.9521ad3.orig/src/pyfaf/ureport.py 2021-01-27 00:52:48.000000000 +0300 +++ faf-git-2884.9521ad3.almalinux/src/pyfaf/ureport.py 2021-02-09 19:24:28.761661372 +0300 @@ -483,6 +483,40 @@ else: log.error("Failed to fetch bug #{0} from '{1}'" .format(bug_id, atype)) + elif atype == "almalinux-mantisbt": + bug_id = int(attachment["data"]) + + reportbug = (db.session.query(ReportMantis) + .filter( + (ReportMantis.report_id == report.id) & + (ReportMantis.mantisbug_id == bug_id)) + .first()) + + if reportbug: + log.debug("Skipping existing attachment") + return + + db_tracker = get_bugtracker_by_name(db, "almalinux-mantisbt") + bug = get_mantis_bug(db, bug_id, db_tracker.id) + if not bug and atype in bugtrackers: + # download from bugtracker identified by atype + tracker = bugtrackers[atype] + + if not tracker.installed(db): + raise FafError("Bugtracker used in this attachment" + " is not installed") + + bug = tracker.download_bug_to_storage(db, bug_id) + + if bug: + new = ReportMantis() + new.report = report + new.mantisbug = bug + db.session.add(new) + db.session.flush() + else: + log.error("Failed to fetch bug #{0} from '{1}'" + .format(bug_id, atype)) elif atype == "comment": comment = ReportComment()