From 883af5b83ca3ed9e31903645fd581ff487139316 Mon Sep 17 00:00:00 2001 From: Jakub Kadlcik Date: Fri, 6 Dec 2024 17:13:29 +0100 Subject: [PATCH] backend, frontend: implement support for Pulp manual createrepo Fix #3498 --- backend/copr_backend/pulp.py | 22 +++++++++++ backend/copr_backend/storage.py | 37 +++++++++++++++++-- .../coprs/logic/complex_logic.py | 6 ++- 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/backend/copr_backend/pulp.py b/backend/copr_backend/pulp.py index 6937abcb0..dc3c5fadf 100644 --- a/backend/copr_backend/pulp.py +++ b/backend/copr_backend/pulp.py @@ -187,6 +187,19 @@ def delete_content(self, repository, artifacts): data = {"remove_content_units": artifacts} return requests.post(url, json=data, **self.request_params) + def copy_content(self, repository, repository_version, units): + """ + Copy a list of content units (RPM packages) into this repository + The "copy" isn't the right word because the actual data isn't touched + at all. Only a new database entry pointing to the data is created. + So regardless of the number of units, this operation should be fast. + https://pulpproject.org/pulp_rpm/restapi/#tag/Repositories:-Rpm/operation/repositories_rpm_rpm_modify + """ + path = os.path.join(repository, "modify/") + url = self.config["base_url"] + path + data = {"add_content_units": units} + return requests.post(url, json=data, **self.request_params) + def delete_repository(self, repository): """ Delete an RPM repository @@ -229,3 +242,12 @@ def list_distributions(self, prefix): url = self.url("api/v3/distributions/rpm/rpm/?") url += urlencode({"name__startswith": prefix}) return requests.get(url, **self.request_params) + + def list_packages(self, repository_version): + """ + Get a list of RPM packages provided by a given repository + https://pulpproject.org/pulp_rpm/restapi/#tag/Content:-Advisories/operation/content_rpm_advisories_list + """ + url = self.url("api/v3/content/rpm/packages/?") + url += urlencode({"repository_version": repository_version}) + return requests.get(url, **self.request_params) diff --git a/backend/copr_backend/storage.py b/backend/copr_backend/storage.py index 1d816b6c1..6170a3209 100644 --- a/backend/copr_backend/storage.py +++ b/backend/copr_backend/storage.py @@ -200,8 +200,37 @@ def init_project(self, dirname, chroot): distribution, response.text) return False + # TODO Move this somewhere else + devel_repository_name = "/".join([ + self.owner, + dirname or self.project, + chroot + "_devel", + ]) + response = self.client.get_repository(devel_repository_name) + results = response.json()["results"] + + if not self.devel and results: + devel_repository = results[0] + devel_repository_version = devel_repository["latest_version_href"] + response = self.client.list_packages(devel_repository_version) + hrefs = [x["pulp_href"] for x in response.json()["results"]] + response = self.client.copy_content(repository, None, hrefs) + if not response.ok: + self.log.error( + "Failed to copy packages into the %s repository: %s", + repository, hrefs, + ) + return False + # <------ The ^^ code should be in a separate function + response = self.client.create_publication(repository) - return response.ok + if not response.ok: + self.log.error( + "Failed to create a Pulp publication for %s because of %s", + repository, response.text, + ) + return False + return True def upload_build_results(self, chroot, results_dir, target_dir_name): resources = [] @@ -343,16 +372,16 @@ def delete_builds(self, dirname, chroot_builddirs, build_ids): return result def _repository_name(self, chroot, dirname=None): + # On backend we use /devel but Pulp has a problem with that + suffix = "_devel" if self.devel else "" return "/".join([ self.owner, dirname or self.project, - chroot, + chroot + suffix, ]) def _distribution_name(self, chroot): repository = self._repository_name(chroot) - if self.devel: - return "{0}-devel".format(repository) return repository def _get_repository(self, chroot): diff --git a/frontend/coprs_frontend/coprs/logic/complex_logic.py b/frontend/coprs_frontend/coprs/logic/complex_logic.py index 992771597..5744b9f18 100644 --- a/frontend/coprs_frontend/coprs/logic/complex_logic.py +++ b/frontend/coprs_frontend/coprs/logic/complex_logic.py @@ -8,7 +8,7 @@ import flask import sqlalchemy -from copr_common.enums import StatusEnum +from copr_common.enums import StatusEnum, StorageEnum from coprs import app from coprs import db from coprs import helpers @@ -610,9 +610,11 @@ def generate_build_config(cls, copr, chroot_id): repos[0]["module_hotfixes"] = True if not copr.auto_createrepo: + suffix = "_devel" if copr.storage == StorageEnum.pulp else "/devel" + baseurl = copr.repo_url + "/{0}{1}/".format(chroot_id, suffix) repos.append({ "id": "copr_base_devel", - "baseurl": copr.repo_url + "/{}/devel/".format(chroot_id), + "baseurl": baseurl, "name": "Copr buildroot", })