From ccbb6acc51d0ca50026fc7ac79ed52ce80d55ae6 Mon Sep 17 00:00:00 2001 From: Jakub Kadlcik Date: Thu, 21 Nov 2024 12:27:49 +0100 Subject: [PATCH] backend: implement a check for every storage whether a repository is available Otherwise, builds in Pulp projects will fail with this: Waiting for copr_base repository Waiting for copr_base repository Backend process error: Giving up waiting for copr_base repository So far it worked only because we didn't create Pulp projects directly but rather migrated existing projects into Pulp and therefore this path existed on the backend. --- .../copr_backend/background_worker_build.py | 3 +- backend/copr_backend/storage.py | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/backend/copr_backend/background_worker_build.py b/backend/copr_backend/background_worker_build.py index 451d7e1f8..128e899b9 100644 --- a/backend/copr_backend/background_worker_build.py +++ b/backend/copr_backend/background_worker_build.py @@ -348,10 +348,9 @@ def _wait_for_repo(self): # we don't need copr_base repodata for srpm builds return - repodata = os.path.join(self.job.chroot_dir, "repodata/repomd.xml") waiting_since = time.time() while time.time() - waiting_since < 60: - if os.path.exists(repodata): + if self.storage.repository_exists(self.job.chroot): return # Either (a) the very first copr-repo run in this chroot dir diff --git a/backend/copr_backend/storage.py b/backend/copr_backend/storage.py index 1d816b6c1..7c40ef63c 100644 --- a/backend/copr_backend/storage.py +++ b/backend/copr_backend/storage.py @@ -5,6 +5,8 @@ import os import json import shutil +from urllib.parse import urlparse +import requests from copr_common.enums import StorageEnum from copr_backend.helpers import call_copr_repo, build_chroot_log_name from copr_backend.pulp import PulpClient @@ -85,6 +87,12 @@ def delete_builds(self, dirname, chroot_builddirs, build_ids): """ raise NotImplementedError + def repository_exists(self, chroot): + """ + Does a repository exist? + """ + raise NotImplementedError + class BackendStorage(Storage): """ @@ -172,6 +180,11 @@ def delete_builds(self, dirname, chroot_builddirs, build_ids): self.log.debug("can't remove %s", log_path) return result + def repository_exists(self, chroot): + repodata = os.path.join(self.opts.destdir, self.owner, self.project, + chroot, "repodata", "repomd.xml") + return os.path.exists(repodata) + class PulpStorage(Storage): """ @@ -342,6 +355,24 @@ def delete_builds(self, dirname, chroot_builddirs, build_ids): return result + def repository_exists(self, chroot): + name = self._distribution_name(chroot) + response = self.client.get_distribution(name) + if not response.ok: + return False + distribution = response.json()["results"][0] + + # For some instances (local container) the distribution base_url + # contains only path, for some instances (hosted STG) it returns fully + # qualified URL. The problem is that there is a lot of magic in the + # hosted deployment in order to provide the data publicly without + # a Red Hat login. And we cannot use the returned URL, only its path. + path = urlparse(distribution["base_url"]).path.lstrip("/") + host = self.client.config["base_url"].rstrip("/") + repodata = "{0}/{1}/repodata/repomd.xml".format(host, path) + response = requests.head(repodata) + return response.ok + def _repository_name(self, chroot, dirname=None): return "/".join([ self.owner,