diff options
author | CoprDistGit <infra@openeuler.org> | 2025-03-29 06:59:40 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2025-03-29 06:59:40 +0000 |
commit | de4e8c7fc5220c8eea5a7b2110a10ad0673205a5 (patch) | |
tree | 1ccab56fc7ab390613b7bef51c1d75cbcd01972a | |
parent | 0a886502463cf9904e7903d2ea2a1ac8792cafe8 (diff) |
automatic import of copr-backendopeneuler24.03_LTS_SP1
-rw-r--r-- | copr-backend.spec | 1440 | ||||
-rw-r--r-- | euler_msgbus.patch | 83 | ||||
-rw-r--r-- | fail_to_build_in_oe2403.patch | 14 | ||||
-rw-r--r-- | signatrust_bin.patch | 105 | ||||
-rw-r--r-- | sources | 4 | ||||
-rw-r--r-- | support_signatrust_backend.patch | 953 |
6 files changed, 1417 insertions, 1182 deletions
diff --git a/copr-backend.spec b/copr-backend.spec index c70cb5a..2bf37e4 100644 --- a/copr-backend.spec +++ b/copr-backend.spec @@ -1,12 +1,16 @@ +%if 0%{?rhel} <= 7 && 0%{?rhel} > 0 +%global _pkgdocdir %{_docdir}/%{name}-%{version} +%endif + %global prunerepo_version 1.20 -%global tests_version 5 +%global tests_version 2 %global tests_tar test-data-copr-backend -%global copr_common_version 0.21.1.dev1 +%global copr_common_version 0.16.4.dev Name: copr-backend -Version: 1.177 -Release: 1 +Version: 1.168 +Release: 1%{?dist} Summary: Backend for Copr License: GPL-2.0-or-later @@ -16,13 +20,7 @@ URL: https://github.com/fedora-copr/copr # git clone %%url && cd copr # tito build --tgz --tag %%name-%%version-%%release Source0: %{name}-%{version}.tar.gz -Source1: %{tests_tar}-%{tests_version}.tar.gz -Patch1: fail_to_build_in_oe2403.patch -Patch2: euler_msgbus.patch -#Patch3: print_queues.patch -#Patch4: redis_helpers.patch # should patch to copr common -Patch5: support_signatrust_backend.patch -Patch6: signatrust_bin.patch +Source1: https://github.com/fedora-copr/%{tests_tar}/archive/v%{tests_version}/%{tests_tar}-%{tests_version}.tar.gz BuildArch: noarch BuildRequires: asciidoc @@ -39,7 +37,6 @@ 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 @@ -59,12 +56,9 @@ BuildRequires: python3-retask BuildRequires: python3-setproctitle BuildRequires: python3-sphinx BuildRequires: python3-tabulate -BuildRequires: python3-zstandard -BuildRequires: python3-cachetools BuildRequires: modulemd-tools >= 0.6 BuildRequires: prunerepo >= %prunerepo_version BuildRequires: dnf -BuildRequires: rpmdevtools Requires: (copr-selinux if selinux-policy-targeted) Requires: ansible @@ -100,14 +94,12 @@ Requires: python3-retask Requires: python3-setproctitle Requires: python3-tabulate Requires: python3-boto3 -Requires: python3-cachetools Requires: redis Requires: rpm-sign Requires: rsync Requires: modulemd-tools >= 0.6 Recommends: util-linux-core Requires: zstd -Requires: python3-kafka-python Requires(post): systemd Requires(preun): systemd @@ -131,8 +123,7 @@ only. %prep -%autosetup -a1 -p1 - +%setup -q -a 1 %build @@ -182,6 +173,7 @@ 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 @@ -225,6 +217,7 @@ 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 @@ -245,11 +238,1408 @@ useradd -r -g copr -G lighttpd -s /bin/bash -c "COPR user" copr %doc %{_pkgdocdir}/ %exclude %{_pkgdocdir}/lighttpd +%exclude %{_pkgdocdir}/playbooks %changelog -* Tue Mar 25 2025 lichaoran <pkwarcraft@hotmail.com> 1.177-1 -- Upgrade to 1.177 -* Sun Mar 23 2025 lichaoran <pkwarcraft@hotmail.com> 1.173-1 -- Upgrade to 1.173 -* Wed Mar 12 2025 lichaoran <pkwarcraft@hotmail.com> 1.168-1 -- Init package +* Wed Apr 05 2023 Jiri Kyjovsky <j1.kyjovsky@gmail.com> 1.168-1 +- Bump version for release mess + +* Tue Apr 04 2023 Jiri Kyjovsky <j1.kyjovsky@gmail.com> 1.167-1 +- Run createrepo without --database +- Make copr_messaging optional + +* Wed Mar 22 2023 Jiri Kyjovsky <j1.kyjovsky@gmail.com> 1.166-1 +- Don't include package name into srpm result dir name +- Remove libmodulemd1 dependency +- Hardlink RPMs while doing rawhide_to_release +- Make sign key domain name configurable +* Wed Jan 25 2023 Jakub Kadlcik <frostyx@email.cz> 1.165-1 +- Skip the test_run_prunerepo test because of Koji + +* Tue Jan 24 2023 Jakub Kadlcik <frostyx@email.cz> 1.164-1 +- Fix chroot version parsing with new python-packaging +- Fix traceback for non-existing tasks +- Python: drop the unneeded marshmallow dep +- Log general exceptions to find issues more easily +- Proper log argument formatting instead of .format +- Use spdx license + +* Wed Nov 30 2022 Pavel Raiskup <praiskup@redhat.com> 1.163-1 +- start systemd services after the redis.service +- build worker - list the built RPMs with rpm --nosignature + +* Sat Nov 26 2022 Jakub Kadlcik <frostyx@email.cz> 1.162-1 +- use OpenPGP v4 signatures +- migrate from pipes to shlex +- require redis.service to be started +- move to GitHub home page +- add resultdir cleaner +- move dispatcher and background workers to copr-common +- de-prio IO for the analyze-results script +- don't traceback when there are no files in the S3 storage +- allow devel instance to remove access files +- send non-CDN hitcounter hits in chunks +- copr-backend-unknown-resalloc-tickets script +- work with multiple CDN hostnames per instance +- move setup_script_logger to copr-common + +* Mon Sep 26 2022 Pavel Raiskup <praiskup@redhat.com> 1.161-1 +- sign everything EPEL-5+ with sha256 hashalgo + +* Tue Sep 20 2022 Jakub Kadlcik <frostyx@email.cz> 1.160-1 +- aws-hitcounter: remove temporary files as soon as possible +- aws-hitcounter: ignore downloaded SRPM files +- aws-hitcounter: decode special characters from URLs + +* Tue Aug 16 2022 Pavel Raiskup <praiskup@redhat.com> 1.159-1 +- count only hits from an appropriate CDN hostname +- add option for infinite number of attempts to the hitcounter script +- print more reasonable output from AWS hitcounter script + +* Tue Aug 16 2022 Jiri Kyjovsky <j1.kyjovsky@gmail.com> 1.158-1 +- log every request that is sent to frontend + +* Tue Jul 26 2022 Jakub Kadlcik <frostyx@email.cz> 1.157-1 +- Don't use --keep-all-metadata +- Search for comps.xml in chroot dir + +* Tue Jun 21 2022 Jakub Kadlcik <frostyx@email.cz> 1.156-1 +- Consolidate the two hitcounter scripts +- Dump Resalloc ticket ID and hostname to backend.log +- Automatically restart services in %%post +- Don't count RPMs downloaded from Mock +- Attempt to sign multiple times +- Try multiple attempts of creating GPG keys + +* Mon Apr 04 2022 Pavel Raiskup <praiskup@redhat.com> 1.155-1 +- fix slow priority queue filling +- speedup the background-process spawner + +* Fri Mar 18 2022 Pavel Raiskup <praiskup@redhat.com> 1.154-1 +- copr_fix_gpg: automatically refresh CDN cache +- copr_fix_gpg: don't use --skip-stat for copr-repo when RPMs are re-signed +- action processor: properly return failures of the fork action +- sign EL8+ with sha256 hash algorithm +- copr_fix_gpg: add a new --chroot option +- copr_fix_gpg: skip non-chroot directories +- add hitcounter script for AWS CDN +- backend: tasks in concurrent sandboxes reprioritized to be more fair + +* Wed Feb 02 2022 Silvie Chlupova <schlupov@redhat.com> 1.153-1 +- less aggressive final_prunerepo setting +- analyze-results: dump data for projects' chroots +- basic build tagging +- better "regenerate repo" instructions +- limit RubyGems and PyPI package names length +- Disable coverage analysis during RPM build +- python code for removing unused tarballs on dist-git server + +* Wed Nov 10 2021 Silvie Chlupova <schlupov@redhat.com> 1.152-1 +- Fixup ACR handling +- Drop the unused pid file from the specfile +* Thu Sep 30 2021 Silvie Chlupova 1.151-1 +- backend: use lock(timeout=5) to work-around fair-locks + +* Wed Aug 25 2021 Pavel Raiskup <praiskup@redhat.com> 1.150-1 +- request arch_noarch resalloc tag for source RPM builds +- re-try /bin/sign call upon connection timeout +- drop 'check_consecutive_build_fails' script + +* Tue Jun 15 2021 Pavel Raiskup <praiskup@redhat.com> 1.149-1 +- new weekly cron-job for analyzing storage use (graphs, statistics) +- added some convenience globals into copr_backend.setup module +- keep the max batch size really on the MAX_IN_BATCH limit +- require up2date rpmbuild version +- new action for removing CoprDirs (triggered by cron on frontend) +- fix the CompsUpdate action +- users now can disable appstream metadata generation themselves (without admins asistance) +- handle results.json given by builder, and provide it to frontend (served as APIv3 later) +- pruner: allow pruning also the finalized chroots on demand +- invent FE-BE API version, so backend politely waits for an updated copr-frontend version + +* Thu May 13 2021 Pavel Raiskup <praiskup@redhat.com> 1.148-1 +- work with builders also over ipv6 + +* Sun May 02 2021 Pavel Raiskup <praiskup@redhat.com> 1.147-1 +- fix logging traceback for module builds +- call creatrepo_c with --update if possible +- don't do full createrpeo with --rpms-to-remove + +* Fri Apr 30 2021 Pavel Raiskup <praiskup@redhat.com> 1.146-1 +- better fixes for the appstream-builder generated files +- new helper script named /bin/copr-assure-permissions +- do not rsync-copy permissions from the builder +- log the partial "prunerepo" effects into resultdir +- better, more verbose call_copr_repo logging + +* Tue Apr 27 2021 Jakub Kadlcik <frostyx@email.cz> 1.145-1 +- backend: make the walk_limited test not dependend on its output order, pt2 + +* Tue Apr 27 2021 Jakub Kadlcik <frostyx@email.cz> 1.144-1 +- backend: make the walk_limited test not dependend on its output order + +* Tue Apr 27 2021 Jakub Kadlcik <frostyx@email.cz> 1.143-1 +- backend: fix copr_prune_results logging once more +- backend: better logging in prunerepo +- backend: prunerepo: don't re-createrepo when no rpm is removed +- backend: catch correct client exceptions in copr_prune_results +- test: backend: change prunerepo logic, use get_rpms_to_remove from prunerepo +- backend: new fixture for testing prunerepo +- backend: use safe defaults if APIv3 result doesn't contain what it should +- backend: migrate to APIv3 +- backend: better how-to-redirect logs comment +- backend, frontend, keygen, distgit: keep cca 3 months of logs +- backend: don't createrepo in srpm-builds on delete +- backend: test walk_limited function from helpers + +* Tue Mar 16 2021 Pavel Raiskup <praiskup@redhat.com> 1.142-1 +- prepare for the centos-stream-8 rename +- add script to prune srpm-build directories +- pruner: correctly deliver the final prunerepo stamp to frontend +- pruner: logging through RedisLogHandler +- pruner: better parallelization +- pruner: re-try be-fe communication upon failures +- require up2date modulemd-tools + +* Wed Jan 20 2021 Pavel Raiskup <praiskup@redhat.com> 1.141-1 +- run prunerepo in parallel +- add one-shot copr_find_wrong_chroot_artifacts.py script +- support modulemd v2 + +* Tue Dec 01 2020 Pavel Raiskup <praiskup@redhat.com> 1.140-1 +- fix frontend-client post arguments + +* Mon Nov 30 2020 Pavel Raiskup <praiskup@redhat.com> 1.139-1 +- require appropriate common version +- use common for repeatedly sends requests to frontend + +* Mon Nov 30 2020 Pavel Raiskup <praiskup@redhat.com> 1.138-1 +- get back to using standard createrepo_c command from createrepo_mod +- drop call to stomp's conn.start() (it was dropped) + +* Mon Nov 09 2020 Jakub Kadlcik <frostyx@email.cz> 1.137-1 +- backend: test action for deleting chroot +- backend: fix testsuite for the new createrepo_c +- frontend: don't set ended_on for canceled builds +- all: run pytest with -vv in package build +- common, cli, python, rpmbuild, frontend, backend: DistGit source method +- backend: use createrepo_mod tool for generating module repodata + +* Wed Aug 12 2020 Pavel Raiskup <praiskup@redhat.com> 1.136-1 +- testsuite: give more time to the slow Koji builders + +* Mon Aug 10 2020 Pavel Raiskup <praiskup@redhat.com> 1.135-1 +- prioritize all non-background jobs +- fix up libmodulemd dependency + +* Fri Jun 19 2020 Pavel Raiskup <praiskup@redhat.com> 1.134-1 +- fix copr-repo to work with absolute paths +- automatically batch the createrepo requests +- scheduler is now fair, and ordered +- indefinitely retry workers' talk to frontend +- allow canceling also "starting" builds +- more verbose delete action in logs +- cleanup the example configuration +- use FileHandler for backend.log, fixes traceback + +* Tue Jun 09 2020 Pavel Raiskup <praiskup@redhat.com> 1.133-1 +- better build task priority processing +- dump attempt to send message to backend.log +- drop the VMM concept, replaced with resalloc +- delegate more work to the builder code +- external blob tarball for unittests +- buggy error handler in pkg_name_evr() +- basic build task priority +- the reschedule-all builds idiom removed +- fix the build cancelation +- drop duplicate BuildRequire on python-requests +- require the newest version of copr-common +- minimalize the transfered amount of information about actions from FE +- process actions in regard to their priority +- move backend's code to standard PYTHONPATH +- move ActionResult to copr_common.enums +- actions/builds use the same WorkerManager logic +- more verbose rawhide to release action processing + +* Wed Feb 05 2020 Pavel Raiskup <praiskup@redhat.com> 1.132-1 +- better handle invalid options in copr-repo --add/--delete +- copr-repo: optimize-out useless createrepo_c runs +- move initial createrepo check from dispatcher to worker +- don't send messages on bus N-times +- /bin/copr-repo now respects .disable-appstream files +- drop unused build_deleting_without_createrepo option + +* Wed Jan 15 2020 Tomas Hrnciar <thrnciar@redhat.com> 1.131-1 +- put build-ID.log file to resultdir +- call call_copr_repo if initial createrepo failed +- Build Dispatcher does not wait forever till repo is created, + it creates it manually +- properly delete logs for old builds +- delete build-ID.log files again +- edit repositories only by new 'copr-repo' tool +- fix multi-build delete +- fix for not saving end time of actions +- lower traffic in build_dispatcher log +- more resilient redis logging +- attempt to publish on msgbus N-times +- log service: move RequiredBy to [Install] +- keep worker ID in proc title + +* Fri Dec 06 2019 Pavel Raiskup <praiskup@redhat.com> 1.130-1 +- backend: execute actions with sane umask=0022 + +* Wed Dec 04 2019 Pavel Raiskup <praiskup@redhat.com> 1.129-1 +- do not start a build if copr_base is not available yet +- systemd services' restart re-ordering +- de-duplicate frontend_.update() call when reattaching to existing build +- allow specifying timeout for spawn/terminate playbooks +- removing dependecy on euca2ools in spec +- send `uses_devel_repo' as a part of task info +- correctly configure logrotate +- get_redis_logger: skip log entries bellow log_level +- delete leftover action workers from redis + +* Fri Oct 11 2019 Pavel Raiskup <praiskup@redhat.com> 1.128-1 +- restart copr-backend sub-services on failure +- don't kill action processors by 'systemctl restart' +- lower the log traffic in build_dispatcher.log + +* Thu Oct 03 2019 Pavel Raiskup <praiskup@redhat.com> 1.127-1 +- fix testsuite for slow Koji builders + +* Thu Oct 03 2019 Pavel Raiskup <praiskup@redhat.com> 1.126-1 +- more reliable communication with frontend (#1021) +- only ask for auto_createrepo once per project +- parallel handling of actions (#1007) +- don't provide builder-live.log once the build ended, and + add 'copr-compress-live-logs' helper (#985) +- less exceptions in logs +- project forking fixes +- depend on copr-messaging, not fedora-messaging +- fixes for copr_print_results_to_delete.py script + +* Wed Aug 28 2019 Dominik Turecek <dturecek@redhat.com> 1.125-1 +- minimize redis traffic for looping over pending-jobs (issue#902) +- batch delete builds into a single action (issue#688) +- admin opt-out createrepo after build-deleting +- fix wrong message validation class +- refine cleanup_vm_nova.py +- depend on copr-messaging + +* Mon Jul 29 2019 Pavel Raiskup <praiskup@redhat.com> 1.124-1 +- run createrepo immediately, don't wait for build (issue#833) +- compress backend-live.log by calling gzip (issue#86) +- use copr-messaging module for validating outgoing messages +- don't run appstream-builder for PR dirs +- don't run createrepo for srpm directories +- skip VMs with failing live-check in scheduler +- sandbox builds per user/submitter/project +- drop unused compat code for droped /bin/copr-builder +- do not call appstream builder with --max-threads (issue#717) +- added copr_print_results_to_delete.py script, should help + us with removal of orphaned resources on backend storage (issue#712) +- allow disabling appstream builder per project (issue#738) +- tabular output from copr_get_vm_info.py + +* Wed Apr 24 2019 Jakub Kadlčík <frostyx@email.cz> 1.123-1 +- clean data for failed builds; fix #619 +- replace runnecessary regex with str.endswith +- move clean_copr from prunerepo to our codebase +- cleanup_vm_nova.py: use yaml.safe_load +- don't rely on createrepo from prunerepo +- simplify logging through redis +- run sign command without sudo to fix #636 +- encode 'msg' in LogRecord sooner +- fix charset warnings on redis-py v3 +- fix default arguments in redis scripts +- don't prunerepo too old directories +- LogHandler: don't drop exc_info from LogRecord +- use the correct data for rawhide_to_release createrepo +- make copr_prune_results skip already pruned outdated chroots +- require libmodulemd in at least 1.7.0 +- remove dependency on python3-configparser + +* Mon Feb 11 2019 Jakub Kadlčík <frostyx@email.cz> 1.122-1 +- Add requires python3-novaclient +- Set the architecture for which the module has been built +- Generate module artifacts in the correct format +- Compress the modules.yaml file + +* Fri Jan 11 2019 Miroslav Suchý <msuchy@redhat.com> 1.121-1 +- remove data from outdated chroots + +* Thu Jan 10 2019 Miroslav Suchý <msuchy@redhat.com> 1.120-1 +- update list of copr services +- Use oslo_concurrency for craeterepo locking +- use run_cmd() in pkg_name_evr() +- drop "downloading" state +- allow blacklisting packages from chroots + +* Fri Oct 19 2018 Miroslav Suchý <msuchy@redhat.com> 1.119-1 +- optimize copr_log_hitcounter.py for speed a bit +- move selinux rules to copr-selinux +- fix traceback for non-serializable log message +- fix tracebacks in copr-backend-log +- more robust run_tests.sh +- remove unused imports +- py3 compat for msgbus support +- use git_dir_archive instead of git_dir_pack +- migrate from deprecated python3-modulemd to libmodulemd +- doc: remove warning that _static directory does not exists +- doc: the undeline need to be at least as long as the title + +* Thu Aug 23 2018 clime <clime@redhat.com> 1.118-1 +- fix logging exception +- send proper arguments for rawhide_to_release +- packaging: Python 2/3, RHEL/Fedora fixes + +* Mon Aug 06 2018 clime <clime@redhat.com> 1.117-1 +- None task protection +- pagure integration +- use manual .pyc file generation +- remove unused imports, ad. pr#327 +- resolving pylint warnings +- for py3 use unittest.mock +- fix msgbus ContentType to application/json + +* Fri May 18 2018 clime <clime@redhat.com> 1.116-1 +- fix #291 forks are incomplete +- log more information about incoming actions +- preparation for opensuse-leap-15.0-x86_64 + +* Thu Apr 26 2018 Dominik Turecek <dturecek@redhat.com> 1.115-1 +- rpkg deployment into COPR - containers + releng continuation +- fix pagure bugs #269, #273, #221 and #268 +- cleanup in test_helpers, one test added +- change order of args in StrictRedis call +- add comment about expected usage of the copr_log_hitcounter script +- try to send hit data to frontend several times from +copr_log_hitcounter + +* Mon Feb 26 2018 clime <clime@redhat.com> 1.114-1 +- add possibility for copr_log_hitcounter to ignore multiple subnets + +* Fri Feb 23 2018 clime <clime@redhat.com> 1.113-1 +- original builder deprecation +- remove Group tag + +* Mon Feb 19 2018 clime <clime@redhat.com> 1.112-1 +- Shebangs cleanup +- escapes in changelogs + +* Sun Feb 18 2018 clime <clime@redhat.com> 1.111-1 +- use netaddr instead of IPy module +- sleep after each load_jobs iteration +- python3 conversion +- UMB: adding content type +- add source_status field for Builds +- generate module artifacts rpms +- the rsync log is actually renderred directly into result dir now +- mockchain.log renamed to backend.log +- pg#192 missing records in mockchain.log +- enable running tests in spec file +- enable and update vmmamanger tests, fix three minor bugs in the + manager +- frontend now presents the whole job queue state to + backend +- copy only module builds into the repo directory + +* Wed Dec 20 2017 clime <clime@redhat.com> 1.110-1 +- exception handling for hit counting when IP address cannot be parsed + +* Mon Dec 18 2017 Dominik Turecek <dturecek@redhat.com> 1.109-1 +- terminate also 'in_use' builders if health checks have failed +- make --detached the last arg for copr-rpmbuild +- update copr_log_hitcounter to check ip against ignored pattern +- new msg bus options +- disable DNF makecache timer/service +- fix message duplication for multi-bus scenario + +* Thu Nov 16 2017 Miroslav Suchý <msuchy@redhat.com> 1.108-1 +- optimize createrepo_c +- Revert "[backend] remove --ignore-lock from createrepo_c" + +* Thu Nov 09 2017 clime <clime@redhat.com> 1.107-1 +- kill all processes in copr-rpmbuild's process group +- add --drop-resultdir switch to copr-rpmbuild call +- release_vm immediately after VM is no longer needed +- remove --ignore-lock from createrepo_c + +* Wed Oct 18 2017 clime <clime@redhat.com> 1.106-1 +- run copr-rpmbuild with --verbose option + +* Wed Sep 27 2017 clime <clime@redhat.com> 1.105-1 +- remove uneeded yum dep + +* Tue Sep 26 2017 clime <clime@redhat.com> 1.104-1 +- update copr-rpmbuild command for the new options +- change arguments to build_id and chroot +- #128 AppStream data collection vetoes addons +- fix rpm download stats collection +- module-stuff update + +* Fri Sep 15 2017 clime <clime@redhat.com> 1.103-1 +- update fedora image version to 26 +- fixes for recent code + +* Thu Sep 07 2017 clime <clime@redhat.com> 1.102-1 +- srpms are now being built from upstream on builders + +* Wed Jun 14 2017 clime <clime@redhat.com> 1.101-1 +- remove unused helpers.run_ssh + function spacing fixup +- cancel-build action fix + +* Fri Jun 09 2017 clime <clime@redhat.com> 1.100-1 +- extend check for a builder package present on a builder machine +- arbitrary dist-git branching +- remove --add-cache-id from appstream-builder call, see Bug 1426166 +- change to using a standalone builder package + +* Wed May 03 2017 clime <clime@redhat.com> 1.99-1 +- missing on_success_build call added back to sign packages and recreate repo after each build + +* Mon Apr 24 2017 clime <clime@redhat.com> 1.98-1 +- Bug 1444804 - Logs are not present for failed builds + +* Wed Apr 19 2017 clime <clime@redhat.com> 1.97-1 +- do not condrestart optional logstash service +- standalone builder option +- build reattaching after copr-backend(-build) service restart +- live mockchain log +- use openssh instead of paramiko +- update cleanup_vm_nova script +- remove buggy logging +- removed Sphinx as a dependency... +- verbose log everything we have about failed playbook +- replace fedorahosted links +- make systemd services out of ActionDispatcher and BuildDispatcher + +* Thu Jan 26 2017 clime <clime@redhat.com> 1.96-1 +- Fixes for building COPR Backend and Dist-git on EL7 +- simplified/improved logging of exceptions mainly +- don't use sha256 checksum for rhel-5* repos, too +- drop mentions of the max_builds_per_vm optoin +- switched usage of deprecated ansible Runner for python-paramiko module +- os_nova filter plugin fixed for python-novaclient 3 +- support for STOMP msg buses +- fix Bug 1402689 regarding job cancellation +- jobgrab service is no more +- respect 'do_sign' option when forking +- fix buildroot_cmd for rhel mock profiles + +* Thu Dec 01 2016 clime <clime@redhat.com> 1.95-1 +- use buildroot_pkgs substitution type according to job.chroot +- use timeout command to respect timeout param coming from frontend +- don't ship unitfiles in %%bindir +- move createrepo to the end of the rawhide_to_release handler +- modulemd 1.0.2 compatibility +- Bug 1397119 - Error reading SSH protocol banner +- added auto-prune project's option +- Bug 1086139 - [RFE] provide UI to cancel a build +- Fix misleading debug statement +- fix exception logging in ensure_dir_exists helper +- Fix chroot_setup_cmd regex for custom chroot + +* Mon Sep 19 2016 clime <clime@redhat.com> 1.94-1 +- also provide default version and release for generated modules.json + +* Mon Sep 19 2016 clime <clime@redhat.com> 1.93-1 +- fix NameError: global name 'result' is not defined +- fix exception logging +- Modularity support +- Bug 1357564 - RFE: allow downloading of mock profiles (reproducible builds) +- "safer" exception handling for actions + +* Mon Aug 15 2016 clime <clime@redhat.com> 1.92-1 +- wrap feedback about actions to frontend into try-except +- log even the traceback from forking +- use makedirs instead of mkpath in fork action +- if anything bad happens, log exception in generate_gpg_key action +- also restart copr-backend-vmm and copr-backend-log when (re)installing +- Bug 1361344 - RFE: Allow denial of build deletion and resubmitting at project or group level +- catch errors in fork action +- set action result for comps.xml and module_md.yaml file deletion +- backend fork action now takes care of new gpg-key generation instead of frontend +- removed no longer supported --api-version=0.8 arg from appstream-builder command line +- specify module_md as module type +- fix saving comps.xml and module_md.yaml into empty copr (with no build) +- module_md.yaml is added to repodata now similarly to appstream.xml +- support for generation of module dist tags +- module_md.yaml uploading for a chroot +- simplified build and action task workflow +- use copy of the mock (chroot) config, not the original in /etc/mock/ + +* Wed Jun 22 2016 Miroslav Suchý <msuchy@redhat.com> 1.91-1 +- configure more packages to run pylint +- terminate machine which was only partially spawned +- [copr-prune-results] do not sys.exit if prunerepo returns non-zero status, + just raise an exception +- more of log file migration +- claim /var/log/copr-backend in %%files +- adjust log path in runtime files +- update conf file log path directives +- change logdir to /var/log/copr-backend/ + +* Fri May 27 2016 Miroslav Suchý <msuchy@redhat.com> 1.90-1 +- do not use --log-dir in appstream-builder + +* Tue May 24 2016 Miroslav Suchý <miroslav@suchy.cz> 1.89-1 +- use correct conditional in requires + +* Mon May 23 2016 Miroslav Suchý <msuchy@redhat.com> 1.88-1 +- backend: change logstash requires to soft requires +- 1336360 - allow custom chroots + +* Fri May 13 2016 Miroslav Suchý <msuchy@redhat.com> 1.87-1 +- workaround for BZ 1334200 +- more info in logs by default +- print seconds just as int +- unsign gpg from forked packages before signing them with new key +- sign forked packages @TODO We need to delsign them first + +* Fri May 06 2016 Miroslav Suchý <msuchy@redhat.com> 1.86-1 +- more info in logs by default +- unsign gpg from forked packages before signing them with new key + +* Thu May 05 2016 Miroslav Suchý <msuchy@redhat.com> 1.85-1 +- also be tolerant about sign/unsign failures on particular rpm +- just log errors (exception) during particular copr fixing, do not + interrupt the whole process +- added additional check on copr path existence into copr_fix_gpg.py +- allow sudo /usr/bin/rpm for `copr` user +- look into build dirs (subdirs of a chroot) for rpms to be re-signed +- on F24+ use just ansible +- Run rpm-sign with sudo when unsigning +- script to fix gpg keys & rpm signatures +- define functions for deleting gpg signatures from packages +- removed temporary mock workaround from Dockerfile (no + longer needed) + +* Thu Apr 28 2016 Miroslav Suchý <msuchy@redhat.com> 1.84-1 +- Bug 1327996 - config_opts['use_host_resolv'] is not set back to + True if it was False before + +* Fri Apr 22 2016 Miroslav Suchý <msuchy@redhat.com> 1.83-1 +- run createrepo on forked project (RhBug: 1329076) +- Bug 1327852 - /usr/bin/check_consecutive_build_fails.py errors +- we need to stick to ansible1.9 +- more escaping +- prunning down testresults :) +- a few unittests for copr_prune_results.py script +- unit test "fixes" +- fix error when forking into existing project +- (mockremote): improve chroot_setup_cmd replacement for EL-5 +- copr_prune_results.py - python path fix +- Bug 1324514 - copr createrepo error messages - fix for errors of + type one +- Bug 1324514 - copr createrepo error messages - fix for errors of + type 2 + +* Thu Mar 24 2016 Jakub Kadlčík <jkadlcik@redhat.com> 1.82-1 +- use timeout variable from config + +* Mon Mar 14 2016 Jakub Kadlčík <jkadlcik@redhat.com> 1.81-1 +- support project forking +- support building from PyPI +- support for redis_host, redis_port, redis_db config options +- dockerized-backend project moved under backend/docker +- run createrepo in rawhide_to_release +- specify rawhide name when calling rawhide_to_release + +* Fri Jan 29 2016 Miroslav Suchý <msuchy@redhat.com> 1.80-1 +- do not fail when when you receive job with architecture which does not have + queue +- fix 1260780 - Build fails after successful package generation - + just add a log error message pointing to an rsync log +- jobgrabcontrol.py/retask misuse fix +- "localhost-targeted" spawn and terminate playbooks added for testing +- [frontend]implement rawhide to release feature First create new + chroots: python manage.py create_chroot fedora-24-i386 fedora-24-x86_64 +- abstraction above [BE <-> JG <-> Builders] channels +- don't traceback backend if frontend is not yet up&running +- do not preserve user and group when rsyncing + +* Wed Dec 23 2015 Miroslav Suchý <msuchy@redhat.com> 1.79-1 +- fix packaging issues in epel-7+ + +* Mon Nov 16 2015 Miroslav Suchý <miroslav@suchy.cz> 1.78-1 +- handle_generate_gpg_key skips key creation when signing is disabled +- Added test_handle_generate_gpg_key +- fixed failing tests +- show when createrepo is waiting for lock +- do not block builds when processing too much actions + +* Fri Nov 06 2015 Miroslav Suchý <msuchy@redhat.com> 1.77-1 +- we need to have recent python-copr +- create copr-backend-service script to handle all copr services +- [backend] fix not starting job_grab + +* Tue Oct 13 2015 Miroslav Suchý <msuchy@redhat.com> 1.76-1 +- createrepo action run infinitely when applied to + deleted project + +* Mon Sep 21 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.75-1 +- [backend] run copr-backend-log service before other components + +* Mon Sep 21 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.74-1 +- [backend] add executable bit to run/copr_run_job_grab.py + +* Mon Sep 21 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.73-1 +- added context manager `local_file_logger` +- eliminated global multiprocessing.Lock +- split backend daemon: extracted RedisLogHandler, JobGrab, VMM +- replace python-bunch with python-munch +- added comps.xml support + +* Tue Aug 04 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.72-1 +- support new results naming in the build deletion action +- fix BuildJob.results_dir; eliminated MockRemote.pkg_dest_path +- using package name and versiong given in the build task; cleanup; +- handle error's caused by failure to obtain srpm from dist-git +- repairing test for newest changes +- rsync update + several fixes +- building from dist git +- fix vm spawn check: spawner count child processes per build group; + +* Wed Jul 01 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.71-1 +- add small script to print queues +- AppData supproted +- copy mockchain and rsync logs to resdir (RhBug:1221519) +- note which modules still stops us from migrating to python3 + +* Mon Jun 15 2015 Miroslav Suchý <msuchy@redhat.com> 1.70-1 +- alter vm_name= regexp +- polishing Bug 1195867 - Move or delete logs when rebuilding failed + build. +- backup only info and log files +- have just one backup directory per results directory +- clean results from previous build +- alter IP= regexp +- disabled appdata until fixed +- unable appdata in createrepo +- more safe VmMaster.check_one_vm_for_dead_builder function +- adding support for AppData +- new requirement form AppData support +- createrepo_unsafe now returns only STDOUT and raise exception on + errors + +* Mon Jun 01 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.69-1 +- removed creation of symlinks for log.gz +- catch exception during Worker.can_start_job +- config cleanup + +* Thu May 28 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.68-1 +- [backend] add config option for VM health check timeout +- [backend] moved config parameters from Threshold class into the backend + config file + +* Thu May 21 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.67-1 +- [backend] Handle unexpected exception VmMaster::check_one_vm_for_dead_builder + +* Thu May 21 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.66-1 +- [backend] fix race condition in check for dead worker + +* Wed May 20 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.65-1 +- [backend] Rescheduling unfinished builds before stop +- fix indentation +- [backend] request frontend to reschedule old unfinished builds at startup +- [backend] update sytemd unit: removed obsolete + EnviromentFile=/home/copr/cloud/ec2rc.variable directive + +* Tue May 19 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.64-1 +- [backend] check for aux process state and restart if needed + +* Fri May 15 2015 Miroslav Suchý <msuchy@redhat.com> 1.63-1 +- BR python-sphinx + +* Fri May 15 2015 Miroslav Suchý <msuchy@redhat.com> 1.62-1 +- [backend] small cleanup, need more tests + +* Fri May 15 2015 Miroslav Suchý <msuchy@redhat.com> 1.61-1 +- [backend] notify job_grab to remove job from added when start_job failed +- [backend] [vmm] terminate VM with state IN_USE only when builder process is + missed +- [backend] bugfix VMM.get_all_vm_in_group : VM could be removed before load + occures +- [backend] job_grab: postpone build is we already serving more builds + than`max_vm_per_user` option +- [backend] fix build logging +- [backend] defer sending job to worker if job owner acquired too much VMs +- [backend] replaced Thresholds.dirty_vm_terminating_timeout with config option + vm_dirty_terminating_timeout +- [backend] Thread's doesn't have a pid +- [backend] vm manage: user threading instead of multiprocessing +- [backend] VMM aware cleunup_vm_nova +- [backend] moving to nginx to serve results. lighttpd couldnt server pre- + compressed properly +- [backend] script to clean up erred and forgotten VM's using python-novaclient +- [backend] new documentation +- [backend] repaired unittests +- [backend] updated builder playbooks +- [backend] updated example spawn playbook +- [backend] don't provide logstash config directly, add only example to + documentation +- [backend] do logging from multiply processes through redis pubsub; some fixes + to VM-management +- [image_builder] initial release, due to OS bug, we cannot create snapshot + after provision through API, need to do it manually in the WebUI. +- [backend] tests cleanup +- [backend] ensure that prune script running under the copr user; simpler + `copr_find_obsolete_builds` +- [backend] safer copr_prune_results script, unittests +- [backend][frontend] Send for delete action only `src_pkg_name` instead of + original URL. +- [backend] returned script to call createrepo from cli +- [copr] don't allow acquire VMs that was last checked before server restart. +- [backend] Added limit to acquire_vm based on VMs used by the same username at + the current moment. +- New python dependencies +- [backend] run tmp redis-server for tests +- [backend] Dedicated and more complex management for builder machines. + [frontend] Now builds failed due to VM errors reschedulted faster. + +* Fri Mar 20 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.60-1 +- [backend][spec] start/stop redis server during package build tests + +* Fri Mar 20 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.59-1 +- [backend][hotfix] 1203753 : don't process delete action if src_pkg is + mallformed + +* Mon Mar 02 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.58-1 +- [rhbz:#1185959] - RFE: Present statistics about project + popularity. A few more counters for downloads from backend's result + directory. +- [backend] [rhbz:#1191037] RFE: Include package name and version in fedmsg + notification +- [rhbz:#1091640] RFE: Release specific additional repos +- [rhbz:#1119300] [RFE] allow easy add copr repos in using + repository lis +- [backend][frontend] removing code related to multiply source rpms in build. + Build.pkgs now expected to have exactly one src.rpm. +- [copr] backend: script fixes, dropped create_repo cli script +- more file descriptors on builder +- [rhbz:#1171796] copr sometimes doesn't delete build from repository +- [rhbz:#1073333] Record consecutive builds fails to redis. Added + script to produce warnings for nagios check from failures recorded to redis. +- correctly print job representation + +* Fri Jan 23 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.57-1 +- call correct Worker method on backend termination +- put gpg pubkey to the project results root dir (one level up from + the chroot dir) +- don't kill Worker from errors during job build +- [rhbz:#1169782] RFE - Show package "version-release" instead of + just "version" +- [rhbz:#1117446] add a build id tagfile into the package directory +- Updated unittests to reflect latest changes. +- builder: use only one log file for rsync per build +- dispatcher: run terminate_instance safely +- cleanup example config +- cleanup mockremote.builder +- Builder.download don't use Popen+PIPE.communicate with rsync, + output redirected to the files. +- disable networking only when required; python style exception + handling in mockremote*; removed run/copr_mockremote +- test build with disabled networking +- simplified mockremote.builder.Builder.check_for_ans_error; new + method mockremote.builder.Builder.run_ansible_with_check +- daemons.dispatched.Worker: don't fail when wrong group_id was + provided +- add vm_ip to worker process title (rhbz: 1182637) + +* Wed Jan 14 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.56-1 +- [backend] [.spec] fix %%files section + +* Wed Jan 14 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.55-1 +- [backend] [bugfix] set pythonpath in systemd unit to run /usr/bin/copr_be.py +- [backend] [RHBZ:#1182106] JobGrabber dies when action raises an exception. +- [backend] Moved scripts into /usr/bin/ Renamed copr{-,_}be.py. + +* Wed Jan 07 2015 Miroslav Suchý <msuchy@redhat.com> 1.54-1 +- 1179713 - workaround for 1179806 +- run script unbufferred otherwise log is written after full block +- express that it is n-th projects +- fix permissions on prune script + +* Mon Jan 05 2015 Valentin Gologuzov <vgologuz@redhat.com> 1.53-1 +- [backend, frontend] [RHBZ:#1176364] Wrong value for the build timeout. + +* Mon Dec 15 2014 Valentin Gologuzov <vgologuz@redhat.com> 1.52-1 +- fixed config option `results_baseurl` usage, in mockremote + +* Fri Dec 12 2014 Valentin Gologuzov <vgologuz@redhat.com> 1.51-1 +- updated BuildRequires; cleanup imports +- package sign: generate gpg usermail with special symbol +- bugfix: when dispatcher has vm_ip it shouldn't start new VM; +- run tests during rpm build +- minor docstring fix + +* Wed Dec 10 2014 Valentin Gologuzov <vgologuz@redhat.com> 1.50-1 +- [backend] added option to control ansible ssh transport, changed by default + to `paramiko` [frontend] bugfix api create new +- [backend] removed spawn_vars options, to be able to spawn VMs in advance +- [backend] unittest for backend.daemons.log +- [backend] massive refactoring and unittest coverage +- [backend] backend.sign: discover `keygen_host` from backend config file + +* Tue Nov 25 2014 Valentin Gologuzov <vgologuz@redhat.com> 1.49-1 +- [backend] small bug in dispatcher + +* Tue Nov 25 2014 Valentin Gologuzov <vgologuz@redhat.com> 1.48-1 +- bugfixes, disabled debug prints, fixed PEP8 violations + +* Thu Nov 20 2014 Valentin Gologuzov <vgologuz@redhat.com> 1.47-1 +- refactored mockremote, added explicit BuildJob class +- allow to spawn builder in advance +- copr-prune-repo respects auto_createrepo option +- bugfix: repeated config reads produced constantly growing lists + +* Fri Oct 24 2014 Valentin Gologuzov <vgologuz@redhat.com> 1.46-1 +- [backend] added handling of new action type: "createrepo" +- [backend] added dependency on `python-copr` +- [backend] added to mockchroot -a /devel/repodata subfolder +- [backend] new config option to define the public frontend api endpoint +- [backend] conditional execution of createrepo_c +- [backend] unittest for Action and minor refactoring +- [backend] rotate backend.log as well + +* Thu Sep 18 2014 Miroslav Suchý <msuchy@redhat.com> 1.45-1 +- [backend][keygen] minor fixes/typos + +* Thu Sep 18 2014 Valentin Gologuzov <vgologuz@redhat.com> 1.44-1 +- [backend] type fix + +* Thu Sep 18 2014 Valentin Gologuzov <vgologuz@redhat.com> 1.43-1 +- [backend] config parsing: convert fields to proper data type. +- [backend] added option to disable package signing. +- [keygen] new component for copr: gpg key generation for package sign +- [backend] broadcast both submitter and owner to fedmsg +- [backend] example backend config: changes url protocol to HTTPS. + +* Mon Aug 25 2014 Adam Samalik <asamalik@redhat.com> 1.42-1 +- [backend] [RHBZ:1128606 ] For rhel-5 builds pass "--checksum md5" to + `createrepo_c` command. +- [backend] fix of builder test +- [backend] test builder instance after spawning +- [backend] never give up while spawning an OpenStack VM +- [backend] worker's log filename correction +- [backend] task id in worker process' name +- [backend] async build playbooks + +* Thu Aug 14 2014 Miroslav Suchý <miroslav@suchy.cz> 1.41-1 +- [backend] fix of fix +- [backend] couple of fixes + +* Wed Aug 13 2014 Miroslav Suchý <msuchy@redhat.com> 1.40-1 +- [backend] queue cleaning +- [backend] experimental build groups for more architectures +- [backend] fix of a strange beaviour of retask +- [backend] fedmsg shows submitter instead of project owner +- [backend] new task queue for workers using retask +- epel-7 comps workaround is need no more, since CENTOS7 have been released + +* Tue Jul 22 2014 Miroslav Suchý <msuchy@redhat.com> 1.39-1 +- FrontendCallback prettified +- Starting state implemented, cancelling fixed +- [backend] faster skipping + +* Tue Jul 15 2014 Miroslav Suchý <msuchy@redhat.com> 1.38-1 +- [backend] built pkgs fix + +* Tue Jul 15 2014 Miroslav Suchý <msuchy@redhat.com> 1.37-1 +- [backend] shell command uses pipes.quote +- Return the chroot that finished when sending build.end +- better and safer deleting of builds +- [backend] separate playbooks for each architecture +- [backend] built pkgs - include subpackages +- [backend] skipped status and package details implemented +- document vm_name option + +* Thu Jun 19 2014 Miroslav Suchý <msuchy@redhat.com> 1.36-1 +- backend: migrate to nova ansible module +- backend: make sure that exit() exit whole script not just sub-shell +- backend: allow passing additional info to playbooks +- handle {spawn,terminate}_instance equally +- backend: stop if you could not change to directory +- W:310, 8: Attribute 'abort' defined outside __init__ (attribute-defined- + outside-init) +- W:139, 0: Dangerous default value [] as argument (dangerous-default-value) + W:139, 0: Dangerous default value [0] as argument (dangerous-default-value) + W:139, 0: Dangerous default value ['stdout', 'stderr'] as argument + (dangerous-default-value) +- W:543, 4: Dangerous default value DEF_MACROS ({}) as argument (dangerous- + default-value) +- W:543, 4: Dangerous default value DEF_REPOS ([]) as argument (dangerous- + default-value) +- W:677,24: Unused variable 'out' (unused-variable) W:677,20: Unused variable + 'rc' (unused-variable) +- W:297,12: Unused variable 'hn' (unused-variable) +- C:116, 0: Unnecessary parens after 'print' keyword (superfluous-parens) +- W: 72,28: Unused variable 'out' (unused-variable) W: 72,24: Unused variable + 'rc' (unused-variable) +- fix typo in exception message printing +- 1102788 - Increase number of file descriptors on the build machine + +* Fri May 30 2014 Miroslav Suchý <msuchy@redhat.com> 1.35-1 +- follow selinux packaging draft +- [backend] epel 5 repo fix (sha256 -> sha) + +* Thu Apr 24 2014 Miroslav Suchý <msuchy@redhat.com> 1.34-1 +- if directory does not exist, do not try to delete it + +* Tue Apr 15 2014 Miroslav Suchý <miroslav@suchy.cz> 1.33-1 +- do not publish copr.worker messages +- better count workers + +* Thu Apr 10 2014 Miroslav Suchý <msuchy@redhat.com> 1.32-1 +- include ec2rc in service unit file + +* Wed Apr 09 2014 Miroslav Suchý <msuchy@redhat.com> 1.31-1 +- 1077791 - set perm of cronfile to 755 +- 1077791 - add LICENSE to -doc subpackage +- 1077791 - remove make as BR + +* Tue Mar 18 2014 Miroslav Suchý <msuchy@redhat.com> 1.30-1 +- [backend] exclude files which are part of main package +- copr-backend.src:113: W: mixed-use-of-spaces-and-tabs (spaces: line 5, tab: + line 113) + +* Tue Mar 18 2014 Miroslav Suchý <msuchy@redhat.com> 1.29-1 +- move backend into separate package + +* Thu Feb 27 2014 Miroslav Suchý <msuchy@redhat.com> 1.28-1 +- [backend] - pass lock to Actions + +* Wed Feb 26 2014 Miroslav Suchý <msuchy@redhat.com> 1.27-1 +- [frontend] update to jquery 1.11.0 +- [fronted] link username to fas +- [cli] allow to build into projects of other users +- [backend] do not create repo in destdir +- [backend] ensure that only one createrepo is running at the same time +- [cli] allow to get data from sent build +- temporary workaround for BZ 1065251 +- Chroot details API now uses GET instead of POST +- when deleting/canceling task, go to same page +- add copr modification to web api +- 1063311 - admin should be able to delete task +- [frontend] Stray end tag h4. +- [frontend] another s/coprs/projects/ rename +- [frontend] provide info about last successful build +- [spec] rhel5 needs group definition even in subpackage +- [frontend] move 'you agree' text to dd +- [frontend] add margin to chroots-set +- [frontend] add margin to field label +- [frontend] put disclaimer to paragraph tags +- [frontend] use black font color +- [frontend] use default filter instead of *_not_filled +- [frontend] use markdown template filter +- [frontend] use isdigit instead of is_int +- [frontend] move Serializer to helpers +- [frontend] fix coding style and py3 compatibility +- [cli] fix coding style and py3 compatibility +- [backend] fix coding style and py3 compatibility + +* Tue Jan 28 2014 Miroslav Suchý <miroslav@suchy.cz> 1.26-1 +- lower testing date +- move localized_time into filters +- [frontend] update user data after login +- [frontend] use iso-8601 date + +* Mon Jan 27 2014 Miroslav Suchý <msuchy@redhat.com> 1.25-1 +- 1044085 - move timezone modification out of template and make it actually + work +- clean up temp data if any +- [db] timezone can be nullable +- [frontend] actually save the timezone to model +- fix colision of revision id +- 1044085 - frontend: display time in user timezone +- [frontend] rebuild stuck task +- disable test on i386 +- use experimental createrepo_c to get rid of lock on temp files +- [frontend] - do not throw ISE when build_id is malformed +- [tests] add test for BuildLogic.add +- [tests] add test for build resubmission +- [frontend] permission checking is done in BuildLogic.add +- [frontend] remove BuildLogic.new, use BL.add only +- [api] fix validation error handling +- [cli] fix initial_pkgs and repos not sent to backend +- [frontend] fix BuildsLogic.new not assigning copr to build +- [frontend] allow resubmitting builds from monitor +- [frontend] allow GET on repeat_build +- [frontend] 1050904 - monitor shows not submitted chroots +- [frontend] rename active_mock_chroots to active_chroots +- [frontend] rename MockChroot.chroot_name to .name +- [frontend] 1054474 - drop Copr.build_count nonsense +- [tests] fix https and repo generation +- [tests] return exit code from manage.py test +- 1054472 - Fix deleting multiple SRPMs +- [spec] tighten acl on copr-be.conf +- [backend] - add missing import +- 1054082 - general: encode to utf8 if err in mimetext +- [backend] lock log file before writing +- 1055594 - mockremote: always unquote pkg url +- 1054086 - change vendor tag +- mockremote: rawhide instead of $releasever in repos when in rawhide chroot +- 1055499 - do not replace version with $releasever on rawhide +- 1055119 - do not propagate https until it is properly signed +- fix spellings on chroot edit page +- 1054341 - be more verbose about allowed licenses +- 1054594 - temporary disable https in repo file + +* Thu Jan 16 2014 Miroslav Suchý <msuchy@redhat.com> 1.24-1 +- add BR python-markdown +- [fronted] don't add description to .repo files +- [spec] fix with_tests conditional +- add build deletion +- 1044158 - do not require fas username prior to login +- replace http with https in copr-cli and in generated repo file +- [cli] UX changes - explicitly state that pkgs is URL +- 1053142 - only build copr-cli on el6 +- [frontend] correctly handle mangled chroot +- [frontend] do not traceback when user malform url +- [frontend] change default description and instructions to sound more + dangerously +- 1052075 - do not set chroots on repeated build +- 1052071 - do not throw ISE when copr does not exist + +* Mon Jan 13 2014 Miroslav Suchý <msuchy@redhat.com> 1.23-1 +- [backend] rhel7-beta do not have comps +- 1052073 - correctly parse malformed chroot + +* Fri Jan 10 2014 Miroslav Suchý <msuchy@redhat.com> 1.22-1 +- [backend] if we could not spawn VM, wait a moment and try again +- [backend] use createrepo_c instead of createrepo +- 1050952 - check if copr_url exist in config +- [frontend] replace newlines in description by space in repo file + +* Wed Jan 08 2014 Miroslav Suchý <msuchy@redhat.com> 1.21-1 +- 1049460 - correct error message +- [cron] manually clean /var/tmp after createrepo + +* Wed Jan 08 2014 Miroslav Suchý <msuchy@redhat.com> 1.20-1 +- [cli] no need to set const with action=store_true +- [cli] code cleanup +- 1049460 - print nice error when projects does not exist +- 1049392 - require python-setuptools +- [backend] add --verbose to log to stderr +- [backend] handle KeyboardInterrupt without tons of tracebacks +- 1048508 - fix links at projects lists +- [backend] in case of error the output is in e.output +- [selinux] allow httpd to search +- [backend] set number of worker in name of process +- [logrotate] rotate every week unconditionally +- [backend] do not traceback if jobfile is mangled +- [backend] print error messages to stderr +- [cli] do not require additional arguments for --nowait +- [backend] replace procname with setproctitle +- [cli] use copr.fedoraproject.org as default url +- [frontend] show monitor even if last build have been canceled +- [backend] call correct function +- [cli] print errors to stderr +- 1044136 - do not print TB if config in mangled +- 1044165 - Provide login and token information in the same form as entered to + ~/.config-copr +- [frontend] code cleanup +- [frontend] move rendering of .repo file to helpers +- 1043649 - in case of Fedora use $releasever in repo file +- [frontend] condition should be in reverse + +* Mon Dec 16 2013 Miroslav Suchý <msuchy@redhat.com> 1.19-1 +- [backend] log real cause if ansible crash +- [frontend] try again if whoosh does not get lock +- [backend] if frontend does not respond, repeat +- print yum repos nicely +- Bump the copr-cli release to 0.2.0 with all the changes made +- Refer to the man page for more information about the configuration file for + copr-cli +- Rework the layout of the list command +- Fix parsing the copr_url from the configuration file +- [backend] run createrepo as copr user +- 1040615 - wrap lines with long URL + +* Wed Dec 11 2013 Miroslav Suchý <msuchy@redhat.com> 1.18-1 +- [frontend] inicialize variable + +* Wed Dec 11 2013 Miroslav Suchý <msuchy@redhat.com> 1.17-1 +- [frontend] fix latest build variable overwrite + +* Wed Dec 11 2013 Miroslav Suchý <msuchy@redhat.com> 1.16-1 +- [backend] store jobs in id-chroot.json file +- [frontend] handle unknown build/chroot status +- use newstyle ansible variables + +* Tue Dec 10 2013 Miroslav Suchý <msuchy@redhat.com> 1.15-1 +- [frontend] smarter package name parsing +- [frontend] extend range to allow 0 +- handle default timeout on backend +- initial support for SCL +- [backend] create word readable files in result directory +- [backend] print tracebacks +- [frontend] monitor: display only pkg name w/o version +- [doc] update api docs +- [doc] update copr-cli manpage +- [cli] list only name, description and instructions +- [cli] add support for build status & build monitor +- [frontend] add build status to API +- [playbook] do not overwrite mockchain +- [backend] add spece between options +- [backend] pass mock options correctly +- [frontend] support markdown in description and instructions +- [backend] Add macros to mockchain define arguments +- [backend] Pass copr username and project name to MockRemote +- [backend] Handle additional macro specification in MockRemote +- [frontend] monitor: show results per package +- [frontend] add favicon +- [backend] quote strings before passing to mockchain +- send chroots with via callback to frontend +- [cli] change cli to new api call +- enhance API documentation +- add yum_repos to coprs/user API call +- [frontend] provide link to description of allowed content +- [backend] we pass just one chroot +- [backend] - variable play is not defined +- if createrepo fail, run it again +- [cron] fix syntax error +- [man] state that --chroot for create command is required +- [spec] enable tests +- [howto] add note about upgrading db schema +- [frontend]: add copr monitor +- [tests]: replace test_allowed_one +- [tests]: fix for BuildChroots & new backend view +- [frontend] rewrite backend view to use Build <-> Chroot relation +- [frontend] add Build <-> Chroot relation +- 1030493 - [cli] check that at least one chroot is entered +- [frontend] typo +- fixup! [tests]: fix test_build_logic to handle BuildChroot +- fixup! [frontend] add ActionsLogic +- [tests]: fix test_build_logic to handle BuildChroot +- [spec] enable/disable test using variable +- add migration script - add table build_chroot +- [frontend] skip legal-flag actions when dumping waiting actions +- [frontend] rewrite backend view to use Build <-> Chroot relation +- [frontend] add ActionsLogic +- [frontend] create BuildChroot objects on new build +- [frontend] add Build <-> Chroot relation +- [frontend] add StatusEnum +- [frontend] fix name -> coprname typo +- [frontend] remove unused imports +- [frontend] add missing json import +- [backend] rework ip address extraction +- ownership of /etc/copr should be just normal +- [backend] - wrap up returning action in "action" blok +- [backend] rename backend api url +- [backend] handle "rename" action +- [backend] handle "delete" action +- base handling of actions +- move callback to frontend to separate object +- secure waiting_actions with password +- pick only individual builds +- make address, where we send legal flags, configurable +- send email to root after legal flag have been raised + +* Fri Nov 08 2013 Miroslav Suchý <msuchy@redhat.com> 1.14-1 +- 1028235 - add disclaimer about repos +- fix pagination +- fix one failing test + +* Wed Nov 06 2013 Miroslav Suchý <msuchy@redhat.com> 1.13-1 +- suggest correct name of repo file +- we could not use releasever macro +- no need to capitalize Projects +- another s/copr/project +- add link to header for sign-in +- fix failing tests +- UX - let textarea will full widht of box +- UX - make background of hovered builds darker +- generate yum repo for each chroot of copr +- align table header same way as ordinary rows +- enable resulting repo and disable gpgchecks + +* Mon Nov 04 2013 Miroslav Suchý <msuchy@redhat.com> 1.12-1 +- do not send parameters when we neither need them nor use them +- authenticate using api login, not using username +- disable editing name of project +- Add commented out WTF_CSRF_ENABLED = True to configs +- Use new session for each test +- fix test_coprs_general failures +- fix test_coprs_builds failures +- Add WTF_CSRF_ENABLED = False to unit test config +- PEP8 fixes +- Fix compatibility with wtforms 0.9 +- typo s/submited/submitted/ +- UX - show details of build only after click +- add link to FAQ to footer +- UX - add placeholders +- UX - add asterisk to required fields +- dynamicly generate url for home +- add footer + +* Sat Oct 26 2013 Miroslav Suchý <msuchy@redhat.com> 1.11-1 +- catch IOError from libravatar if there is no network + +* Fri Oct 25 2013 Miroslav Suchý <msuchy@redhat.com> 1.10-1 +- do not normalize url +- specify full prefix of http +- execute playbook using /usr/bin/ansible-playbook +- use ssh transport +- check after connection is made +- add notes about debuging mockremote +- clean up instance even when worker fails +- normalize paths before using +- do not use exception variable +- operator should be preceded and followed by space +- remove trailing whitespace +- convert comment to docstring +- use ssh transport +- do not create new ansible connection, reuse self.conn +- run copr-be.py as copr +- s/Copr/Project/ where we use copr in meaning of projects +- number will link to those coprs, to which it refers +- run log and jobgrab as copr user +- log event to log file +- convert comment into docstring +- use unbufferred output for copr-be.py +- hint how to set ec2 variables +- document sleeptime +- document copr_url for copr-cli +- document how to set api key for copr-cli +- do not create list of list +- document SECRET_KEY variable +- make note how to become admin +- instruct people to install selinux with frontend + +* Thu Oct 03 2013 Miroslav Suchý <msuchy@redhat.com> 1.9-1 +- prune old builds +- require python-decorator +- remove requirements.txt +- move TODO-backend to our wiki +- create pid file in /var/run/copr-backend +- add backend service file for systemd +- remove daemonize option in config +- use python logging +- create pid file in /var/run by default +- do not create destdir +- use daemon module instead of home brew function +- fix default location of copr-be.conf +- 2 tests fixed, one still failing +- fix failing test test_fail_on_missing_dash +- fixing test_fail_on_nonexistent_copr test +- run frontend unit tests when building package +- Adjust URLs in the unit-tests to their new structure +- Adjust the CLI to call the adjuste endpoint of the API +- Adjust API endpoint to reflects the UI endpoints in their url structure +- First pass at adding fedmsg hooks. + +* Tue Sep 24 2013 Miroslav Suchý <msuchy@redhat.com> 1.8-1 +- 1008532 - require python2-devel +- add note about ssh keys to copr-setup.txt +- set home of copr user to system default + +* Mon Sep 23 2013 Miroslav Suchý <msuchy@redhat.com> 1.7-1 +- 1008532 - backend should own _pkgdocdir +- 1008532 - backend should owns /etc/copr as well +- 1008532 - require logrotate +- 1008532 - do not distribute empty copr.if +- 1008532 - use %%{?_smp_mflags} macro with make +- move jobsdir to /var/lib/copr/jobs +- correct playbooks path +- selinux with enforce can be used for frontend + +* Wed Sep 18 2013 Miroslav Suchý <msuchy@redhat.com> 1.6-1 +- add BR python-devel +- generate selinux type for /var/lib/copr and /var/log/copr +- clean up backend setup instructions +- initial selinux subpackage + +* Mon Sep 16 2013 Miroslav Suchý <msuchy@redhat.com> 1.5-1 +- 1008532 - use __python2 instead of __python +- 1008532 - do not mark man page as doc +- 1008532 - preserve timestamp + +* Mon Sep 16 2013 Miroslav Suchý <msuchy@redhat.com> 1.4-1 +- add logrotate file + +* Mon Sep 16 2013 Miroslav Suchý <msuchy@redhat.com> 1.3-1 +- be clear how we create tgz + +* Mon Sep 16 2013 Miroslav Suchý <msuchy@redhat.com> 1.2-1 +- fix typo +- move frontend data into /var/lib/copr +- no need to own /usr/share/copr by copr-fe +- mark application as executable +- coprs_frontend does not need to be owned by copr-fe +- add executable attribute to copr-be.py +- remove shebang from dispatcher.py +- squeeze description into 80 chars +- fix typo +- frontend need argparse too +- move results into /var/lib/copr/public_html +- name of dir is just copr-%%version +- Remove un-necessary quote that breaks the tests +- Adjust unit-tests to the new urls +- Update the URL to be based upon a /user/copr/<action> structure +- comment config copr-be.conf and add defaults +- put examples of builderpb.yml and terminatepb.yml into doc dir +- more detailed description of copr-be.conf +- move files in config directory not directory itself +- include copr-be.conf +- include copr-be.py +- create copr with lighttpd group +- edit backend part of copr-setup.txt +- remove fedora16 and add 19 and 20 +- create -doc subpackage with python documentation +- add generated documentation on gitignore list +- add script to generate python documentation +- copr-setup.txt change to for mock +- rhel6 do not know _pkgdocdir macro +- make instruction clear +- require recent whoosh +- add support for libravatar +- include backend in rpm +- add notes about lighttpd config files and how to deploy them +- do not list file twice +- move log file to /var/log +- change destdir in copr-be.conf.example +- lightweight is the word and buildsystem has more meaning than 'koji'. +- restart apache after upgrade of frontend +- own directory where backend put results +- removal of hidden-file-or-dir + /usr/share/copr/coprs_frontend/coprs/logic/.coprs_logic.py.swo +- copr-backend.noarch: W: spelling-error %%description -l en_US latests -> + latest, latest's, la tests +- simplify configuration - introduce /etc/copr/copr*.conf +- Replace "with" statements with @TransactionDecorator decorator +- add python-flexmock to deps of frontend +- remove sentence which does not have meaning +- change api token expiration to 120 days and make it configurable +- create_chroot must be run as copr-fe user +- add note that you have to add chroots to db +- mark config.py as config so it is not overwritten during upgrade +- own directory data/whooshee/copr_user_whoosheer +- gcc is not needed +- sqlite db must be owned by copr-fe user +- copr does not work with selinux +- create subdirs under data/openid_store +- suggest to install frontend as package from copr repository +- on el6 add python-argparse to BR +- add python-requests to BR +- add python-setuptools to BR +- maintain apache configuration on one place only +- apache 2.4 changed access control +- require python-psycopg2 +- postgresql server is not needed +- document how to create db +- add to HOWTO how to create db +- require python-alembic +- add python-flask-script and python-flask-whooshee to requirements +- change user in coprs.conf.example to copr-fe +- fix paths in coprs.conf.example +- copr is noarch package +- add note where to configure frontend +- move frontend to /usr/share/copr/coprs_frontend +- put production placeholders in coprs_frontend/coprs/config.py +- put frontend into copr.spec +- web application should be put in /usr/share/%%{name} + +* Mon Jun 17 2013 Miroslav Suchý <msuchy@redhat.com> 1.1-1 +- new package built with tito diff --git a/euler_msgbus.patch b/euler_msgbus.patch deleted file mode 100644 index 5eca90a..0000000 --- a/euler_msgbus.patch +++ /dev/null @@ -1,83 +0,0 @@ -diff --git a/copr_backend/euler_msgbus.py b/copr_backend/euler_msgbus.py -new file mode 100644 -index 000000000..1395249be ---- /dev/null -+++ b/copr_backend/euler_msgbus.py -@@ -0,0 +1,77 @@ -+import socket -+ -+from kafka import KafkaProducer -+import os -+import datetime -+import uuid -+import json -+import ssl -+ -+ -+def message_from_worker_job(topic, job, who, ip, pid): -+ message = {} -+ content = { -+ 'user': job.submitter, -+ 'copr': job.project_name, -+ 'owner': job.project_owner, -+ 'pkg': job.package_name, -+ 'build': job.build_id, -+ 'chroot': job.chroot, -+ 'version': job.package_version, -+ 'status': job.status, -+ } -+ content.update({'ip': ip, 'who': who, 'pid': pid}) -+ message_types = { -+ 'build.start': { -+ 'what': "build start: user:{user} copr:{copr}" \ -+ " pkg:{pkg} build:{build} ip:{ip} pid:{pid}", -+ }, -+ 'chroot.start': { -+ 'what': "chroot start: chroot:{chroot} user:{user}" \ -+ " copr:{copr} pkg:{pkg} build:{build} ip:{ip} pid:{pid}", -+ }, -+ 'build.end': { -+ 'what': "build end: user:{user} copr:{copr} build:{build}" \ -+ " pkg:{pkg} version:{version} ip:{ip} pid:{pid} status:{status}", -+ }, -+ } -+ content['what'] = message_types[topic]['what'].format(**content) -+ message['body'] = content -+ now = datetime.datetime.now().isoformat() -+ headers = { -+ "openEuler_messaging_schema": "eur." + topic, -+ "sent-at": now, -+ } -+ message['headers'] = headers -+ message['id'] = str(uuid.uuid4()) -+ message['topic'] = "org.openEuler.prod.eur." + topic -+ return message -+ -+ -+class MessageSender: -+ def __init__(self, backend_opts, name, log): -+ self.log = log -+ self.name = name -+ self.pid = os.getpid() -+ self.opts = backend_opts -+ -+ def announce(self, topic, job, host): -+ msg = message_from_worker_job(topic, job, self.name, host, self.pid) -+ self.send_message(msg) -+ -+ def send_message(self, msg): -+ """ Send message to kafka """ -+ -+ context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) -+ context.verify_mode = ssl.CERT_REQUIRED -+ context.load_verify_locations("etc/copr/kafka.crt") -+ producer = KafkaProducer(bootstrap_servers=self.opts.message.bootstrap_servers, -+ api_version=(3, 5, 0), -+ sasl_mechanism="PLAIN", -+ ssl_context=context, -+ security_protocol='SASL_SSL', -+ sasl_plain_username=self.opts.message.user_name, -+ sasl_plain_password=self.opts.message.password, -+ value_serializer=lambda v: json.dumps(v).encode('utf-8')) -+ producer.send(str(self.opts.message.topic), msg) -+ producer.flush() diff --git a/fail_to_build_in_oe2403.patch b/fail_to_build_in_oe2403.patch deleted file mode 100644 index be32aee..0000000 --- a/fail_to_build_in_oe2403.patch +++ /dev/null @@ -1,14 +0,0 @@ -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/signatrust_bin.patch b/signatrust_bin.patch deleted file mode 100644 index fcba220..0000000 --- a/signatrust_bin.patch +++ /dev/null @@ -1,105 +0,0 @@ -diff --git a/run/copr_fix_gpg.py b/run/copr_fix_gpg.py -index 24edf74e..bfa70c05 100755 ---- a/run/copr_fix_gpg.py -+++ b/run/copr_fix_gpg.py -@@ -9,7 +9,7 @@ from urllib.parse import urlparse - import pwd - - from copr_backend.helpers import BackendConfigReader, call_copr_repo, run_cmd --from copr_backend.sign import get_pubkey, unsign_rpms_in_dir, sign_rpms_in_dir, create_user_keys, create_gpg_email -+from copr_backend.sign import new_signer, create_gpg_email - - logging.basicConfig( - filename="/var/log/copr-backend/fix_gpg.log", -@@ -69,12 +69,14 @@ def fix_copr(args, opts, copr_full_name): - log.info('Ignoring %s. Directory does not exist.', copr_path) - return - -+ signer = new_signer(opts) -+ - log.info("Generate key-pair on copr-keygen (if not generated) for email %s", - create_gpg_email(owner, coprname, opts.sign_domain)) -- create_user_keys(owner, coprname, opts) -+ signer.create_user_keys(owner, coprname, opts) - - log.info("Regenerate pubkey.gpg in copr %s", copr_path) -- get_pubkey(owner, coprname, log, opts.sign_domain, os.path.join(copr_path, 'pubkey.gpg')) -+ signer.get_pubkey(owner, coprname, log, opts.sign_domain, os.path.join(copr_path, 'pubkey.gpg')) - - # Match the "00001231-anycharacer" directory names. Compile once, use many. - builddir_matcher = re.compile(r"\d{8,}-") -@@ -111,8 +113,8 @@ def fix_copr(args, opts, copr_full_name): - - log.info("Processing rpms in builddir %s", builddir_path) - try: -- unsign_rpms_in_dir(builddir_path, opts, log) # first we need to unsign by using rpm-sign before we sign with obs-sign -- sign_rpms_in_dir(owner, coprname, builddir_path, chroot, opts, log) -+ signer.unsign_rpms_in_dir(builddir_path, opts, log) # first we need to unsign by using rpm-sign before we sign with obs-sign -+ signer.sign_rpms_in_dir(owner, coprname, builddir_path, chroot, opts, log) - except Exception as e: - log.exception(str(e)) - continue -diff --git a/run/copr_sign_unsigned.py b/run/copr_sign_unsigned.py -index 33eaeae3..e17e65bb 100755 ---- a/run/copr_sign_unsigned.py -+++ b/run/copr_sign_unsigned.py -@@ -12,7 +12,7 @@ import pwd - - from copr_backend.helpers import (BackendConfigReader, create_file_logger, - uses_devel_repo, call_copr_repo) --from copr_backend.sign import get_pubkey, sign_rpms_in_dir, create_user_keys -+from copr_backend.sign import new_signer - from copr_backend.exceptions import CoprSignNoKeyError - - -@@ -26,10 +26,11 @@ log = logging.getLogger(__name__) - def check_signed_rpms_in_pkg_dir(pkg_dir, user, project, opts, chroot_dir, devel): - success = True - -+ signer = new_signer(opts) - logger = create_file_logger("run.check_signed_rpms_in_pkg_dir", - "/tmp/copr_check_signed_rpms.log") - try: -- sign_rpms_in_dir(user, project, pkg_dir, chroot_dir, opts, log=logger) -+ signer.sign_rpms_in_dir(user, project, pkg_dir, chroot_dir, opts, log=logger) - log.info("running createrepo for %s", pkg_dir) - call_copr_repo(directory=chroot_dir, devel=devel, logger=log) - except Exception as err: -@@ -80,9 +81,10 @@ def check_pubkey(pubkey_path, user, project, opts): - log.info("Pubkey for %s/%s exists: %s", user, project, pubkey_path) - return True - else: -+ signer = new_signer(opts) - log.info("Missing pubkey for %s/%s", user, project) - try: -- get_pubkey(user, project, log, opts.sign_domain, pubkey_path) -+ signer.get_pubkey(user, project, log, opts.sign_domain, pubkey_path) - return True - except Exception as err: - log.exception(err) -@@ -102,6 +104,8 @@ def main(): - opts = BackendConfigReader().read() - log.info("Starting pubkey fill, destdir: %s", opts.destdir) - -+ signer = new_signer(opts) -+ - log.debug("list dir: %s", os.listdir(opts.destdir)) - for user_name in os.listdir(opts.destdir): - if user_name in users_done_old: -@@ -116,13 +120,13 @@ def main(): - log.info("Checking project dir: %s", project_name) - - try: -- get_pubkey(user_name, project_name, log, opts.sign_domain) -+ signer.get_pubkey(user_name, project_name, log, opts.sign_domain) - log.info("Key-pair exists for %s/%s", user_name, project_name) - except CoprSignNoKeyError: -- create_user_keys(user_name, project_name, opts) -+ signer.create_user_keys(user_name, project_name, opts) - log.info("Created new key-pair for %s/%s", user_name, project_name) - except Exception as err: -- log.error("Failed to get pubkey for {}/{}, mark as failed, skipping") -+ log.error("Failed to get pubkey for {}/{}, mark as failed, skipping".format(user_name, project_name)) - log.exception(err) - failed = True - continue @@ -1,2 +1,2 @@ -25ff25e926c351d188a38b843a7d898a copr-backend-1.177.tar.gz -c94d55e21a4935b3e62f673fbae65af2 test-data-copr-backend-5.tar.gz +8dacd18f46475296d0199365db977649 copr-backend-1.168.tar.gz +a35697a68640fb4c0bcfef02a93eac63 test-data-copr-backend-2.tar.gz diff --git a/support_signatrust_backend.patch b/support_signatrust_backend.patch deleted file mode 100644 index adcbf1e..0000000 --- a/support_signatrust_backend.patch +++ /dev/null @@ -1,953 +0,0 @@ -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" - DEF_DESTDIR = os.getcwd() - DEF_MACROS = {} - DEF_BUILDROOT_PKGS = "" -+DEF_SIGN_BACKEND = "obs-signd" - - - DEF_CONSECUTIVE_FAILURE_THRESHOLD = 10 -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): - - def __str__(self): - out = super(CoprKeygenRequestError, self).__str__() -- out += "\nrequest to copr-keygen: {}\n".format(self.request) -- if self.response: -+ out += "\nrequest to key_backend: {}\n".format(self.request) -+ if self.response is not None: - 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/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 - from copr_common.redis_helpers import get_redis_connection - from copr.v3 import Client - 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 - - from . import constants -@@ -309,6 +309,18 @@ class BackendConfigReader(object): - opts.sign_domain = _get_conf( - cp, "backend", "sign_domain", DOMAIN) - -+ opts.sign_backend = _get_conf( -+ cp, "backend", "sign_backend", DEF_SIGN_BACKEND) -+ -+ opts.signatrust_host = _get_conf( -+ cp, "backend", "signatrust_host", "") -+ -+ opts.signatrust_token = _get_conf( -+ cp, "backend", "signatrust_token", "") -+ -+ opts.signatrust_key_expire = _get_conf( -+ cp, "backend", "signatrust_key_expire", 1825, mode="int") -+ - 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/backend/copr_backend/sign.py -index e21653e78..599d209ee 100644 ---- a/copr_backend/sign.py -+++ b/copr_backend/sign.py -@@ -7,17 +7,16 @@ Wrapper for /bin/sign from obs-sign package - from subprocess import Popen, PIPE, SubprocessError - import os - import time -+import functools - - from packaging import version - - from copr_common.request import SafeRequest --from copr_backend.helpers import get_redis_logger -+from copr_backend.helpers import get_redis_logger, get_backend_opts - 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,77 +24,17 @@ def create_gpg_email(username, projectname, domain): - - return "{}#{}@copr.{}".format(username, projectname, domain) - -- - def call_sign_bin(cmd, log): -- """ -- Call /bin/sign and return (rc, stdout, stderr). Re-try the call -- automatically upon certain failures (if that makes sense). -- """ -- cmd_pretty = ' '.join(cmd) -- for attempt in [1, 2, 3]: -- log.info("Calling '%s' (attempt #%s)", cmd_pretty, attempt) -- try: -- handle = Popen(cmd, stdout=PIPE, stderr=PIPE, encoding="utf-8") -- stdout, stderr = handle.communicate() -- except (SubprocessError, OSError) as err: -- new_err = CoprSignError("Failed to invoke '{}'".format(cmd_pretty)) -- raise new_err from err -- -- if handle.returncode != 0: -- log.warning("Command '%s' failed with: %s", -- cmd_pretty, stderr.rstrip()) -- sleeptime = 20 -- log.warning("Going to sleep %ss and re-try.", sleeptime) -- time.sleep(sleeptime) -- continue -- break -- return handle.returncode, stdout, stderr -- -+ signer = new_signer() -+ return signer.call_sign_bin(cmd, log) - - def get_pubkey(username, projectname, log, sign_domain, outfile=None): -- """ -- Retrieves public key for user/project from signer host. -- -- :param sign_domain: the domain name of the sign key -- :param outfile: [optional] file to write obtained key -- :return: public keys -- -- :raises CoprSignError: failed to retrieve key, see error message -- :raises CoprSignNoKeyError: if there are no such user in keyring -- """ -- usermail = create_gpg_email(username, projectname, sign_domain) -- cmd = [SIGN_BINARY, "-u", usermail, "-p"] -- -- returncode, stdout, stderr = call_sign_bin(cmd, log) -- if returncode != 0: -- if "unknown key:" in stderr: -- raise CoprSignNoKeyError( -- "There are no gpg keys for user {} in keyring".format(username), -- return_code=returncode, -- cmd=cmd, stdout=stdout, stderr=stderr) -- raise CoprSignError( -- msg="Failed to get user pubkey\n" -- "sign stdout: {}\n sign stderr: {}\n".format(stdout, stderr), -- return_code=returncode, -- cmd=cmd, stdout=stdout, stderr=stderr) -- -- if outfile: -- with open(outfile, "w") as handle: -- handle.write(stdout) -- -- return stdout -- -+ signer = new_signer() -+ return signer.get_pubkey(username, projectname, log, sign_domain, outfile) - - def _sign_one(path, email, hashtype, log): -- cmd = [SIGN_BINARY, "-4", "-h", hashtype, "-u", email, "-r", path] -- returncode, stdout, stderr = call_sign_bin(cmd, log) -- if returncode != 0: -- raise CoprSignError( -- msg="Failed to sign {} by user {}".format(path, email), -- return_code=returncode, -- cmd=cmd, stdout=stdout, stderr=stderr) -- return stdout, stderr -- -+ signer = new_signer() -+ return signer._sign_one(path, email, hashtype, log) - - def gpg_hashtype_for_chroot(chroot, opts): - """ -@@ -135,134 +74,455 @@ def gpg_hashtype_for_chroot(chroot, opts): - # fallback to sha256 - return "sha256" - -- - def sign_rpms_in_dir(username, projectname, path, chroot, opts, log): -- """ -- Signs rpms using obs-signd. -+ signer = new_signer() -+ return signer.sign_rpms_in_dir(username, projectname, path, chroot, opts, log) - -- If some some pkgs failed to sign, entire build marked as failed, -- but we continue to try sign other pkgs. -- -- :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 -+def create_user_keys(username, projectname, opts, try_indefinitely=False): -+ signer = new_signer() -+ return signer.create_user_keys(username, projectname, opts, try_indefinitely) - -- :type log: logging.Logger -+def _unsign_one(path): -+ signer = new_signer() -+ return signer._unsign_one(path) - -- :raises: :py:class:`backend.exceptions.CoprSignError` failed to sign at least one package -- """ -+def unsign_rpms_in_dir(path, opts, log): -+ signer = new_signer() -+ return signer.unsign_rpms_in_dir(path, opts, log) -+ -+ -+# a sign interface -+class Signer(object): -+ @classmethod -+ def get_pubkey(cls, username, projectname, log, sign_domain, outfile=None): -+ """get public key""" -+ raise NotImplementedError -+ -+ @classmethod -+ def sign_rpms_in_dir(cls, username, projectname, path, chroot, opts, log): -+ """batch sign rpms""" -+ raise NotImplementedError -+ -+ @classmethod -+ def create_user_keys(username, projectname, opts, try_indefinitely=False): -+ """create user key pair""" -+ raise NotImplementedError -+ -+ @classmethod -+ def _sign_one(cls, path, email, hashtype, log): -+ """sign one rpm""" -+ raise NotImplementedError -+ -+ @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() - -- rpm_list = [ -- os.path.join(path, filename) -- for filename in os.listdir(path) -- if filename.endswith(".rpm") -- ] -+ if handle.returncode != 0: -+ err = CoprSignError( -+ msg="Failed to unsign {}".format(path), -+ return_code=handle.returncode, -+ cmd=cmd, stdout=stdout, stderr=stderr) - -- if not rpm_list: -- return -+ raise err -+ -+ return stdout, stderr -+ -+ @classmethod -+ def call_sign_bin(cls, cmd, log): -+ """ -+ Call sign_cmd and return (rc, stdout, stderr). Re-try the call -+ automatically upon certain failures (if that makes sense). -+ """ -+ cmd_pretty = ' '.join(cmd) -+ for attempt in [1, 2, 3]: -+ log.info("Calling '%s' (attempt #%s)", cmd_pretty, attempt) -+ try: -+ handle = Popen(cmd, stdout=PIPE, stderr=PIPE, encoding="utf-8") -+ stdout, stderr = handle.communicate() -+ except (SubprocessError, OSError) as err: -+ new_err = CoprSignError("Failed to invoke '{}'".format(cmd_pretty)) -+ raise new_err from err -+ -+ if handle.returncode != 0: -+ log.warning("Command '%s' failed with: %s", -+ cmd_pretty, stderr.rstrip()) -+ sleeptime = 20 -+ log.warning("Going to sleep %ss and re-try.", sleeptime) -+ time.sleep(sleeptime) -+ continue -+ break -+ return handle.returncode, stdout, stderr -+ -+ @classmethod -+ def sign_rpms_in_dir(cls, 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. -+ -+ :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 -+ -+ :type log: logging.Logger -+ -+ :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) -+ 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) -+ hashtype = gpg_hashtype_for_chroot(chroot, opts) - -- errors = [] # tuples (rpm_filepath, exception) -- for rpm in rpm_list: - try: -- _sign_one(rpm, create_gpg_email(username, projectname, opts.sign_domain), -- hashtype, log) -- log.info("signed rpm: %s", rpm) -- -- except CoprSignError as e: -- log.exception("failed to sign rpm: %s", rpm) -- errors.append((rpm, e)) -- -- if errors: -- raise CoprSignError("Rpm sign failed, affected rpms: {}" -- .format([err[0] for err in errors])) -- -- --def create_user_keys(username, projectname, opts, try_indefinitely=False): -- """ -- Generate a new key-pair at sign host -+ cls.get_pubkey(username, projectname, log, opts.sign_domain) -+ except CoprSignNoKeyError: -+ cls.create_user_keys(username, projectname, opts, try_indefinitely=True) -+ -+ errors = [] # tuples (rpm_filepath, exception) -+ for rpm in rpm_list: -+ try: -+ cls._sign_one(rpm, create_gpg_email(username, projectname, opts.sign_domain), -+ hashtype, log) -+ log.info("signed rpm: %s", rpm) -+ -+ except CoprSignError as e: -+ log.exception("failed to sign rpm: %s", rpm) -+ errors.append((rpm, e)) -+ -+ if errors: -+ raise CoprSignError("Rpm sign failed, affected rpms: {}" -+ .format([err[0] for err in errors])) -+ -+ @classmethod -+ def unsign_rpms_in_dir(cls, path, opts, log): -+ """ -+ :param path: directory with rpms to be signed -+ :param Munch opts: backend config -+ :type log: logging.Logger -+ :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") -+ ] -+ -+ if not rpm_list: -+ return -+ -+ errors = [] # tuples (rpm_filepath, exception) -+ for rpm in rpm_list: -+ try: -+ cls._unsign_one(rpm) -+ log.info("unsigned rpm: %s", rpm) -+ -+ except CoprSignError as e: -+ log.exception("failed to unsign rpm: %s", rpm) -+ errors.append((rpm, e)) -+ -+ if errors: -+ raise CoprSignError("Rpm unsign failed, affected rpms: {}" -+ .format([err[0] for err in errors])) -+ -+@functools.lru_cache(maxsize=1) -+def new_signer(): -+ opts = get_backend_opts() -+ if hasattr(opts, "sign_backend") and opts.sign_backend == "signatrust": -+ Signatrust.signatrust_token = opts.signatrust_token -+ Signatrust.signatrust_host = opts.signatrust_host -+ return Signatrust -+ else: # keep obs-signd as default backend -+ return ObsSign -+ -+class ObsSign(Signer): -+ sign_cmd = "/bin/sign" -+ -+ @classmethod -+ def get_pubkey(cls, username, projectname, log, sign_domain, outfile=None): -+ """ -+ Retrieves public key for user/project from signer host. -+ -+ :param sign_domain: the domain name of the sign key -+ :param outfile: [optional] file to write obtained key -+ :return: public keys -+ -+ :raises CoprSignError: failed to retrieve key, see error message -+ :raises CoprSignNoKeyError: if there are no such user in keyring -+ """ -+ usermail = create_gpg_email(username, projectname, sign_domain) -+ cmd = [cls.sign_cmd, "-u", usermail, "-p"] -+ -+ returncode, stdout, stderr = cls.call_sign_bin(cmd, log) -+ if returncode != 0: -+ if "unknown key:" in stderr: -+ raise CoprSignNoKeyError( -+ "There are no gpg keys for user {} in keyring".format(username), -+ return_code=returncode, -+ cmd=cmd, stdout=stdout, stderr=stderr) -+ raise CoprSignError( -+ msg="Failed to get user pubkey\n" -+ "sign stdout: {}\n sign stderr: {}\n".format(stdout, stderr), -+ return_code=returncode, -+ cmd=cmd, stdout=stdout, stderr=stderr) - -- :param username: -- :param projectname: -- :param opts: backend config -+ if outfile: -+ with open(outfile, "w") as handle: -+ handle.write(stdout) - -- :return: None -- """ -- data = { -- "name_real": "{}_{}".format(username, projectname), -- "name_email": create_gpg_email(username, projectname, opts.sign_domain) -- } -- -- log = get_redis_logger(opts, "sign", "actions") -- keygen_url = "http://{}/gen_key".format(opts.keygen_host) -- query = dict(url=keygen_url, data=data, method="post") -- try: -- request = SafeRequest(log=log, try_indefinitely=try_indefinitely) -- response = request.send(**query) -- except Exception as e: -- raise CoprKeygenRequestError( -- msg="Failed to create key-pair for user: {}," -- " project:{} with error: {}" -- .format(username, projectname, e), request=query) -- -- if response.status_code >= 400: -- raise CoprKeygenRequestError( -- msg="Failed to create key-pair for user: {}, project:{}, status_code: {}, response: {}" -- .format(username, projectname, response.status_code, response.text), -- request=query, response=response) -+ return stdout - -+ @classmethod -+ def _sign_one(cls, path, email, hashtype, log): -+ cmd = [cls.sign_cmd, "-4", "-h", hashtype, "-u", email, "-r", path] -+ returncode, stdout, stderr = cls.call_sign_bin(cmd, log) -+ if returncode != 0: -+ raise CoprSignError( -+ msg="Failed to sign {} by user {}".format(path, email), -+ return_code=returncode, -+ cmd=cmd, stdout=stdout, stderr=stderr) -+ return stdout, stderr -+ -+ @classmethod -+ def create_user_keys(cls, username, projectname, opts, try_indefinitely=False): -+ """ -+ Generate a new key-pair at sign host -+ -+ :param username: -+ :param projectname: -+ :param opts: backend config -+ -+ :return: None -+ """ -+ data = { -+ "name_real": "{}_{}".format(username, projectname), -+ "name_email": create_gpg_email(username, projectname, opts.sign_domain) -+ } -+ -+ log = get_redis_logger(opts, "sign", "actions") -+ keygen_url = "http://{}/gen_key".format(opts.keygen_host) -+ query = dict(url=keygen_url, data=data, method="post") -+ try: -+ request = SafeRequest(log=log, try_indefinitely=try_indefinitely) -+ response = request.send(**query) -+ except Exception as e: -+ raise CoprKeygenRequestError( -+ msg="Failed to create key-pair for user: {}," -+ " project:{} with error: {}" -+ .format(username, projectname, e), request=query) -+ -+ if response.status_code >= 400: -+ raise CoprKeygenRequestError( -+ msg="Failed to create key-pair for user: {}, project:{}, status_code: {}, response: {}" -+ .format(username, projectname, response.status_code, response.text), -+ request=query, response=response) -+ -+class Signatrust(Signer): -+ sign_cmd = "/usr/local/bin/client" -+ prefix = "" -+ signatrust_host = "" -+ signatrust_token = "" -+ -+ @classmethod -+ def get_prefix(cls): -+ """ -+ Get prefix of the user -+ -+ As in copr, we set key attr with visibility=private -+ These keys' name were prefixed by user's email like: -+ tommylikehu@gmail.com:mywaaagh_admin_test -+ """ -+ headers = { -+ "accept": "application/json", -+ "Authorization": cls.signatrust_token -+ } -+ try: -+ r = requests.get("{}/api/v1/users/info".format(cls.signatrust_host), headers=headers).json() -+ cls.prefix = r.get("email") -+ except Exception as e: -+ raise CoprKeygenRequestError( -+ msg="Failed to get userinfo", request="/api/v1/users/info") -+ -+ @classmethod -+ def get_key_name(cls, username, projectname, prefix=True): -+ """ -+ copr key_name rule in signatrust: -+ <user prefix>:<user_name>_<project_name> -+ """ -+ if not cls.prefix: -+ cls.get_prefix() -+ if prefix: -+ return "{}:{}_{}".format(cls.prefix, username, projectname) -+ return "{}_{}".format(username, projectname) -+ -+ @classmethod -+ def get_pubkey(cls, username, projectname, log, sign_domain, outfile=None): -+ """ -+ get public key -+ -+ https://domain:port/api/v1/keys/<key_name>/public_key -+ """ -+ if not cls.prefix: -+ cls.get_prefix() -+ -+ headers = { -+ "accept": "application/json", -+ "Authorization": cls.signatrust_token -+ } -+ -+ key_name = cls.get_key_name(username, projectname) -+ url = "{}/api/v1/keys/{}/public_key".format(cls.signatrust_host, key_name) -+ try: -+ r = requests.get(url, headers=headers) -+ except Exception as e: -+ raise CoprKeygenRequestError( -+ msg="Failed to get public_key", request="/api/v1/keys/{}/public_key".format(key_name), response=r) - --def _unsign_one(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() -+ if r.status_code == 404: -+ raise CoprSignNoKeyError( -+ "There are no gpg keys for user {} in keyring".format(username), -+ return_code=r.status_code, -+ cmd="GET {}".format(url), stdout="", stderr="") -+ elif r.status_code >= 400: -+ raise CoprKeygenRequestError( -+ msg="Failed to get user pubkey\n", -+ request="/api/v1/keys/{}/public_key".format(key_name), response=r) -+ -+ if outfile: -+ with open(outfile, "wb") as handle: -+ handle.write(r.content) -+ -+ return r.content -+ -+ @classmethod -+ def sign_rpms_in_dir(cls, username, projectname, path, chroot, opts, log): -+ """batch sign rpms""" -+ if not cls.prefix: -+ cls.get_prefix() -+ -+ if not cls._key_existed(username, projectname, opts): -+ cls.create_user_keys(username, projectname, opts) -+ -+ # when we migrate copr keys into signatrust -+ # we fellow the rules: -+ # key_name = <user_email>:<user_name>_<project_name> -+ cmd = [cls.sign_cmd, "-c", "/etc/signatrust.toml", "add", "--file-type", "rpm", "--key-type", "pgp", "--key-name", cls.get_key_name(username, projectname), path] -+ -+ returncode, stdout, stderr = cls.call_sign_bin(cmd, log) -+ if returncode != 0: -+ raise CoprSignError( -+ msg="Failed to sign rpms\n" -+ "sign stdout: {}\n sign stderr: {}\n".format(stdout, stderr), -+ return_code=returncode, -+ cmd=cmd, stdout=stdout, stderr=stderr) - -- if handle.returncode != 0: -- err = CoprSignError( -- msg="Failed to unsign {}".format(path), -- return_code=handle.returncode, -- cmd=cmd, stdout=stdout, stderr=stderr) -+ if stderr: -+ # signatrust client will print error message for one rpm per line -+ failed_list = re.findall(r"failed to sign file (.*.rpm) due to error", stderr) -+ -+ if failed_list: -+ failed_rpms = " ".join(map(os.path.basename, failed_list)) -+ log.exception("failed to sign rpm: %s".format(failed_rpms)) -+ raise CoprSignError("Rpm sign failed, affected rpms: {}" -+ .format(failed_rpms)) -+ -+ @classmethod -+ def unsign_rpms_in_dir(cls, path, opts, log): -+ """ -+ signatrust will replace the signature infomation defaultly, -+ so there is no need to unsign, just return -+ """ -+ return - -- raise err -+ @classmethod -+ def _key_existed(cls, username, projectname, opts): -+ """ -+ check keyname existence - -- return stdout, stderr -+ HEAD /api/v1/keys/ -+ """ -+ if not cls.prefix: -+ cls.get_prefix() - -+ key_name = cls.get_key_name(username, projectname, prefix=False) - --def unsign_rpms_in_dir(path, opts, log): -- """ -- :param path: directory with rpms to be signed -- :param Munch opts: backend config -- :type log: logging.Logger -- :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") -- ] -+ query = { -+ "name": key_name, -+ "visibility": "private" -+ } - -- if not rpm_list: -- return -+ headers = { -+ "accept": "application/json", -+ "Authorization": cls.signatrust_token -+ } - -- errors = [] # tuples (rpm_filepath, exception) -- for rpm in rpm_list: - try: -- _unsign_one(rpm) -- log.info("unsigned rpm: %s", rpm) -- -- except CoprSignError as e: -- log.exception("failed to unsign rpm: %s", rpm) -- errors.append((rpm, e)) -+ res = requests.head("{}/api/v1/keys/name_identical".format(opts.signatrust_host), headers=headers, params=query) -+ except Exception as e: -+ raise CoprKeygenRequestError( -+ msg="Failed to check key existence", request="/api/v1/keys/name_identical", response=res) -+ -+ # signatrust return 200 means key name available -+ if res.status_code == 200: -+ return False -+ # signatrust return 409 means key name redundant -+ elif res.status_code == 409: -+ return True -+ else: -+ raise CoprKeygenRequestError( -+ msg="Failed to check key existence", request="/api/v1/keys/name_identical", response=res) -+ -+ @classmethod -+ def create_user_keys(cls, username, projectname, opts, try_indefinitely=False): -+ """ -+ create user key pair -+ -+ POST /api/v1/keys/ -+ """ -+ if not cls.prefix: -+ cls.get_prefix() -+ -+ if cls._key_existed(username, projectname, opts): -+ return -+ time_format = "%Y-%m-%d %H:%M:%S%z" -+ expire = datetime.now(datetime.now(timezone.utc).astimezone().tzinfo) + timedelta(days=opts.signatrust_key_expire) -+ data = { -+ "name": cls.get_key_name(username, projectname, prefix=False), -+ "description": "gpg key to sign rpms in {}/{}".format(username, projectname), -+ "key_type": "pgp", -+ "visibility": "private", # we use private key type for those key will not be seen by other users -+ "attributes": { -+ "digest_algorithm": "sha2_256", -+ "key_type": "rsa", -+ "key_length": "2048", -+ "email": "{}".format(create_gpg_email(username, projectname, opts.sign_domain)), -+ }, -+ "expire_at": datetime.strftime(expire, time_format) -+ } -+ -+ headers = { -+ "content-type": "application/json", -+ "accept": "application/json", -+ "Authorization": opts.signatrust_token -+ } - -- if errors: -- raise CoprSignError("Rpm unsign failed, affected rpms: {}" -- .format([err[0] for err in errors])) -+ try: -+ res = requests.post("{}/api/v1/keys/".format(opts.signatrust_host), headers=headers, json=data) -+ except Exception as e: -+ raise CoprKeygenRequestError( -+ msg="Failed to get userinfo", request="/api/v1/keys/", response=res) -+ -+ 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/test_background_worker_build.py b/backend/tests/test_background_worker_build.py -index 1dfe19563..ba1e5aeab 100644 ---- a/tests/test_background_worker_build.py -+++ b/tests/test_background_worker_build.py -@@ -88,6 +88,12 @@ def _fake_host(): - host.release = mock.MagicMock() - return host - -+@pytest.fixture(autouse=True) -+def get_opts(): -+ with pytest.MonkeyPatch.context() as mp: -+ mp.setattr("copr_backend.sign.get_backend_opts", lambda: None) -+ yield mp -+ - @pytest.fixture - def f_build_something(): - """ -@@ -324,8 +330,8 @@ def test_full_srpm_build(f_build_srpm): - "00855954/hello-2.8-1.src.rpm") - - --@mock.patch("copr_backend.sign.SIGN_BINARY", "tests/fake-bin-sign") --@mock.patch("copr_backend.sign._sign_one") -+@mock.patch("copr_backend.sign.ObsSign.sign_cmd", "tests/fake-bin-sign") -+@mock.patch("copr_backend.sign.ObsSign._sign_one") - def test_build_and_sign(mc_sign_one, f_build_rpm_sign_on, caplog): - config = f_build_rpm_sign_on - worker = config.bw -@@ -351,7 +357,7 @@ def test_build_and_sign(mc_sign_one, f_build_rpm_sign_on, caplog): - _, level, _ = record - assert level <= logging.INFO - --@mock.patch("copr_backend.sign.SIGN_BINARY", "tests/fake-bin-sign") -+@mock.patch("copr_backend.sign.ObsSign.sign_cmd", "tests/fake-bin-sign") - @mock.patch("copr_backend.sign._sign_one") - @_patch_bwbuild_object("sign_rpms_in_dir") - def test_sign_built_packages_exception(mc_sign_rpms, mc_sign_one, -@@ -452,7 +458,7 @@ def test_invalid_job_info(f_build_rpm_case, caplog): - - @mock.patch("copr_backend.vm_alloc.time.sleep", mock.MagicMock()) - @_patch_bwbuild_object("CANCEL_CHECK_PERIOD", 0.5) --@mock.patch("copr_backend.sign.SIGN_BINARY", "tests/fake-bin-sign") -+@mock.patch("copr_backend.sign.ObsSign.sign_cmd", "tests/fake-bin-sign") - def test_cancel_build_on_vm_allocation(f_build_rpm_sign_on, caplog): - config = f_build_rpm_sign_on - worker = config.bw -@@ -513,7 +519,7 @@ class _CancelFunction(): - time.sleep(0.25) - - @_patch_bwbuild_object("CANCEL_CHECK_PERIOD", 0.5) --@mock.patch("copr_backend.sign.SIGN_BINARY", "tests/fake-bin-sign") -+@mock.patch("copr_backend.sign.ObsSign.sign_cmd", "tests/fake-bin-sign") - def test_cancel_build_on_tail_log_no_ssh(f_build_rpm_sign_on, caplog): - config = f_build_rpm_sign_on - worker = config.bw -@@ -542,7 +548,7 @@ def test_cancel_build_on_tail_log_no_ssh(f_build_rpm_sign_on, caplog): - assert "canceled stdout" in log - - @_patch_bwbuild_object("CANCEL_CHECK_PERIOD", 0.5) --@mock.patch("copr_backend.sign.SIGN_BINARY", "tests/fake-bin-sign") -+@mock.patch("copr_backend.sign.ObsSign.sign_cmd", "tests/fake-bin-sign") - def test_cancel_before_vm(f_build_rpm_sign_on, caplog): - config = f_build_rpm_sign_on - worker = config.bw -@@ -558,7 +564,7 @@ def test_cancel_before_vm(f_build_rpm_sign_on, caplog): - assert_logs_dont_exist(["Releasing VM back to pool"], caplog) - - @_patch_bwbuild_object("CANCEL_CHECK_PERIOD", 0.5) --@mock.patch("copr_backend.sign.SIGN_BINARY", "tests/fake-bin-sign") -+@mock.patch("copr_backend.sign.ObsSign.sign_cmd", "tests/fake-bin-sign") - def test_cancel_before_start(f_build_rpm_sign_on, caplog): - config = f_build_rpm_sign_on - worker = config.bw -@@ -578,7 +584,7 @@ def test_cancel_before_start(f_build_rpm_sign_on, caplog): - ], caplog) - - @_patch_bwbuild_object("CANCEL_CHECK_PERIOD", 0.5) --@mock.patch("copr_backend.sign.SIGN_BINARY", "tests/fake-bin-sign") -+@mock.patch("copr_backend.sign.ObsSign.sign_cmd", "tests/fake-bin-sign") - def test_build_retry(f_build_rpm_sign_on): - config = f_build_rpm_sign_on - worker = config.bw -@@ -650,7 +656,7 @@ def test_fe_failed_start(f_build_rpm_sign_on, caplog): - assert worker.redis_get_worker_flag("status") == "done" - - @_patch_bwbuild_object("CANCEL_CHECK_PERIOD", 0.5) --@mock.patch("copr_backend.sign.SIGN_BINARY", "tests/fake-bin-sign") -+@mock.patch("copr_backend.sign.ObsSign.sign_cmd", "tests/fake-bin-sign") - def test_cancel_script_failure(f_build_rpm_sign_on, caplog): - config = f_build_rpm_sign_on - worker = config.bw -@@ -672,7 +678,7 @@ def test_cancel_script_failure(f_build_rpm_sign_on, caplog): - ], caplog) - - @_patch_bwbuild_object("CANCEL_CHECK_PERIOD", 0.5) --@mock.patch("copr_backend.sign.SIGN_BINARY", "tests/fake-bin-sign") -+@mock.patch("copr_backend.sign.ObsSign.sign_cmd", "tests/fake-bin-sign") - def test_cancel_build_during_log_download(f_build_rpm_sign_on, caplog): - config = f_build_rpm_sign_on - worker = config.bw -diff --git a/tests/test_sign.py b/backend/tests/test_sign.py -index bf2dd1b8c..13a7a2ebc 100644 ---- a/tests/test_sign.py -+++ b/tests/test_sign.py -@@ -12,13 +12,16 @@ from copr_backend.exceptions import CoprSignError, CoprSignNoKeyError, CoprKeyge - from copr_backend.sign import ( - get_pubkey, _sign_one, sign_rpms_in_dir, create_user_keys, - gpg_hashtype_for_chroot, -- call_sign_bin, -+ call_sign_bin - ) -+from copr_backend import helpers - - STDOUT = "stdout" - STDERR = "stderr" - - -+ -+ - class TestSign(object): - # pylint: disable=too-many-public-methods - -@@ -38,6 +41,12 @@ class TestSign(object): - if self.tmp_dir_path: - shutil.rmtree(self.tmp_dir_path) - -+ @pytest.fixture(autouse=True) -+ def get_opts(self): -+ with pytest.MonkeyPatch.context() as mp: -+ mp.setattr("copr_backend.sign.get_backend_opts", lambda: None) -+ yield mp -+ - @pytest.fixture - def tmp_dir(self): - subdir = "test_createrepo_{}".format(time.time()) -@@ -54,7 +63,7 @@ class TestSign(object): - handle.write("1") - - @mock.patch("copr_backend.sign.Popen") -- def test_get_pubkey(self, mc_popen): -+ def test_get_pubkey(self, mc_popen, get_opts): - mc_handle = MagicMock() - mc_handle.communicate.return_value = (STDOUT, STDERR) - mc_handle.returncode = 0 -@@ -198,9 +207,9 @@ class TestSign(object): - 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 -@@ -212,9 +221,9 @@ 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): - -@@ -234,9 +243,9 @@ 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): - -@@ -250,9 +259,9 @@ 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): - -@@ -266,9 +275,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): - -@@ -285,9 +294,9 @@ 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): - |