1 import flask
2 from flask import request, render_template, url_for, stream_with_context
3 import re
4 import os
5 import shutil
6 import tempfile
7
8 from functools import wraps
9 from werkzeug import secure_filename
10
11 from coprs import app
12 from coprs import db
13 from coprs import forms
14 from coprs import helpers
15
16 from coprs.logic import builds_logic
17 from coprs.logic import coprs_logic
18 from coprs.logic.builds_logic import BuildsLogic
19 from coprs.logic.complex_logic import ComplexLogic
20
21 from coprs.views.misc import (login_required, page_not_found, req_with_copr,
22 req_with_copr, send_build_icon)
23 from coprs.views.coprs_ns import coprs_ns
24
25 from coprs.exceptions import (ActionInProgressException,
26 InsufficientRightsException,
27 UnrepeatableBuildException)
35
36
37 @coprs_ns.route("/build/<int:build_id>/status_image.png")
38 -def copr_build_icon(build_id):
40
41
42
43
44 @coprs_ns.route("/<username>/<coprname>/build/<int:build_id>/")
45 @coprs_ns.route("/g/<group_name>/<coprname>/build/<int:build_id>/")
46 @req_with_copr
47 -def copr_build(copr, build_id):
49
54
55
56
57
58 @coprs_ns.route("/<username>/<coprname>/builds/")
59 @coprs_ns.route("/g/<group_name>/<coprname>/builds/")
60 @req_with_copr
61 -def copr_builds(copr):
63
77
78
79
80 @coprs_ns.route("/<username>/<coprname>/add_build/")
81 @coprs_ns.route("/g/<group_name>/<coprname>/add_build/")
82 @login_required
83 @req_with_copr
84 -def copr_add_build(copr, form=None):
87
94
95
96 @coprs_ns.route("/<username>/<coprname>/new_build/", methods=["POST"])
97 @coprs_ns.route("/g/<group_name>/<coprname>/new_build/", methods=["POST"])
98 @login_required
99 @req_with_copr
100 -def copr_new_build(copr):
105
108 def factory(**build_options):
109 pkgs = form.pkgs.data.split("\n")
110 for pkg in pkgs:
111 BuildsLogic.create_new_from_url(
112 flask.g.user, copr, pkg,
113 chroot_names=form.selected_chroots,
114 **build_options
115 )
116 for pkg in pkgs:
117 flask.flash("New build has been created: {}".format(pkg), "success")
118
119 form = forms.BuildFormUrlFactory(copr.active_chroots)()
120 return process_new_build(copr, form, factory, render_add_build,
121 add_view, url_on_success, msg_on_success=False)
122
123
124 -def process_new_build(copr, form, create_new_build_factory, add_function, add_view, url_on_success, msg_on_success=True):
125 if form.validate_on_submit():
126 build_options = {
127 "enable_net": form.enable_net.data,
128 "timeout": form.timeout.data,
129 }
130
131 try:
132 create_new_build_factory(**build_options)
133 db.session.commit()
134 except (ActionInProgressException, InsufficientRightsException, UnrepeatableBuildException) as e:
135 db.session.rollback()
136 flask.flash(str(e), "error")
137 else:
138 if msg_on_success:
139 flask.flash("New build has been created.", "success")
140
141 return flask.redirect(url_on_success)
142 else:
143 return add_function(copr, form, add_view)
144
145
146
147
148 @coprs_ns.route("/<username>/<coprname>/add_build_scm/")
149 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_scm/")
150 @login_required
151 @req_with_copr
152 -def copr_add_build_scm(copr, form=None):
155
162
163
164 @coprs_ns.route("/<username>/<coprname>/new_build_scm/", methods=["POST"])
165 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_scm/", methods=["POST"])
166 @login_required
167 @req_with_copr
168 -def copr_new_build_scm(copr):
172
188 form = forms.BuildFormScmFactory(copr.active_chroots)()
189 return process_new_build(copr, form, factory, render_add_build_scm, add_view, url_on_success)
190
191
192
193
194 @coprs_ns.route("/<username>/<coprname>/add_build_pypi/")
195 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_pypi/")
196 @login_required
197 @req_with_copr
198 -def copr_add_build_pypi(copr, form=None):
201
208
209
210 @coprs_ns.route("/<username>/<coprname>/new_build_pypi/", methods=["POST"])
211 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_pypi/", methods=["POST"])
212 @login_required
213 @req_with_copr
214 -def copr_new_build_pypi(copr):
218
231 form = forms.BuildFormPyPIFactory(copr.active_chroots)()
232 return process_new_build(copr, form, factory, render_add_build_pypi, add_view, url_on_success)
233
234
235
236
237 @coprs_ns.route("/<username>/<coprname>/add_build_rubygems/")
238 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_rubygems/")
239 @login_required
240 @req_with_copr
241 -def copr_add_build_rubygems(copr, form=None):
244
251
252
253 @coprs_ns.route("/<username>/<coprname>/new_build_rubygems/", methods=["POST"])
254 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_rubygems/", methods=["POST"])
255 @login_required
256 @req_with_copr
257 -def copr_new_build_rubygems(copr):
261
272 form = forms.BuildFormRubyGemsFactory(copr.active_chroots)()
273 return process_new_build(copr, form, factory, render_add_build_rubygems, add_view, url_on_success)
274
275
276
277 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_custom/", methods=["POST"])
278 @coprs_ns.route("/<username>/<coprname>/new_build_custom/", methods=["POST"])
279 @login_required
280 @req_with_copr
281 -def copr_new_build_custom(copr):
299
300 form = forms.BuildFormCustomFactory(copr.active_chroots)()
301
302 return process_new_build(copr, form, factory, render_add_build_custom,
303 view, url_on_success)
304
305
306
307 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_custom/")
308 @coprs_ns.route("/<username>/<coprname>/add_build_custom/")
309 @login_required
310 @req_with_copr
311 -def copr_add_build_custom(copr, form=None):
314
320
321
322
323
324 @coprs_ns.route("/<username>/<coprname>/add_build_upload/")
325 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_upload/")
326 @login_required
327 @req_with_copr
328 -def copr_add_build_upload(copr, form=None):
331
338
339
340 @coprs_ns.route("/<username>/<coprname>/new_build_upload/", methods=["POST"])
341 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_upload/", methods=["POST"])
342 @login_required
343 @req_with_copr
344 -def copr_new_build_upload(copr):
348
359 form = forms.BuildFormUploadFactory(copr.active_chroots)()
360 return process_new_build(copr, form, factory, render_add_build_upload, add_view, url_on_success)
361
362
363
364
365 @coprs_ns.route("/<username>/<coprname>/new_build_rebuild/<int:build_id>/", methods=["POST"])
366 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_rebuild/<int:build_id>/", methods=["POST"])
367 @login_required
368 @req_with_copr
369 -def copr_new_build_rebuild(copr, build_id):
373
383 form = forms.BuildFormRebuildFactory.create_form_cls(copr.active_chroots)()
384 return process_new_build(copr, form, factory, render_add_build, view, url_on_success)
385
386
387
388
389 @coprs_ns.route("/<username>/<coprname>/repeat_build/<int:build_id>/", methods=["GET", "POST"])
390 @coprs_ns.route("/g/<group_name>/<coprname>/repeat_build/<int:build_id>/", methods=["GET", "POST"])
391 @login_required
392 @req_with_copr
393 -def copr_repeat_build(copr, build_id):
395
398 build = ComplexLogic.get_build_safe(build_id)
399 if not flask.g.user.can_build_in(build.copr):
400 flask.flash("You are not allowed to repeat this build.")
401
402 if build.source_type == helpers.BuildSourceEnum('upload'):
403
404
405 available_chroots = build.chroots
406
407 else:
408
409
410 available_chroots = copr.active_chroots
411
412 form = forms.BuildFormRebuildFactory.create_form_cls(available_chroots)(
413 build_id=build_id, enable_net=build.enable_net)
414
415
416 for ch in available_chroots:
417 field = getattr(form, ch.name)
418 field.data = False
419 chroot_to_build = request.args.get("chroot")
420 app.logger.debug("got param chroot: {}".format(chroot_to_build))
421 if chroot_to_build:
422
423 if hasattr(form, chroot_to_build):
424 getattr(form, chroot_to_build).data = True
425 else:
426 build_chroot_names = set(ch.name for ch in build.chroots)
427 build_failed_chroot_names = set(ch.name for ch in build.get_chroots_by_status([
428 helpers.StatusEnum('failed'), helpers.StatusEnum('canceled'),
429 ]))
430 for ch in available_chroots:
431
432 if (ch.name not in build_chroot_names) or (ch.name in build_failed_chroot_names):
433 getattr(form, ch.name).data = True
434 return flask.render_template(
435 "coprs/detail/add_build/rebuild.html",
436 copr=copr, build=build, form=form)
437
450
451
452 @coprs_ns.route("/<username>/<coprname>/cancel_build/<int:build_id>/", methods=["POST"])
453 @coprs_ns.route("/g/<group_name>/<coprname>/cancel_build/<int:build_id>/", methods=["POST"])
454 @login_required
455 @req_with_copr
456 -def copr_cancel_build(copr, build_id):
460
461
462
463
464 @coprs_ns.route("/<username>/<coprname>/delete_build/<int:build_id>/",
465 methods=["POST"])
479