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
78
79
80
81 @coprs_ns.route("/<username>/<coprname>/add_build/")
82 @coprs_ns.route("/g/<group_name>/<coprname>/add_build/")
83 @login_required
84 @req_with_copr
85 -def copr_add_build(copr, form=None):
88
95
96
97 @coprs_ns.route("/<username>/<coprname>/new_build/", methods=["POST"])
98 @coprs_ns.route("/g/<group_name>/<coprname>/new_build/", methods=["POST"])
99 @login_required
100 @req_with_copr
101 -def copr_new_build(copr):
106
109 def factory(**build_options):
110 pkgs = form.pkgs.data.split("\n")
111 for pkg in pkgs:
112 BuildsLogic.create_new_from_url(
113 flask.g.user, copr, pkg,
114 chroot_names=form.selected_chroots,
115 **build_options
116 )
117 for pkg in pkgs:
118 flask.flash("New build has been created: {}".format(pkg), "success")
119
120 form = forms.BuildFormUrlFactory(copr.active_chroots)()
121 return process_new_build(copr, form, factory, render_add_build,
122 add_view, url_on_success, msg_on_success=False)
123
124
125 -def process_new_build(copr, form, create_new_build_factory, add_function, add_view, url_on_success, msg_on_success=True):
126 if form.validate_on_submit():
127 build_options = {
128 "enable_net": form.enable_net.data,
129 "timeout": form.timeout.data,
130 }
131
132 try:
133 create_new_build_factory(**build_options)
134 db.session.commit()
135 except (ActionInProgressException, InsufficientRightsException, UnrepeatableBuildException) as e:
136 db.session.rollback()
137 flask.flash(str(e), "error")
138 else:
139 if msg_on_success:
140 flask.flash("New build has been created.", "success")
141
142 return flask.redirect(url_on_success)
143 else:
144 return add_function(copr, form, add_view)
145
146
147
148
149 @coprs_ns.route("/<username>/<coprname>/add_build_scm/")
150 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_scm/")
151 @login_required
152 @req_with_copr
153 -def copr_add_build_scm(copr, form=None):
156
163
164
165 @coprs_ns.route("/<username>/<coprname>/new_build_scm/", methods=["POST"])
166 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_scm/", methods=["POST"])
167 @login_required
168 @req_with_copr
169 -def copr_new_build_scm(copr):
173
189 form = forms.BuildFormScmFactory(copr.active_chroots)()
190 return process_new_build(copr, form, factory, render_add_build_scm, add_view, url_on_success)
191
192
193
194
195 @coprs_ns.route("/<username>/<coprname>/add_build_pypi/")
196 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_pypi/")
197 @login_required
198 @req_with_copr
199 -def copr_add_build_pypi(copr, form=None):
202
209
210
211 @coprs_ns.route("/<username>/<coprname>/new_build_pypi/", methods=["POST"])
212 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_pypi/", methods=["POST"])
213 @login_required
214 @req_with_copr
215 -def copr_new_build_pypi(copr):
219
232 form = forms.BuildFormPyPIFactory(copr.active_chroots)()
233 return process_new_build(copr, form, factory, render_add_build_pypi, add_view, url_on_success)
234
235
236
237
238 @coprs_ns.route("/<username>/<coprname>/add_build_rubygems/")
239 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_rubygems/")
240 @login_required
241 @req_with_copr
242 -def copr_add_build_rubygems(copr, form=None):
245
252
253
254 @coprs_ns.route("/<username>/<coprname>/new_build_rubygems/", methods=["POST"])
255 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_rubygems/", methods=["POST"])
256 @login_required
257 @req_with_copr
258 -def copr_new_build_rubygems(copr):
262
273 form = forms.BuildFormRubyGemsFactory(copr.active_chroots)()
274 return process_new_build(copr, form, factory, render_add_build_rubygems, add_view, url_on_success)
275
276
277
278 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_custom/", methods=["POST"])
279 @coprs_ns.route("/<username>/<coprname>/new_build_custom/", methods=["POST"])
280 @login_required
281 @req_with_copr
282 -def copr_new_build_custom(copr):
300
301 form = forms.BuildFormCustomFactory(copr.active_chroots)()
302
303 return process_new_build(copr, form, factory, render_add_build_custom,
304 view, url_on_success)
305
306
307
308 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_custom/")
309 @coprs_ns.route("/<username>/<coprname>/add_build_custom/")
310 @login_required
311 @req_with_copr
312 -def copr_add_build_custom(copr, form=None):
315
321
322
323
324
325 @coprs_ns.route("/<username>/<coprname>/add_build_upload/")
326 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_upload/")
327 @login_required
328 @req_with_copr
329 -def copr_add_build_upload(copr, form=None):
332
339
340
341 @coprs_ns.route("/<username>/<coprname>/new_build_upload/", methods=["POST"])
342 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_upload/", methods=["POST"])
343 @login_required
344 @req_with_copr
345 -def copr_new_build_upload(copr):
349
360 form = forms.BuildFormUploadFactory(copr.active_chroots)()
361 return process_new_build(copr, form, factory, render_add_build_upload, add_view, url_on_success)
362
363
364
365
366 @coprs_ns.route("/<username>/<coprname>/new_build_rebuild/<int:build_id>/", methods=["POST"])
367 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_rebuild/<int:build_id>/", methods=["POST"])
368 @login_required
369 @req_with_copr
370 -def copr_new_build_rebuild(copr, build_id):
374
384 form = forms.BuildFormRebuildFactory.create_form_cls(copr.active_chroots)()
385 return process_new_build(copr, form, factory, render_add_build, view, url_on_success)
386
387
388
389
390 @coprs_ns.route("/<username>/<coprname>/repeat_build/<int:build_id>/", methods=["GET", "POST"])
391 @coprs_ns.route("/g/<group_name>/<coprname>/repeat_build/<int:build_id>/", methods=["GET", "POST"])
392 @login_required
393 @req_with_copr
394 -def copr_repeat_build(copr, build_id):
396
399 build = ComplexLogic.get_build_safe(build_id)
400 if not flask.g.user.can_build_in(build.copr):
401 flask.flash("You are not allowed to repeat this build.")
402
403 if build.source_type == helpers.BuildSourceEnum('upload'):
404
405
406 available_chroots = build.chroots
407
408 else:
409
410
411 available_chroots = copr.active_chroots
412
413 form = forms.BuildFormRebuildFactory.create_form_cls(available_chroots)(
414 build_id=build_id, enable_net=build.enable_net)
415
416
417 for ch in available_chroots:
418 field = getattr(form, ch.name)
419 field.data = False
420 chroot_to_build = request.args.get("chroot")
421 app.logger.debug("got param chroot: {}".format(chroot_to_build))
422 if chroot_to_build:
423
424 if hasattr(form, chroot_to_build):
425 getattr(form, chroot_to_build).data = True
426 else:
427 build_chroot_names = set(ch.name for ch in build.chroots)
428 build_failed_chroot_names = set(ch.name for ch in build.get_chroots_by_status([
429 helpers.StatusEnum('failed'), helpers.StatusEnum('canceled'),
430 ]))
431 for ch in available_chroots:
432
433 if (ch.name not in build_chroot_names) or (ch.name in build_failed_chroot_names):
434 getattr(form, ch.name).data = True
435 return flask.render_template(
436 "coprs/detail/add_build/rebuild.html",
437 copr=copr, build=build, form=form)
438
451
452
453 @coprs_ns.route("/<username>/<coprname>/cancel_build/<int:build_id>/", methods=["POST"])
454 @coprs_ns.route("/g/<group_name>/<coprname>/cancel_build/<int:build_id>/", methods=["POST"])
455 @login_required
456 @req_with_copr
457 -def copr_cancel_build(copr, build_id):
461
462
463
464
465 @coprs_ns.route("/<username>/<coprname>/delete_build/<int:build_id>/",
466 methods=["POST"])
480