diff options
author | CoprDistGit <infra@openeuler.org> | 2025-03-21 17:37:41 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2025-03-21 17:37:42 +0000 |
commit | 133ef9d4cb72a5081fab588e821eee4a178afc7e (patch) | |
tree | 76779ef5ca00cab259eb516c4c44eef0b3048cc9 | |
parent | c3bf05eae09a01b1153504b7e7de2b8c43a34eea (diff) |
automatic import of copr-backend
-rw-r--r-- | copr-backend.spec | 15 | ||||
-rw-r--r-- | euler_msgbus.patch | 4 | ||||
-rw-r--r-- | fail_to_build_in_oe2403.patch | 14 | ||||
-rw-r--r-- | helpers.patch | 35 | ||||
-rw-r--r-- | print_queues.patch | 12 | ||||
-rw-r--r-- | sources | 4 | ||||
-rw-r--r-- | support_signatrust_backend.patch | 505 |
7 files changed, 440 insertions, 149 deletions
diff --git a/copr-backend.spec b/copr-backend.spec index 511f185..ae9f5f4 100644 --- a/copr-backend.spec +++ b/copr-backend.spec @@ -1,11 +1,11 @@ %global prunerepo_version 1.20 -%global tests_version 2 +%global tests_version 5 %global tests_tar test-data-copr-backend -%global copr_common_version 0.19 +%global copr_common_version 0.20.1.dev1 Name: copr-backend -Version: 1.168 +Version: 1.173 Release: 1%{?dist} Summary: Backend for Copr @@ -17,9 +17,9 @@ URL: https://github.com/fedora-copr/copr # tito build --tgz --tag %%name-%%version-%%release Source0: %{name}-%{version}.tar.gz Source1: %{tests_tar}-%{tests_version}.tar.gz -Patch1: helpers.patch +Patch1: fail_to_build_in_oe2403.patch Patch2: euler_msgbus.patch -Patch3: print_queues.patch +#Patch3: print_queues.patch #Patch4: redis_helpers.patch # should patch to copr common Patch5: support_signatrust_backend.patch Patch6: signatrust_bin.patch @@ -39,6 +39,7 @@ BuildRequires: python3-devel BuildRequires: python3-setuptools BuildRequires: python3-copr +BuildRequires: python3-kafka-python BuildRequires: python3-copr-common = %copr_common_version BuildRequires: python3-daemon BuildRequires: python3-dateutil @@ -103,6 +104,7 @@ Requires: rsync Requires: modulemd-tools >= 0.6 Recommends: util-linux-core Requires: zstd +Requires: python3-kafka-python Requires(post): systemd Requires(preun): systemd @@ -177,7 +179,6 @@ install -d %{buildroot}%{_sysconfdir}/logstash.d install -d %{buildroot}%{_datadir}/logstash/patterns/ cp -a conf/logstash/lighttpd.pattern %{buildroot}%{_datadir}/logstash/patterns/lighttpd.pattern -cp -a conf/playbooks %{buildroot}%{_pkgdocdir}/ install -d %{buildroot}%{_pkgdocdir}/examples/%{_sysconfdir}/logstash.d cp -a conf/logstash/copr_backend.conf %{buildroot}%{_pkgdocdir}/examples/%{_sysconfdir}/logstash.d/copr_backend.conf @@ -221,7 +222,6 @@ useradd -r -g copr -G lighttpd -s /bin/bash -c "COPR user" copr %config(noreplace) %{_sysconfdir}/logrotate.d/copr-backend %dir %{_pkgdocdir} %doc %{_pkgdocdir}/lighttpd -%doc %{_pkgdocdir}/playbooks %dir %{_sysconfdir}/copr %config(noreplace) %attr(0640, root, copr) %{_sysconfdir}/copr/copr-be.conf %{_unitdir}/*.service @@ -242,7 +242,6 @@ useradd -r -g copr -G lighttpd -s /bin/bash -c "COPR user" copr %doc %{_pkgdocdir}/ %exclude %{_pkgdocdir}/lighttpd -%exclude %{_pkgdocdir}/playbooks %changelog * Wed Mar 12 2025 lichaoran <pkwarcraft@hotmail.com> 1.168-1 diff --git a/euler_msgbus.patch b/euler_msgbus.patch index 8973ce1..5eca90a 100644 --- a/euler_msgbus.patch +++ b/euler_msgbus.patch @@ -1,8 +1,8 @@ -diff --git a/backend/copr_backend/euler_msgbus.py b/backend/copr_backend/euler_msgbus.py +diff --git a/copr_backend/euler_msgbus.py b/copr_backend/euler_msgbus.py new file mode 100644 index 000000000..1395249be --- /dev/null -+++ b/backend/copr_backend/euler_msgbus.py ++++ b/copr_backend/euler_msgbus.py @@ -0,0 +1,77 @@ +import socket + diff --git a/fail_to_build_in_oe2403.patch b/fail_to_build_in_oe2403.patch new file mode 100644 index 0000000..be32aee --- /dev/null +++ b/fail_to_build_in_oe2403.patch @@ -0,0 +1,14 @@ +diff --git a/tests/test_modifyrepo.py b/backend/tests/test_modifyrepo.py +index 330ff68f7..2c1bd0a66 100644 +--- a/tests/test_modifyrepo.py ++++ b/tests/test_modifyrepo.py +@@ -431,7 +431,8 @@ def test_copr_repo_run_createrepo(self, popen, do_stat, chroot, database_option) + "--workers", "8", "--general-compress-type=gz", "--update"] + additional_args + + @pytest.mark.skipif( +- distro.id() == 'fedora' and int(distro.version()) >= 36, ++ (distro.id() == 'fedora' and int(distro.version()) >= 36) or ++ (distro.id() == 'openeuler' and float(distro.version()) >= 24.03), + reason="createrepo_c dropped md5 checksum support" + ) + def test_copr_repo_el5(self, f_third_build): diff --git a/helpers.patch b/helpers.patch deleted file mode 100644 index 33be500..0000000 --- a/helpers.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/copr_backend/helpers.py b/copr_backend/helpers.py -index df2819e0..c85c7396 100644 ---- a/copr_backend/helpers.py -+++ b/copr_backend/helpers.py -@@ -288,6 +288,9 @@ class BackendConfigReader(object): - opts.redis_port = _get_conf( - cp, "backend", "redis_port", "6379") - -+ opts.redis_pwd = _get_conf( -+ cp, "backend", "redis_password", None) -+ - opts.redis_db = _get_conf( - cp, "backend", "redis_db", "0") - - -@@ -416,6 +416,19 @@ class BackendConfigReader(object): - opts.aws_cloudfront_distribution = _get_conf( - cp, "backend", "aws_cloudfront_distribution", None) - -+ opts.message = Munch() -+ opts.message.bootstrap_servers = _get_conf( -+ cp, "message", "bootstrap_servers", None) -+ -+ opts.message.user_name = _get_conf( -+ cp, "message", "user_name", None) -+ -+ opts.message.password = _get_conf( -+ cp, "message", "password", None) -+ -+ opts.message.topic = _get_conf( -+ cp, "message", "topic", None) -+ - # ssh options - opts.ssh = Munch() - opts.ssh.builder_config = _get_conf( diff --git a/print_queues.patch b/print_queues.patch deleted file mode 100644 index 83d7fc8..0000000 --- a/print_queues.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/run/print_queues.py b/run/print_queues.py -index 849f8f6a..f48d1157 100755 ---- a/run/print_queues.py -+++ b/run/print_queues.py -@@ -14,6 +14,7 @@ redis_config = { - 'host': opts['redis_host'], - 'port': opts['redis_port'], - 'db': opts['redis_db'], -+ 'password': opts['redis_pwd'], - } - - for i in range(0, NUM_QUEUES): @@ -1,2 +1,2 @@ -8dacd18f46475296d0199365db977649 copr-backend-1.168.tar.gz -a35697a68640fb4c0bcfef02a93eac63 test-data-copr-backend-2.tar.gz +5ed3646f3887a4ff1656c1f7a05d78eb copr-backend-1.173.tar.gz +c94d55e21a4935b3e62f673fbae65af2 test-data-copr-backend-5.tar.gz diff --git a/support_signatrust_backend.patch b/support_signatrust_backend.patch index 9e1fde5..d803d26 100644 --- a/support_signatrust_backend.patch +++ b/support_signatrust_backend.patch @@ -1,5 +1,5 @@ -diff --git a/copr_backend/actions.py b/copr_backend/actions.py -index 39722b84..6da2dfb6 100644 +diff --git a/copr_backend/actions.py b/backend/copr_backend/actions.py +index 39722b843..6da2dfb65 100644 --- a/copr_backend/actions.py +++ b/copr_backend/actions.py @@ -21,13 +21,13 @@ from copr_common.worker_manager import WorkerManager @@ -57,8 +57,8 @@ index 39722b84..6da2dfb6 100644 chroot, opts=self.opts, log=self.log) self.log.info("Forked build %s as %s", src_path, dst_path) -diff --git a/copr_backend/background_worker.py b/copr_backend/background_worker.py -index 4b5f1313..bc05edbd 100644 +diff --git a/copr_backend/background_worker.py b/backend/copr_backend/background_worker.py +index 4b5f13135..bc05edbd7 100644 --- a/copr_backend/background_worker.py +++ b/copr_backend/background_worker.py @@ -9,7 +9,7 @@ import logging @@ -78,21 +78,22 @@ index 4b5f1313..bc05edbd 100644 def _switch_logger_to_redis(self): logger_name = '{}.{}.pid-{}'.format( -diff --git a/copr_backend/background_worker_build.py b/copr_backend/background_worker_build.py -index 233549b4..afc948e8 100644 +diff --git a/copr_backend/background_worker_build.py b/backend/copr_backend/background_worker_build.py +index 0eee39ab8..c12d4921d 100644 --- a/copr_backend/background_worker_build.py +++ b/copr_backend/background_worker_build.py -@@ -27,7 +27,7 @@ from copr_backend.helpers import ( +@@ -27,8 +27,8 @@ from copr_backend.helpers import ( + call_copr_repo, run_cmd, register_build_result, format_evr, ) from copr_backend.job import BuildJob -from copr_backend.msgbus import MessageSender -+from copr_backend.euler_msgbus import MessageSender -from copr_backend.sign import sign_rpms_in_dir, get_pubkey ++from copr_backend.euler_msgbus import MessageSender +from copr_backend.sign import new_signer from copr_backend.sshcmd import SSHConnection, SSHConnectionError from copr_backend.vm_alloc import ResallocHostFactory -@@ -599,7 +599,7 @@ class BuildBackgroundWorker(BackendBackgroundWorker): +@@ -622,7 +622,7 @@ class BuildBackgroundWorker(BackendBackgroundWorker): self.log.info("Going to sign pkgs from source: %s in chroot: %s", self.job.task_id, self.job.chroot_dir) @@ -101,7 +102,7 @@ index 233549b4..afc948e8 100644 self.job.project_owner, self.job.project_name, os.path.join(self.job.chroot_dir, self.job.target_dir_name), -@@ -712,7 +712,7 @@ class BuildBackgroundWorker(BackendBackgroundWorker): +@@ -736,7 +736,7 @@ class BuildBackgroundWorker(BackendBackgroundWorker): # TODO: uncomment this when key revoke/change will be implemented # if os.path.exists(pubkey_path): # return @@ -110,8 +111,8 @@ index 233549b4..afc948e8 100644 self.log.info("Added pubkey for user %s project %s into: %s", user, project, pubkey_path) -diff --git a/copr_backend/constants.py b/copr_backend/constants.py -index a529be28..83bcb8fb 100644 +diff --git a/copr_backend/constants.py b/backend/copr_backend/constants.py +index a529be28a..83bcb8fbe 100644 --- a/copr_backend/constants.py +++ b/copr_backend/constants.py @@ -13,6 +13,7 @@ DEF_BUILD_USER = "mockbuilder" @@ -122,8 +123,8 @@ index a529be28..83bcb8fb 100644 DEF_CONSECUTIVE_FAILURE_THRESHOLD = 10 -diff --git a/copr_backend/exceptions.py b/copr_backend/exceptions.py -index 21afb14c..0865fcc8 100644 +diff --git a/copr_backend/exceptions.py b/backend/copr_backend/exceptions.py +index 21afb14c6..0865fcc8c 100644 --- a/copr_backend/exceptions.py +++ b/copr_backend/exceptions.py @@ -48,8 +48,8 @@ class CoprKeygenRequestError(Exception): @@ -137,8 +138,8 @@ index 21afb14c..0865fcc8 100644 out += "status code: {}\n" "response content: {}\n" \ .format(self.response.status_code, self.response.content) return out -diff --git a/copr_backend/helpers.py b/copr_backend/helpers.py -index 05348366..db4af7f4 100644 +diff --git a/copr_backend/helpers.py b/backend/copr_backend/helpers.py +index 75fa5e62d..291228912 100644 --- a/copr_backend/helpers.py +++ b/copr_backend/helpers.py @@ -31,7 +31,7 @@ from munch import Munch @@ -147,7 +148,7 @@ index 05348366..db4af7f4 100644 from copr_backend.constants import DEF_BUILD_USER, DEF_BUILD_TIMEOUT, DEF_CONSECUTIVE_FAILURE_THRESHOLD, \ - CONSECUTIVE_FAILURE_REDIS_KEY, default_log_format + CONSECUTIVE_FAILURE_REDIS_KEY, default_log_format, DEF_SIGN_BACKEND - from copr_backend.exceptions import CoprBackendError, CoprBackendSrpmError + from copr_backend.exceptions import CoprBackendError from . import constants @@ -309,6 +309,18 @@ class BackendConfigReader(object): @@ -169,32 +170,11 @@ index 05348366..db4af7f4 100644 opts.build_groups = [] for group_id in range(opts.build_groups_count): archs = _get_conf(cp, "backend", -diff --git a/copr_backend/sign.py b/copr_backend/sign.py -index 6655fb98..31af3c8a 100644 +diff --git a/copr_backend/sign.py b/backend/copr_backend/sign.py +index e21653e78..95f674255 100644 --- a/copr_backend/sign.py +++ b/copr_backend/sign.py -@@ -4,8 +4,11 @@ - Wrapper for /bin/sign from obs-sign package - """ - -+from datetime import datetime, timedelta, timezone - from subprocess import Popen, PIPE, SubprocessError - import os -+import re -+import requests - import time - - from packaging import version -@@ -16,8 +19,6 @@ from .exceptions import CoprSignError, CoprSignNoKeyError, \ - CoprKeygenRequestError - - --SIGN_BINARY = "/bin/sign" -- - def create_gpg_email(username, projectname, domain): - """ - Creates canonical name_email to identify gpg key -@@ -25,78 +26,6 @@ def create_gpg_email(username, projectname, domain): +@@ -25,78 +25,6 @@ def create_gpg_email(username, projectname, domain): return "{}#{}@copr.{}".format(username, projectname, domain) @@ -273,56 +253,63 @@ index 6655fb98..31af3c8a 100644 def gpg_hashtype_for_chroot(chroot, opts): """ Given the chroot name (in "mock format", like "fedora-rawhide-x86_64") -@@ -135,133 +64,438 @@ def gpg_hashtype_for_chroot(chroot, opts): - # fallback to sha256 +@@ -136,133 +64,436 @@ def gpg_hashtype_for_chroot(chroot, opts): return "sha256" + +-def sign_rpms_in_dir(username, projectname, path, chroot, opts, log): +- """ +- Signs rpms using obs-signd. +# a sign interface +class Signer(object): + @classmethod + def get_pubkey(cls, username, projectname, log, sign_domain, outfile=None): + """get public key""" + raise NotImplementedError -+ + +- If some some pkgs failed to sign, entire build marked as failed, +- but we continue to try sign other pkgs. + @classmethod + def sign_rpms_in_dir(cls, username, projectname, path, chroot, opts, log): + """batch sign rpms""" + raise NotImplementedError -+ + +- :param username: copr username +- :param projectname: copr projectname +- :param path: directory with rpms to be signed +- :param chroot: chroot name where we sign packages, affects the hash type +- :param Munch opts: backend config + @classmethod -+ def create_user_keys(cls, username, projectname, opts): ++ def create_user_keys(username, projectname, opts, try_indefinitely=False): + """create user key pair""" + raise NotImplementedError -+ + +- :type log: logging.Logger + @classmethod + def _sign_one(cls, path, email, hashtype, log): + """sign one rpm""" + raise NotImplementedError -+ + +- :raises: :py:class:`backend.exceptions.CoprSignError` failed to sign at least one package +- """ + @classmethod + def _unsign_one(cls, path): + # Requires rpm-sign package + cmd = ["/usr/bin/rpm", "--delsign", path] + handle = Popen(cmd, stdout=PIPE, stderr=PIPE, encoding="utf-8") + stdout, stderr = handle.communicate() - --def sign_rpms_in_dir(username, projectname, path, chroot, opts, log): -- """ -- Signs rpms using obs-signd. -- -- If some some pkgs failed to sign, entire build marked as failed, -- but we continue to try sign other pkgs. ++ + if handle.returncode != 0: + err = CoprSignError( + msg="Failed to unsign {}".format(path), + return_code=handle.returncode, + cmd=cmd, stdout=stdout, stderr=stderr) -- :param username: copr username -- :param projectname: copr projectname -- :param path: directory with rpms to be signed -- :param chroot: chroot name where we sign packages, affects the hash type -- :param Munch opts: backend config +- rpm_list = [ +- os.path.join(path, filename) +- for filename in os.listdir(path) +- if filename.endswith(".rpm") +- ] + raise err + + return stdout, stderr @@ -377,25 +364,22 @@ index 6655fb98..31af3c8a 100644 + if filename.endswith(".rpm") + ] -- :type log: logging.Logger +- if not rpm_list: +- return + if not rpm_list: + return -- :raises: :py:class:`backend.exceptions.CoprSignError` failed to sign at least one package -- """ -- rpm_list = [ -- os.path.join(path, filename) -- for filename in os.listdir(path) -- if filename.endswith(".rpm") -- ] +- hashtype = gpg_hashtype_for_chroot(chroot, opts) + hashtype = gpg_hashtype_for_chroot(chroot, opts) -- if not rpm_list: -- return +- try: +- get_pubkey(username, projectname, log, opts.sign_domain) +- except CoprSignNoKeyError: +- create_user_keys(username, projectname, opts, try_indefinitely=True) + try: + cls.get_pubkey(username, projectname, log, opts.sign_domain) + except CoprSignNoKeyError: -+ cls.create_user_keys(username, projectname, opts) ++ cls.create_user_keys(username, projectname, opts, try_indefinitely=True) + + errors = [] # tuples (rpm_filepath, exception) + for rpm in rpm_list: @@ -444,14 +428,12 @@ index 6655fb98..31af3c8a 100644 + .format([err[0] for err in errors])) + +def new_signer(opts): -+ if opts.sign_backend == "obs-signd": -+ return ObsSign -+ elif opts.sign_backend == "signatrust": ++ if opts.sign_backend == "signatrust": + Signatrust.signatrust_token = opts.signatrust_token + Signatrust.signatrust_host = opts.signatrust_host + return Signatrust -+ else: -+ raise CoprSignError("invalid signer type: {}".format(opts.signer_type)) ++ else: # keep obs-signd as default backend ++ return ObsSign + +class ObsSign(Signer): + sign_cmd = "/bin/sign" @@ -484,19 +466,14 @@ index 6655fb98..31af3c8a 100644 + return_code=returncode, + cmd=cmd, stdout=stdout, stderr=stderr) -- hashtype = gpg_hashtype_for_chroot(chroot, opts) +- errors = [] # tuples (rpm_filepath, exception) +- for rpm in rpm_list: + if outfile: + with open(outfile, "w") as handle: + handle.write(stdout) - -- try: -- get_pubkey(username, projectname, log, opts.sign_domain) -- except CoprSignNoKeyError: -- create_user_keys(username, projectname, opts) ++ + return stdout - -- errors = [] # tuples (rpm_filepath, exception) -- for rpm in rpm_list: ++ + @classmethod + def _sign_one(cls, path, email, hashtype, log): + cmd = [cls.sign_cmd, "-4", "-h", hashtype, "-u", email, "-r", path] @@ -509,7 +486,7 @@ index 6655fb98..31af3c8a 100644 + return stdout, stderr + + @classmethod -+ def create_user_keys(cls, username, projectname, opts): ++ def create_user_keys(cls, username, projectname, opts, try_indefinitely=False): + """ + Generate a new key-pair at sign host + @@ -528,7 +505,7 @@ index 6655fb98..31af3c8a 100644 + keygen_url = "http://{}/gen_key".format(opts.keygen_host) + query = dict(url=keygen_url, data=data, method="post") + try: -+ request = SafeRequest(log=log) ++ request = SafeRequest(log=log, try_indefinitely=try_indefinitely) + response = request.send(**query) + except Exception as e: + raise CoprKeygenRequestError( @@ -673,7 +650,7 @@ index 6655fb98..31af3c8a 100644 + """ + check keyname existence --def create_user_keys(username, projectname, opts): +-def create_user_keys(username, projectname, opts, try_indefinitely=False): - """ - Generate a new key-pair at sign host + HEAD /api/v1/keys/ @@ -697,7 +674,7 @@ index 6655fb98..31af3c8a 100644 - keygen_url = "http://{}/gen_key".format(opts.keygen_host) - query = dict(url=keygen_url, data=data, method="post") - try: -- request = SafeRequest(log=log) +- request = SafeRequest(log=log, try_indefinitely=try_indefinitely) - response = request.send(**query) - except Exception as e: - raise CoprKeygenRequestError( @@ -778,7 +755,7 @@ index 6655fb98..31af3c8a 100644 + msg="Failed to check key existence", request="/api/v1/keys/name_identical", response=res) + + @classmethod -+ def create_user_keys(cls, username, projectname, opts): ++ def create_user_keys(cls, username, projectname, opts, try_indefinitely=False): + """ + create user key pair + @@ -823,3 +800,351 @@ index 6655fb98..31af3c8a 100644 + if res.status_code >= 400: + raise CoprKeygenRequestError( + msg="Failed to create user payload: {}".format(data), request="/api/v1/keys/", response=res) +diff --git a/tests/daemons/test_log.py b/backend/tests/daemons/test_log.py +index 73b1a777a..c68b7d918 100644 +--- a/tests/daemons/test_log.py ++++ b/tests/daemons/test_log.py +@@ -45,7 +45,8 @@ class TestLog(object): + self.log_file = os.path.join(self.log_dir, "copr.log") + self.opts = Munch( + verbose=False, +- log_dir=self.log_dir ++ log_dir=self.log_dir, ++ sign_backend = "obs-signd" + ) + print("\n log dir: {}".format(self.log_dir)) + self.queue = MagicMock() +diff --git a/tests/daemons/unused_test_job_grab.py b/backend/tests/daemons/unused_test_job_grab.py +index be3e64c56..79f6472b7 100644 +--- a/tests/daemons/unused_test_job_grab.py ++++ b/tests/daemons/unused_test_job_grab.py +@@ -87,6 +87,7 @@ class TestJobGrab(object): + redis_host="127.0.0.1", + redis_port=6379, + redis_db=0, ++ sign_backend = "obs-signd" + ) + + self.queue = MagicMock() +diff --git a/tests/run/test_copr_prune_results.py b/backend/tests/run/test_copr_prune_results.py +index 6620f01b1..8c9ef2369 100644 +--- a/tests/run/test_copr_prune_results.py ++++ b/tests/run/test_copr_prune_results.py +@@ -59,7 +59,8 @@ class TestPruneResults(object): + self.opts = Munch( + prune_days=14, + frontend_base_url = '<frontend_url>', +- destdir=self.testresults_dir ++ destdir=self.testresults_dir, ++ sign_backend = "obs-signd" + ) + + def teardown_method(self, method): +diff --git a/tests/test_action.py b/backend/tests/test_action.py +index 7da3ab09c..4c935eb53 100644 +--- a/tests/test_action.py ++++ b/tests/test_action.py +@@ -57,6 +57,7 @@ class TestAction(object): + results_baseurl=RESULTS_ROOT_URL, + + do_sign=False, ++ sign_backend = "obs-signd", + + keygen_host="example.com" + ) +@@ -136,7 +137,7 @@ class TestAction(object): + @mock.patch("copr_backend.actions.os.makedirs") + @mock.patch("copr_backend.actions.copy_tree") + @mock.patch("copr_backend.actions.os.path.exists") +- @mock.patch("copr_backend.actions.unsign_rpms_in_dir") ++ @mock.patch("copr_backend.sign.ObsSign.unsign_rpms_in_dir") + @mock.patch("copr_backend.helpers.subprocess.Popen") + def test_action_handle_forks(self, mc_popen, mc_unsign_rpms_in_dir, + mc_exists, mc_copy_tree, _mc_os_makedirs, +diff --git a/tests/test_background_worker_build.py b/backend/tests/test_background_worker_build.py +index 1dfe19563..258564067 100644 +--- a/tests/test_background_worker_build.py ++++ b/tests/test_background_worker_build.py +@@ -77,6 +77,7 @@ def _reset_build_worker(): + # Don't waste time with mocking. We don't want to log anywhere, and we want + # to let BuildBackgroundWorker adjust the handlers. + worker.log.handlers = [] ++ worker.opts.sign_backend = "obs-signd" + return worker + + def _fake_host(): +diff --git a/tests/test_frontend.py b/backend/tests/test_frontend.py +index eeb8dc8f4..06a6e605b 100644 +--- a/tests/test_frontend.py ++++ b/tests/test_frontend.py +@@ -48,6 +48,7 @@ class TestFrontendClient(object): + self.opts = Munch( + frontend_base_url="http://example.com/", + frontend_auth="12345678", ++ sign_backend = "obs-signd" + ) + self.fc = FrontendClient(self.opts) + +diff --git a/tests/test_helpers.py b/backend/tests/test_helpers.py +index 8da70269d..e23565054 100644 +--- a/tests/test_helpers.py ++++ b/tests/test_helpers.py +@@ -31,6 +31,7 @@ class TestHelpers(object): + self.opts = Munch( + redis_db=9, + redis_port=7777, ++ sign_backend = "obs-signd" + ) + + self.rc = get_redis_connection(self.opts) +diff --git a/tests/test_sign.py b/backend/tests/test_sign.py +index bf2dd1b8c..ebb8f2be3 100644 +--- a/tests/test_sign.py ++++ b/tests/test_sign.py +@@ -10,10 +10,10 @@ import pytest + + from copr_backend.exceptions import CoprSignError, CoprSignNoKeyError, CoprKeygenRequestError + from copr_backend.sign import ( +- get_pubkey, _sign_one, sign_rpms_in_dir, create_user_keys, ++ new_signer, + gpg_hashtype_for_chroot, +- call_sign_bin, + ) ++from copr_backend.constants import DEF_SIGN_BACKEND + + STDOUT = "stdout" + STDERR = "stderr" +@@ -33,6 +33,8 @@ class TestSign(object): + self.opts = Munch(keygen_host="example.com") + self.opts.gently_gpg_sha256 = False + self.opts.sign_domain = "fedorahosted.org" ++ self.opts.sign_backend = DEF_SIGN_BACKEND ++ self.signer = new_signer(self.opts) + + def teardown_method(self, method): + if self.tmp_dir_path: +@@ -60,7 +62,7 @@ class TestSign(object): + mc_handle.returncode = 0 + mc_popen.return_value = mc_handle + +- result = get_pubkey(self.username, self.projectname, MagicMock(), self.opts.sign_domain) ++ result = self.signer.get_pubkey(self.username, self.projectname, MagicMock(), self.opts.sign_domain) + assert result == STDOUT + assert mc_popen.call_args[0][0] == ['/bin/sign', '-u', self.usermail, '-p'] + +@@ -70,7 +72,7 @@ class TestSign(object): + mc_popen.side_effect = IOError(STDERR) + + with pytest.raises(CoprSignError): +- get_pubkey(self.username, self.projectname, MagicMock(), self.opts.sign_domain) ++ self.signer.get_pubkey(self.username, self.projectname, MagicMock(), self.opts.sign_domain) + + + @mock.patch("copr_backend.sign.time.sleep") +@@ -82,7 +84,7 @@ class TestSign(object): + mc_popen.return_value = mc_handle + + with pytest.raises(CoprSignNoKeyError) as err: +- get_pubkey(self.username, self.projectname, MagicMock(), self.opts.sign_domain) ++ self.signer.get_pubkey(self.username, self.projectname, MagicMock(), self.opts.sign_domain) + + assert "There are no gpg keys for user foo in keyring" in str(err) + +@@ -95,7 +97,7 @@ class TestSign(object): + mc_popen.return_value = mc_handle + + with pytest.raises(CoprSignError) as err: +- get_pubkey(self.username, self.projectname, MagicMock(), self.opts.sign_domain) ++ self.signer.get_pubkey(self.username, self.projectname, MagicMock(), self.opts.sign_domain) + + assert "Failed to get user pubkey" in str(err) + +@@ -108,7 +110,7 @@ class TestSign(object): + + outfile_path = os.path.join(self.tmp_dir_path, "out.pub") + assert not os.path.exists(outfile_path) +- result = get_pubkey(self.username, self.projectname, MagicMock(), ++ result = self.signer.get_pubkey(self.username, self.projectname, MagicMock(), + self.opts.sign_domain, outfile_path) + assert result == STDOUT + assert os.path.exists(outfile_path) +@@ -124,7 +126,7 @@ class TestSign(object): + mc_popen.return_value = mc_handle + + fake_path = "/tmp/pkg.rpm" +- result = _sign_one(fake_path, self.usermail, "sha1", MagicMock()) ++ result = self.signer._sign_one(fake_path, self.usermail, "sha1", MagicMock()) + assert STDOUT, STDERR == result + + expected_cmd = ['/bin/sign', "-4", "-h", "sha1", "-u", self.usermail, +@@ -137,7 +139,7 @@ class TestSign(object): + + fake_path = "/tmp/pkg.rpm" + with pytest.raises(CoprSignError): +- _sign_one(fake_path, self.usermail, "sha256", MagicMock()) ++ self.signer._sign_one(fake_path, self.usermail, "sha256", MagicMock()) + + @mock.patch("copr_backend.sign.time.sleep") + @mock.patch("copr_backend.sign.Popen") +@@ -149,12 +151,11 @@ class TestSign(object): + + fake_path = "/tmp/pkg.rpm" + with pytest.raises(CoprSignError): +- _sign_one(fake_path, self.usermail, "sha256", MagicMock()) ++ self.signer._sign_one(fake_path, self.usermail, "sha256", MagicMock()) + +- @staticmethod + @mock.patch("copr_backend.sign.time.sleep") + @mock.patch("copr_backend.sign.Popen") +- def test_call_sign_bin_repeatedly(mc_popen, _sleep): ++ def test_call_sign_bin_repeatedly(self, mc_popen, _sleep): + """ + Test that we attempt to run /bin/sign multiple times if it returns + non-zero exit status +@@ -163,13 +164,13 @@ class TestSign(object): + mc_handle.communicate.return_value = (STDOUT, STDERR) + mc_handle.returncode = 1 + mc_popen.return_value = mc_handle +- call_sign_bin(cmd=[], log=MagicMock()) ++ self.signer.call_sign_bin(cmd=[], log=MagicMock()) + assert mc_popen.call_count == 3 + + @mock.patch("copr_backend.sign.SafeRequest.send") + def test_create_user_keys(self, mc_request): + mc_request.return_value.status_code = 200 +- create_user_keys(self.username, self.projectname, self.opts) ++ self.signer.create_user_keys(self.username, self.projectname, self.opts) + + assert mc_request.called + expected_call = mock.call( +@@ -183,7 +184,7 @@ class TestSign(object): + def test_create_user_keys_error_1(self, mc_request): + mc_request.side_effect = IOError() + with pytest.raises(CoprKeygenRequestError) as err: +- create_user_keys(self.username, self.projectname, self.opts) ++ self.signer.create_user_keys(self.username, self.projectname, self.opts) + + assert "Failed to create key-pair" in str(err) + +@@ -195,16 +196,16 @@ class TestSign(object): + mc_request.return_value.content = "error: {}".format(code) + + with pytest.raises(CoprKeygenRequestError) as err: +- create_user_keys(self.username, self.projectname, self.opts) ++ self.signer.create_user_keys(self.username, self.projectname, self.opts) + assert "Failed to create key-pair for user: foo, project:bar" in str(err) + +- @mock.patch("copr_backend.sign._sign_one") +- @mock.patch("copr_backend.sign.create_user_keys") +- @mock.patch("copr_backend.sign.get_pubkey") ++ @mock.patch("copr_backend.sign.ObsSign._sign_one") ++ @mock.patch("copr_backend.sign.ObsSign.create_user_keys") ++ @mock.patch("copr_backend.sign.ObsSign.get_pubkey") + def test_sign_rpms_id_dir_nothing(self, mc_gp, mc_cuk, mc_so, + tmp_dir): + # empty target dir doesn't produce error +- sign_rpms_in_dir(self.username, self.projectname, ++ self.signer.sign_rpms_in_dir(self.username, self.projectname, + self.tmp_dir_path, "epel-8-x86_64", self.opts, + log=MagicMock()) + +@@ -212,13 +213,13 @@ class TestSign(object): + assert not mc_cuk.called + assert not mc_so.called + +- @mock.patch("copr_backend.sign._sign_one") +- @mock.patch("copr_backend.sign.create_user_keys") +- @mock.patch("copr_backend.sign.get_pubkey") ++ @mock.patch("copr_backend.sign.ObsSign._sign_one") ++ @mock.patch("copr_backend.sign.ObsSign.create_user_keys") ++ @mock.patch("copr_backend.sign.ObsSign.get_pubkey") + def test_sign_rpms_id_dir_ok(self, mc_gp, mc_cuk, mc_so, + tmp_dir, tmp_files): + +- sign_rpms_in_dir(self.username, self.projectname, ++ self.signer.sign_rpms_in_dir(self.username, self.projectname, + self.tmp_dir_path, "fedora-rawhide-x86_64", + self.opts, log=MagicMock()) + +@@ -234,15 +235,15 @@ class TestSign(object): + assert os.path.join(self.tmp_dir_path, name) in pathes + assert len(pathes) == count + +- @mock.patch("copr_backend.sign._sign_one") +- @mock.patch("copr_backend.sign.create_user_keys") +- @mock.patch("copr_backend.sign.get_pubkey") ++ @mock.patch("copr_backend.sign.ObsSign._sign_one") ++ @mock.patch("copr_backend.sign.ObsSign.create_user_keys") ++ @mock.patch("copr_backend.sign.ObsSign.get_pubkey") + def test_sign_rpms_id_dir_error_on_pubkey( + self, mc_gp, mc_cuk, mc_so, tmp_dir, tmp_files): + + mc_gp.side_effect = CoprSignError("foobar") + with pytest.raises(CoprSignError): +- sign_rpms_in_dir(self.username, self.projectname, ++ self.signer.sign_rpms_in_dir(self.username, self.projectname, + self.tmp_dir_path, "epel-7-x86_64", self.opts, + log=MagicMock()) + +@@ -250,15 +251,15 @@ class TestSign(object): + assert not mc_cuk.called + assert not mc_so.called + +- @mock.patch("copr_backend.sign._sign_one") +- @mock.patch("copr_backend.sign.create_user_keys") +- @mock.patch("copr_backend.sign.get_pubkey") ++ @mock.patch("copr_backend.sign.ObsSign._sign_one") ++ @mock.patch("copr_backend.sign.ObsSign.create_user_keys") ++ @mock.patch("copr_backend.sign.ObsSign.get_pubkey") + def test_sign_rpms_id_dir_no_pub_key( + self, mc_gp, mc_cuk, mc_so, tmp_dir, tmp_files): + + mc_gp.side_effect = CoprSignNoKeyError("foobar") + +- sign_rpms_in_dir(self.username, self.projectname, ++ self.signer.sign_rpms_in_dir(self.username, self.projectname, + self.tmp_dir_path, "rhel-7-x86_64", self.opts, + log=MagicMock()) + +@@ -266,9 +267,9 @@ class TestSign(object): + assert mc_cuk.called + assert mc_so.called + +- @mock.patch("copr_backend.sign._sign_one") +- @mock.patch("copr_backend.sign.create_user_keys") +- @mock.patch("copr_backend.sign.get_pubkey") ++ @mock.patch("copr_backend.sign.ObsSign._sign_one") ++ @mock.patch("copr_backend.sign.ObsSign.create_user_keys") ++ @mock.patch("copr_backend.sign.ObsSign.get_pubkey") + def test_sign_rpms_id_dir_sign_error_one( + self, mc_gp, mc_cuk, mc_so, tmp_dir, tmp_files): + +@@ -276,7 +277,7 @@ class TestSign(object): + None, CoprSignError("foobar"), None + ] + with pytest.raises(CoprSignError): +- sign_rpms_in_dir(self.username, self.projectname, ++ self.signer.sign_rpms_in_dir(self.username, self.projectname, + self.tmp_dir_path, "fedora-36-x86_64", self.opts, + log=MagicMock()) + +@@ -285,15 +286,15 @@ class TestSign(object): + + assert mc_so.called + +- @mock.patch("copr_backend.sign._sign_one") +- @mock.patch("copr_backend.sign.create_user_keys") +- @mock.patch("copr_backend.sign.get_pubkey") ++ @mock.patch("copr_backend.sign.ObsSign._sign_one") ++ @mock.patch("copr_backend.sign.ObsSign.create_user_keys") ++ @mock.patch("copr_backend.sign.ObsSign.get_pubkey") + def test_sign_rpms_id_dir_sign_error_all( + self, mc_gp, mc_cuk, mc_so, tmp_dir, tmp_files): + + mc_so.side_effect = CoprSignError("foobar") + with pytest.raises(CoprSignError): +- sign_rpms_in_dir(self.username, self.projectname, ++ self.signer.sign_rpms_in_dir(self.username, self.projectname, + self.tmp_dir_path, "fedora-36-i386", self.opts, + log=MagicMock()) + |