From 6619eae752fee12bb826e449548046768a75ed4a Mon Sep 17 00:00:00 2001 From: Jiri Kyjovsky Date: Fri, 19 May 2023 13:40:34 +0200 Subject: [PATCH] frontend, cli, python, backend, rpmbuild: Add priority=X to repo config This allows users to set priority of their repository via frontend page or copr-cli. This priority value sets the `priority=X` value in repo confid in /etc/yum.repos.d/_copr:*repo --- .../copr_backend/background_worker_build.py | 1 + backend/copr_backend/job.py | 2 ++ cli/copr_cli/main.py | 8 ++++++ cli/tests/test_cli.py | 2 ++ .../7d9f6f921fa0_add_repo_priority_field.py | 25 +++++++++++++++++++ frontend/coprs_frontend/coprs/constants.py | 2 ++ frontend/coprs_frontend/coprs/forms.py | 13 ++++++++++ frontend/coprs_frontend/coprs/models.py | 14 +++++++++++ .../coprs/templates/coprs/_coprs_forms.html | 5 ++++ .../coprs/views/apiv3_ns/apiv3_projects.py | 2 ++ .../coprs/views/backend_ns/backend_general.py | 1 + .../coprs/views/coprs_ns/coprs_general.py | 3 +++ .../tests/test_apiv3/test_projects.py | 7 ++++-- python/copr/v3/proxies/project.py | 8 ++++-- rpmbuild/copr_rpmbuild/builders/mock.py | 3 +++ rpmbuild/main.py | 3 +++ rpmbuild/man/copr-rpmbuild.1.asciidoc | 3 +++ 17 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 frontend/coprs_frontend/alembic/versions/7d9f6f921fa0_add_repo_priority_field.py diff --git a/backend/copr_backend/background_worker_build.py b/backend/copr_backend/background_worker_build.py index 344609422..cea10ceed 100644 --- a/backend/copr_backend/background_worker_build.py +++ b/backend/copr_backend/background_worker_build.py @@ -450,6 +450,7 @@ def _start_remote_build(self): command += " --srpm --task-url {task_url} --detached" else: command += " --task-url {task_url} --chroot {chroot} --detached" + command = command.format(task_url=self.job.task_url, chroot=self.job.chroot) diff --git a/backend/copr_backend/job.py b/backend/copr_backend/job.py index 47f8d8367..3b5b61c2a 100644 --- a/backend/copr_backend/job.py +++ b/backend/copr_backend/job.py @@ -73,6 +73,8 @@ def __init__(self, task_data, worker_opts): self.results = None self.appstream = None + self.repo_priority = None + # TODO: validate update data for key, val in task_data.items(): key = str(key) diff --git a/cli/copr_cli/main.py b/cli/copr_cli/main.py index 328322aa8..15496a948 100644 --- a/cli/copr_cli/main.py +++ b/cli/copr_cli/main.py @@ -481,6 +481,7 @@ def action_create(self, args): appstream=ON_OFF_MAP[args.appstream], runtime_dependencies=args.runtime_dependencies, packit_forge_projects_allowed=args.packit_forge_projects_allowed, + repo_priority=args.repo_priority, ) owner_part = username.replace('@', "g/") @@ -514,6 +515,7 @@ def action_modify_project(self, args): appstream=ON_OFF_MAP[args.appstream], runtime_dependencies=args.runtime_dependencies, packit_forge_projects_allowed=args.packit_forge_projects_allowed, + repo_priority=args.repo_priority, ) @requires_api_auth @@ -1174,6 +1176,9 @@ def setup_parser(): "created for you (as soon as they are available) as rawhide " "chroot forks.")) + parser_create.add_argument("--repo-priority", default=None, + help="Set the priority value of this repository") + create_and_modify_common_opts(parser_create) parser_create.set_defaults(func="action_create") @@ -1241,6 +1246,9 @@ def setup_parser(): "created for you (as soon as they are available) as rawhide " "chroot forks.")) + parser_modify.add_argument("--repo-priority", default=None, + help="Set the priority value of this repository") + create_and_modify_common_opts(parser_modify) parser_modify.set_defaults(func="action_modify_project") diff --git a/cli/tests/test_cli.py b/cli/tests/test_cli.py index 97c887f91..98b7a70c7 100644 --- a/cli/tests/test_cli.py +++ b/cli/tests/test_cli.py @@ -479,6 +479,7 @@ def test_create_project(config_from_file, project_proxy_add, capsys): "appstream": False, "runtime_dependencies": None, "packit_forge_projects_allowed": None, + "repo_priority": None, } assert stdout == "New project was successfully created: http://copr/coprs/jdoe/foo/\n" @@ -575,6 +576,7 @@ def test_create_multilib_project(config_from_file, project_proxy_add, capsys): "appstream": False, "runtime_dependencies": None, "packit_forge_projects_allowed": None, + "repo_priority": None, } assert stdout == "New project was successfully created: http://copr/coprs/jdoe/foo/\n" diff --git a/frontend/coprs_frontend/alembic/versions/7d9f6f921fa0_add_repo_priority_field.py b/frontend/coprs_frontend/alembic/versions/7d9f6f921fa0_add_repo_priority_field.py new file mode 100644 index 000000000..dfaa9eee9 --- /dev/null +++ b/frontend/coprs_frontend/alembic/versions/7d9f6f921fa0_add_repo_priority_field.py @@ -0,0 +1,25 @@ +""" +Add repo priority field + +Revision ID: 7d9f6f921fa0 +Revises: ba6ac0936bfb +Create Date: 2023-05-25 11:05:39.877208 +""" + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '7d9f6f921fa0' +down_revision = 'ba6ac0936bfb' +branch_labels = None +depends_on = None + + +def upgrade(): + op.add_column('copr', sa.Column('repo_priority', sa.Integer(), nullable=True)) + + +def downgrade(): + op.drop_column('copr', 'repo_priority') diff --git a/frontend/coprs_frontend/coprs/constants.py b/frontend/coprs_frontend/coprs/constants.py index 4f51c2511..0bd8ab83a 100644 --- a/frontend/coprs_frontend/coprs/constants.py +++ b/frontend/coprs_frontend/coprs/constants.py @@ -4,3 +4,5 @@ BANNER_LOCATION = "/var/lib/copr/data/banner-include.html" + +DEFAULT_REPO_PRIORITY_VALUE = 99 diff --git a/frontend/coprs_frontend/coprs/forms.py b/frontend/coprs_frontend/coprs/forms.py index 2c658f9d8..9db502afc 100644 --- a/frontend/coprs_frontend/coprs/forms.py +++ b/frontend/coprs_frontend/coprs/forms.py @@ -9,6 +9,8 @@ from flask_wtf.file import FileRequired, FileField from fnmatch import fnmatch +from coprs.constants import DEFAULT_REPO_PRIORITY_VALUE + try: # get rid of deprecation warning with newer flask_wtf from flask_wtf import FlaskForm except ImportError: @@ -655,6 +657,17 @@ class CoprForm(BaseForm): filters=[StringListFilter(), StripUrlSchemaListFilter()], validators=[wtforms.validators.Optional()],) + repo_priority = wtforms.IntegerField( + "The priority value of this repository", + description="""If there is more than one package to install from (e.g. vim from + Fedora repo and Copr repo), the repo with lower priority is picked.""", + render_kw={"placeholder": "Optional - integer, e.g. 22"}, + validators=[ + wtforms.validators.Optional(), + wtforms.validators.NumberRange(min=1, max=DEFAULT_REPO_PRIORITY_VALUE)], + default=None, + ) + @property def errors(self): """ diff --git a/frontend/coprs_frontend/coprs/models.py b/frontend/coprs_frontend/coprs/models.py index 038534b47..e14fac82b 100644 --- a/frontend/coprs_frontend/coprs/models.py +++ b/frontend/coprs_frontend/coprs/models.py @@ -388,6 +388,20 @@ class _CoprPublic(db.Model, helpers.Serializer): # allowed to build in this Copr via Packit packit_forge_projects_allowed = db.Column(db.Text) + # priority=NUMBER in repo configs + repo_priority = db.Column(db.Integer, nullable=True) + + @validates("repo_priority") + def validate_repo_priority(self, _, value): + """Checks whether priority value is correct""" + if value < 1: + raise ValueError("Repo priority can't be lower than 1") + + if value > 99: + raise ValueError("Repo priority can't be higher than 99") + + return value + class _CoprPrivate(db.Model, helpers.Serializer): """ diff --git a/frontend/coprs_frontend/coprs/templates/coprs/_coprs_forms.html b/frontend/coprs_frontend/coprs/templates/coprs/_coprs_forms.html index 6430624cd..004605e5a 100644 --- a/frontend/coprs_frontend/coprs/templates/coprs/_coprs_forms.html +++ b/frontend/coprs_frontend/coprs/templates/coprs/_coprs_forms.html @@ -156,6 +156,11 @@

