Repository : http://git.fedorahosted.org/cgit/copr.git
On branch : master
commit 4e635ea8e603d652a38a33d0f68b76c8bfe19b0f Author: Adam Samalik asamalik@redhat.com Date: Thu Sep 3 16:10:46 2015 +0200
[frontend] resubmitting build ...
Using resubmit: - will just rebuild sources from dist git - allows to use chroots from the original build only
Resubmitting an old build which is not in dist git: - will try to import it into dist git from URL as a new one
frontend/coprs_frontend/coprs/forms.py | 43 ++++++++++++++++ .../coprs/logic/.builds_logic.py.swo | Bin 0 -> 16384 bytes .../coprs_frontend/coprs/logic/builds_logic.py | 48 +++++++++++++++++- frontend/coprs_frontend/coprs/models.py | 2 - .../templates/coprs/detail/_builds_forms.html | 12 ++++- .../templates/coprs/detail/_packages_table.html | 48 ++++++++++++++++++ .../templates/coprs/detail/add_build/rebuild.html | 29 +++++++++++ .../templates/coprs/detail/add_build/url.html | 2 +- .../coprs/templates/coprs/detail/packages.html | 16 ++++++ .../coprs/views/coprs_ns/coprs_builds.py | 53 ++++++++++++++++++-- 10 files changed, 243 insertions(+), 10 deletions(-)
diff --git a/frontend/coprs_frontend/coprs/forms.py b/frontend/coprs_frontend/coprs/forms.py index 1a33a2b..766ada3 100644 --- a/frontend/coprs_frontend/coprs/forms.py +++ b/frontend/coprs_frontend/coprs/forms.py @@ -358,6 +358,49 @@ class BuildFormUploadFactory(object): return F
+class BuildFormRebuildFactory(object): + @staticmethod + def create_form_cls(active_chroots): + class F(wtf.Form): + @property + def selected_chroots(self): + selected = [] + for ch in self.chroots_list: + if getattr(self, ch).data: + selected.append(ch) + return selected + + memory_reqs = wtforms.IntegerField( + "Memory requirements", + validators=[ + wtforms.validators.NumberRange( + min=constants.MIN_BUILD_MEMORY, + max=constants.MAX_BUILD_MEMORY)], + default=constants.DEFAULT_BUILD_MEMORY) + + timeout = wtforms.IntegerField( + "Timeout", + validators=[ + wtforms.validators.NumberRange( + min=constants.MIN_BUILD_TIMEOUT, + max=constants.MAX_BUILD_TIMEOUT)], + default=constants.DEFAULT_BUILD_TIMEOUT) + + enable_net = wtforms.BooleanField() + + F.chroots_list = map(lambda x: x.name, active_chroots) + F.chroots_list.sort() + F.chroots_sets = {} + for ch in F.chroots_list: + setattr(F, ch, wtforms.BooleanField(ch, default=True)) + if ch[0] in F.chroots_sets: + F.chroots_sets[ch[0]].append(ch) + else: + F.chroots_sets[ch[0]] = [ch] + + return F + + class ChrootForm(wtf.Form):
""" diff --git a/frontend/coprs_frontend/coprs/logic/.builds_logic.py.swo b/frontend/coprs_frontend/coprs/logic/.builds_logic.py.swo new file mode 100644 index 0000000..d8fd7ab Binary files /dev/null and b/frontend/coprs_frontend/coprs/logic/.builds_logic.py.swo differ diff --git a/frontend/coprs_frontend/coprs/logic/builds_logic.py b/frontend/coprs_frontend/coprs/logic/builds_logic.py index 9524189..ace4bfa 100644 --- a/frontend/coprs_frontend/coprs/logic/builds_logic.py +++ b/frontend/coprs_frontend/coprs/logic/builds_logic.py @@ -174,6 +174,46 @@ class BuildsLogic(object): return models.Build.query.get(build_id)
@classmethod + def create_new_from_other_build(cls, user, copr, source_build, + chroot_names=None, **build_options): + # check which chroots we need + chroots = [] + for chroot in copr.active_chroots: + if chroot.name in chroot_names: + chroots.append(chroot) + + # I don't want to import anything, just rebuild what's in dist git + skip_import = True + git_hashes = {} + for chroot in source_build.build_chroots: + if not chroot.git_hash: + # I got an old build from time we didn't use dist git + # So I'll submit it as a new build using it's link + skip_import = False + git_hashes = None + flask.flash("This build is not in Dist Git. Trying to import the package again.") + break + git_hashes[chroot.name] = chroot.git_hash + + # try: + build = cls.add( + user=user, + pkgs=source_build.pkgs, + copr=copr, + chroots=chroots, + source_type=source_build.source_type, + source_json=source_build.source_json, + enable_net=build_options.get("enabled_net", True), + git_hashes=git_hashes, + skip_import=skip_import) + + if user.proven: + if "timeout" in build_options: + build.timeout = build_options["timeout"] + + return build + + @classmethod def create_new_from_url(cls, user, copr, srpm_url, chroot_names=None, **build_options): """ @@ -264,7 +304,7 @@ class BuildsLogic(object): @classmethod def add(cls, user, pkgs, copr, source_type=None, source_json=None, repos=None, chroots=None, timeout=None, enable_net=True, - git_hashes=None): + git_hashes=None, skip_import=False): if chroots is None: chroots = []
@@ -308,12 +348,18 @@ class BuildsLogic(object): if not chroots: chroots = copr.active_chroots
+ status = helpers.StatusEnum("importing") + + if skip_import: + status = StatusEnum("pending") + for chroot in chroots: git_hash = None if git_hashes: git_hash = git_hashes.get(chroot.name) buildchroot = models.BuildChroot( build=build, + status=status, mock_chroot=chroot, git_hash=git_hash)
diff --git a/frontend/coprs_frontend/coprs/models.py b/frontend/coprs_frontend/coprs/models.py index eac9535..e52087c 100644 --- a/frontend/coprs_frontend/coprs/models.py +++ b/frontend/coprs_frontend/coprs/models.py @@ -516,8 +516,6 @@ class Build(db.Model, helpers.Serializer):
Build is repeatable only if it's not pending, starting or running """ - if self.source_type == BuildSourceEnum("srpm_upload"): - return False return self.status not in [StatusEnum("pending"), StatusEnum("starting"), StatusEnum("running"), ] diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/_builds_forms.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/_builds_forms.html index f59d57d..fdbbb79 100644 --- a/frontend/coprs_frontend/coprs/templates/coprs/detail/_builds_forms.html +++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/_builds_forms.html @@ -26,9 +26,13 @@
{##### GENERAL FORM HELPERS #####}
-{% macro copr_build_form_begin(form, view, copr) %} +{% macro copr_build_form_begin(form, view, copr, build=None) %} {{ render_form_errors(form, [form._mock_chroots_error]) }} + {% if not build %} <form class="form-horizontal" action="{{ url_for(view, username=copr.owner.name, coprname=copr.name) }}" method="post" enctype="multipart/form-data"> + {% else %} + <form class="form-horizontal" action="{{ url_for(view, username=copr.owner.name, coprname=copr.name, build_id=build.id) }}" method="post" enctype="multipart/form-data"> + {% endif %} <div class="form-group"> <label class="col-sm-2 control-label" for="textInput-markup"> Chroots @@ -102,6 +106,12 @@ {% endmacro %}
+{% macro copr_build_form_rebuild(form, view, copr, build) %} + {{ copr_build_form_begin(form, view, copr, build) }} + {{ copr_build_form_end(form, view, copr) }} +{% endmacro %} + +
{% macro copr_build_cancel_form(build, page) %} {% if build.cancelable %} diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/_packages_table.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/_packages_table.html new file mode 100644 index 0000000..47c1004 --- /dev/null +++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/_packages_table.html @@ -0,0 +1,48 @@ +{% macro packages_table(packages) %} +{% if packages %} + <table class="datatable table table-striped table-bordered"> + <thead> + <tr> + <th>Name</th> + <th>Current Version</th> + <th>Builds</th> + <th>Last Built</th> + <th>Dist Git</th> + </tr> + </thead> + <tbody> + {% for package in packages %} + <tr> + <td> + {{ package.name }} + </td> + <td> + no idea + </td> + <td> + {% for b in package.builds %}{{b.id}} ; {%endfor%} + </td> + <td> + no idea + </td> + <td> + {{ package.dist_git }} + </td> + </tr> + {% endfor %} + </tbody> + </table> +{% else %} + <h3>No packages so far</h3> +{% endif %} + +<script> + // Initialize Datatables + $(document).ready(function() { + $('.datatable').dataTable({ + "order": [[ 0, "desc" ]] + }); + }); +</script> + +{% endmacro %} diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/add_build/rebuild.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/add_build/rebuild.html new file mode 100644 index 0000000..f42fcda --- /dev/null +++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/add_build/rebuild.html @@ -0,0 +1,29 @@ +{% extends "coprs/detail.html" %} +{% from "coprs/detail/_builds_forms.html" import copr_build_form_rebuild with context %} + +{% block new_build_rebuild_selected %}active{% endblock %} + +{%block project_breadcrumb %} +<li> + <a href="{{ url_for('coprs_ns.copr_builds', username=copr.owner.name, coprname=copr.name) }}">Builds</a> +</li> +<li> + <a href="{{url_for("coprs_ns.copr_build", username = build.copr.owner.name, coprname = build.copr.name, build_id = build.id)}}"> + {{build.id}} + </a> +</li> +<li class="active"> + resubmit +</li> +{%endblock%} + + +{% block detail_body %} +<div class="row"> + <div class="col-sm-12"> + <h2> Resubmit build {{ build.id }} </h2> + <p> Resubmitting a build will rebuild the same sources again. </p> + {{ copr_build_form_rebuild(form, 'coprs_ns.copr_new_build_rebuild', copr, build) }} + </div> +</div> +{% endblock %} diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/add_build/url.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/add_build/url.html index 575a03f..cb5568c 100644 --- a/frontend/coprs_frontend/coprs/templates/coprs/detail/add_build/url.html +++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/add_build/url.html @@ -10,7 +10,7 @@
{% block build_form %} <h3> Build From URL of a SRPM Package</h3> -<p> Provide an external URL link to the package you want to build. You can provide more than one URL. +<p> Provide an external URL link to the package you want to build. You can provide more than one URL. </p>
{{ copr_build_form_url(form, 'coprs_ns.copr_new_build', copr) }}
diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/packages.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/packages.html new file mode 100644 index 0000000..ce63cee --- /dev/null +++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/packages.html @@ -0,0 +1,16 @@ +{% extends "coprs/detail.html" %} +{% block title %}Packages for {{ copr.owner.name }}/{{ copr.name }}{% endblock %} +{% block packages_selected %}active{% endblock %} +{% from "_helpers.html" import render_pagination %} +{% from "coprs/detail/_packages_table.html" import packages_table with context %} +{%block project_breadcrumb %} +<li class="active"> + Packages +</li> +{%endblock%} + +{% block detail_body %} +<h2>Project Packages</h2> +<p>This view shows all packages in the project</p> + {{ packages_table(packages) }} +{% endblock %} diff --git a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_builds.py b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_builds.py index 2dffef3..7c9d27e 100644 --- a/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_builds.py +++ b/frontend/coprs_frontend/coprs/views/coprs_ns/coprs_builds.py @@ -230,6 +230,49 @@ def copr_new_build(username, coprname): return copr_add_build(username=username, coprname=coprname, form=form)
+@coprs_ns.route("/<username>/<coprname>/new_build_rebuild/int:build_id/", methods=["POST"]) +@login_required +def copr_new_build_rebuild(username, coprname, build_id): + source_build = builds_logic.BuildsLogic.get(build_id).first() + copr = coprs_logic.CoprsLogic.get(username, coprname).first() + if not copr: + return page_not_found( + "Project {0}/{1} does not exist.".format(username, coprname)) + + if not source_build: + return page_not_found( + "Build {} does not exist!".format(form.build_id.data)) + + form = forms.BuildFormRebuildFactory.create_form_cls(copr.active_chroots)() + + if form.validate_on_submit(): + try: + build_options = { + "enable_net": form.enable_net.data, + "timeout": form.timeout.data, + } + + BuildsLogic.create_new_from_other_build( + flask.g.user, copr, source_build, + chroot_names=form.selected_chroots, + **build_options + ) + + except (ActionInProgressException, InsufficientRightsException) as e: + flask.flash(str(e), "error") + db.session.rollback() + else: + flask.flash("New build has been created", "success") + + db.session.commit() + + return flask.redirect(flask.url_for("coprs_ns.copr_builds", + username=username, + coprname=copr.name)) + else: + return copr_add_build(username=username, coprname=coprname, form=form) + + @coprs_ns.route("/<username>/<coprname>/cancel_build/int:build_id/", defaults={"page": 1}, methods=["POST"]) @@ -277,12 +320,12 @@ def copr_repeat_build(username, coprname, build_id, page=1): if not flask.g.user.can_build_in(build.copr): flask.flash("You are not allowed to repeat this build.")
- form = forms.BuildFormFactory.create_form_cls(copr.active_chroots)( - pkgs=build.pkgs, enable_net=build.enable_net, + form = forms.BuildFormRebuildFactory.create_form_cls(build.chroots)( + build_id=build_id, enable_net=build.enable_net, )
# remove all checkboxes by default - for ch in copr.active_chroots: + for ch in build.chroots: field = getattr(form, ch.name) field.data = False
@@ -302,8 +345,8 @@ def copr_repeat_build(username, coprname, build_id, page=1): if ch.name in chroots_to_select: getattr(form, ch.name).data = True
- return flask.render_template("coprs/detail/add_build/url.html", - copr=copr, form=form) + return flask.render_template("coprs/detail/add_build/rebuild.html", + copr=copr, build=build, form=form)
@coprs_ns.route("/<username>/<coprname>/delete_build/int:build_id/",
copr-commits@lists.fedorahosted.org