From: Michael Tremer Date: Fri, 24 Jan 2025 10:56:08 +0000 (+0000) Subject: builds: Fix cloning a build X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=89b3518835c61fc58d40f160a737e1dde81259c3;p=pbs.git builds: Fix cloning a build Signed-off-by: Michael Tremer --- diff --git a/src/buildservice/builds.py b/src/buildservice/builds.py index 562dd96e..67eec6f7 100644 --- a/src/buildservice/builds.py +++ b/src/buildservice/builds.py @@ -270,7 +270,7 @@ class Builds(base.Object): build_repo = repo, pkg = package, owner = owner, - group = group, + build_group_id = group.id if group else None, test = test, disable_test_builds = disable_test_builds, ) @@ -1182,6 +1182,28 @@ class Build(database.Base, database.BackendMixin, database.SoftDeleteMixin): return await self.db.fetch_one(stmt) + # Clone! + + async def clone(self, owner, repo=None): + """ + Creates a clone of this build + """ + # Create a new build from the same package + clone = await self.backend.builds.create( + # Build the same package + package = self.pkg, + + # Owner + owner = owner, + + # Repository + repo = repo or self.build_repo, + ) + + log.info("Cloned %s as %s" % (self, clone)) + + return clone + class BuildGroup(database.Base, database.SoftDeleteMixin): __tablename__ = "build_groups" diff --git a/src/buildservice/users.py b/src/buildservice/users.py index b26bcb49..8a8154fa 100644 --- a/src/buildservice/users.py +++ b/src/buildservice/users.py @@ -845,7 +845,7 @@ class User(database.Base, database.BackendMixin, database.SoftDeleteMixin): # Custom repositories - async def get_repos(self): + async def get_repos(self, distro=None): """ Returns all custom repositories """ @@ -861,6 +861,12 @@ class User(database.Base, database.BackendMixin, database.SoftDeleteMixin): ) ) + # Filter by distribution + if distro: + stmt = stmt.where( + repos.Repo.distro == distro, + ) + return await self.db.fetch_as_list(stmt) async def get_repo(self, distro, slug=None): diff --git a/src/templates/builds/clone.html b/src/templates/builds/clone.html index fe3e6393..557425bf 100644 --- a/src/templates/builds/clone.html +++ b/src/templates/builds/clone.html @@ -1,6 +1,6 @@ -{% extends "../modal.html" %} +{% extends "modal.html" %} -{% block title %}{{ build }} - {{ _("Clone") }}{% end block %} +{% block title %}{{ build }} - {{ _("Clone") }}{% endblock %} {% block breadcrumbs %} -{% end block %} +{% endblock %} {% block modal_title %}

{{ _("Clone Build") }}

{{ build }}
-{% end block %} +{% endblock %} {% block modal %}
- {% raw xsrf_form_html() %} + {{ xsrf_form_html() | safe }} {# Repositories #} + {% set repos = current_user.get_repos(distro=build.distro) %} +
@@ -38,9 +40,9 @@
@@ -53,4 +55,4 @@
-{% end block %} +{% endblock %} diff --git a/src/web/base.py b/src/web/base.py index 1cc9bc53..8b9104c4 100644 --- a/src/web/base.py +++ b/src/web/base.py @@ -599,6 +599,20 @@ class BaseHandler(tornado.web.RequestHandler): if slug: return await self.backend.distros.get_by_slug(slug) + async def get_argument_repo(self, *args, distro=None, user=None, **kwargs): + if distro is None: + raise ValueError("Distro required") + + # Fetch the slug of the repository + slug = self.get_argument(*args, **kwargs) + + # Fetch the user repository + if user: + return await user.get_repo(slug=slug, distro=distro) + + # Or fetch it from the distribution + return await distro.get_repo(slug=slug) + # Uploads async def _get_upload(self, uuid): diff --git a/src/web/builds.py b/src/web/builds.py index e8c0822f..87afc205 100644 --- a/src/web/builds.py +++ b/src/web/builds.py @@ -135,33 +135,31 @@ class ApproveHandler(base.BaseHandler): class CloneHandler(base.BaseHandler): @base.authenticated - def get(self, uuid): - build = self.backend.builds.get_by_uuid(uuid) + async def get(self, uuid): + build = await self.backend.builds.get_by_uuid(uuid) if not build: raise tornado.web.HTTPError(404, "Could not find build %s" % uuid) - # Fetch repositories - try: - repos = self.current_user.repos[build.distro] - except KeyError: - repos = [] - - self.render("builds/clone.html", build=build, repos=repos) + await self.render("builds/clone.html", build=build) @base.authenticated async def post(self, uuid): - build = self.backend.builds.get_by_uuid(uuid) + build = await self.backend.builds.get_by_uuid(uuid) if not build: raise tornado.web.HTTPError(404, "Could not find build %s" % uuid) # Fetch the repository - repo = self.current_user.get_repo(build.distro, self.get_argument("repo")) + repo = await self.get_argument_repo( + "repo", + user = self.current_user, + distro = build.distro, + ) # Clone the build - with self.db.transaction(): - clone = await self.backend.builds.create( - repo=repo, package=build.pkg, owner=self.current_user, - ) + clone = await build.clone( + owner = self.current_user, + repo = repo, + ) # Launch all jobs (in the background) self.backend.run_task(self.backend.builds.launch, [clone])