{{ counter('instructions') }}. Other options

placeholder='Optional', info='Delete the project after the specfied period of time (empty = disabled)') }} + {{ render_field(form.repo_priority, + class="short-input-field", + placeholder='Optional', + info='Set the priority value of this repository. Defaults to 99.') }} + {{ render_field(form.isolation, placeholder='default') }} {{ render_bootstrap_options(form) }} diff --git a/frontend/coprs_frontend/coprs/views/apiv3_ns/apiv3_projects.py b/frontend/coprs_frontend/coprs/views/apiv3_ns/apiv3_projects.py index 1b4b8b389..dd5e99133 100644 --- a/frontend/coprs_frontend/coprs/views/apiv3_ns/apiv3_projects.py +++ b/frontend/coprs_frontend/coprs/views/apiv3_ns/apiv3_projects.py @@ -39,6 +39,7 @@ def to_dict(copr): "appstream": copr.appstream, "packit_forge_projects_allowed": copr.packit_forge_projects_allowed_list, "follow_fedora_branching": copr.follow_fedora_branching, + "repo_priority": copr.repo_priority, } @@ -162,6 +163,7 @@ def _form_field_repos(form_field): runtime_dependencies=_form_field_repos(form.runtime_dependencies), appstream=form.appstream.data, packit_forge_projects_allowed=_form_field_repos(form.packit_forge_projects_allowed), + repo_priority=form.repo_priority.data, ) db.session.commit() except (DuplicateException, diff --git a/frontend/coprs_frontend/coprs/views/backend_ns/backend_general.py b/frontend/coprs_frontend/coprs/views/backend_ns/backend_general.py index a6e16ccaa..51a1722fa 100755 --- a/frontend/coprs_frontend/coprs/views/backend_ns/backend_general.py +++ b/frontend/coprs_frontend/coprs/views/backend_ns/backend_general.py @@ -163,6 +163,7 @@ def get_build_record(task, for_backend=False): "isolation": task.build.isolation, "fedora_review": task.build.copr.fedora_review, "appstream": bool(task.build.appstream), + "repo_priority": task.build.copr.repo_priority }) copr_chroot = CoprChrootsLogic.get_by_name_safe(task.build.copr, task.mock_chroot.name) diff --git a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py index f370e86a1..063d17676 100644 --- a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py +++ b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_general.py @@ -279,6 +279,7 @@ def copr_new(username=None, group_name=None): isolation=form.isolation.data, appstream=form.appstream.data, packit_forge_projects_allowed=form.packit_forge_projects_allowed.data, + repo_priority=form.repo_priority.data ) db.session.commit() @@ -551,6 +552,8 @@ def process_copr_update(copr, form): copr.isolation = form.isolation.data copr.appstream = form.appstream.data copr.packit_forge_projects_allowed = form.packit_forge_projects_allowed.data + copr.repo_priority = form.repo_priority.data + if flask.g.user.admin: copr.auto_prune = form.auto_prune.data else: diff --git a/frontend/coprs_frontend/tests/test_apiv3/test_projects.py b/frontend/coprs_frontend/tests/test_apiv3/test_projects.py index 800211cdc..2a8a9cd6c 100644 --- a/frontend/coprs_frontend/tests/test_apiv3/test_projects.py +++ b/frontend/coprs_frontend/tests/test_apiv3/test_projects.py @@ -77,7 +77,7 @@ def test_update_copr_api3(self): # testing method! already_tested = set([ "delete_after", "build_enable_net", "auto_createrepo", "repos", - "runtime_dependencies", "packit_forge_projects_allowed" + "runtime_dependencies", "packit_forge_projects_allowed", "repo_priority" ]) # check non-trivial changes @@ -91,6 +91,7 @@ def test_update_copr_api3(self): assert old_data["auto_prune"] is True assert old_data["follow_fedora_branching"] is True assert old_data["packit_forge_projects_allowed"] == "" + assert old_data["repo_priority"] is None self.api3.modify_project( "test", delete_after_days=5, enable_net=True, devel_mode=True, repos=["http://example/repo/", "http://another/"], @@ -100,7 +101,8 @@ def test_update_copr_api3(self): "https://github.com/packit/ogr", "github.com/packit/requre", "http://github.com/packit/packit" - ] + ], + repo_priority=13, ) new_data = self._get_copr_id_data(1) delete_after = datetime.datetime.now() + datetime.timedelta(days=5) @@ -113,6 +115,7 @@ def test_update_copr_api3(self): old_data["bootstrap"] = "default" old_data["packit_forge_projects_allowed"] = "github.com/packit/ogr\ngithub.com/packit/requre\ngithub.com" \ "/packit/packit" + old_data["repo_priority"] = 13 assert old_data == new_data old_data = new_data diff --git a/python/copr/v3/proxies/project.py b/python/copr/v3/proxies/project.py index e22642757..89b062ea2 100644 --- a/python/copr/v3/proxies/project.py +++ b/python/copr/v3/proxies/project.py @@ -71,7 +71,8 @@ def add(self, ownername, projectname, chroots, description=None, instructions=No auto_prune=True, use_bootstrap_container=None, devel_mode=False, delete_after_days=None, multilib=False, module_hotfixes=False, bootstrap=None, bootstrap_image=None, isolation=None, follow_fedora_branching=True, - fedora_review=None, appstream=False, runtime_dependencies=None, packit_forge_projects_allowed=None): + fedora_review=None, appstream=False, runtime_dependencies=None, packit_forge_projects_allowed=None, + repo_priority=None): """ Create a project @@ -139,6 +140,7 @@ def add(self, ownername, projectname, chroots, description=None, instructions=No "appstream": appstream, "runtime_dependencies": runtime_dependencies, "packit_forge_projects_allowed": packit_forge_projects_allowed, + "repo_priority": repo_priority, } _compat_use_bootstrap_container(data, use_bootstrap_container) @@ -157,7 +159,8 @@ def edit(self, ownername, projectname, chroots=None, description=None, instructi auto_prune=None, use_bootstrap_container=None, devel_mode=None, delete_after_days=None, multilib=None, module_hotfixes=None, bootstrap=None, bootstrap_image=None, isolation=None, follow_fedora_branching=None, - fedora_review=None, appstream=None, runtime_dependencies=None, packit_forge_projects_allowed=None): + fedora_review=None, appstream=None, runtime_dependencies=None, packit_forge_projects_allowed=None, + repo_priority=None): """ Edit a project @@ -223,6 +226,7 @@ def edit(self, ownername, projectname, chroots=None, description=None, instructi "appstream": appstream, "runtime_dependencies": runtime_dependencies, "packit_forge_projects_allowed": packit_forge_projects_allowed, + "repo_priority": repo_priority, } _compat_use_bootstrap_container(data, use_bootstrap_container) diff --git a/rpmbuild/copr_rpmbuild/builders/mock.py b/rpmbuild/copr_rpmbuild/builders/mock.py index 003a79eef..b533c12a1 100644 --- a/rpmbuild/copr_rpmbuild/builders/mock.py +++ b/rpmbuild/copr_rpmbuild/builders/mock.py @@ -27,6 +27,9 @@ def __init__(self, task, sourcedir, resultdir, config): self.buildroot_pkgs = task.get("buildroot_pkgs") self.enable_net = task.get("enable_net") self.repos = task.get("repos") + if task.get("repos") and task.get("repo_priority") is not None: + self.repos["priority"] = task.get("repo_priority") + self.bootstrap = task.get("bootstrap") self.bootstrap_image = task.get("bootstrap_image") self.timeout = task.get("timeout", 3600) diff --git a/rpmbuild/main.py b/rpmbuild/main.py index bd34e3a02..efe071f4e 100755 --- a/rpmbuild/main.py +++ b/rpmbuild/main.py @@ -197,6 +197,9 @@ def get_task(args, config, build_config_url_path=None, task_id=None): if args.copr: task['task_id'] = copr_chroot_to_task_id(args.copr, args.chroot) + if args.repo_priority: + task["repo_priority"] = args.repo_priority + return task diff --git a/rpmbuild/man/copr-rpmbuild.1.asciidoc b/rpmbuild/man/copr-rpmbuild.1.asciidoc index 59b7a8ec3..d0ed55b88 100644 --- a/rpmbuild/man/copr-rpmbuild.1.asciidoc +++ b/rpmbuild/man/copr-rpmbuild.1.asciidoc @@ -42,6 +42,9 @@ OPTIONS --verbose:: Print debugging information. +--priority:: + Set the priority of this copr repository. + --help:: Display help.