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, req_with_copr
22 from coprs.views.coprs_ns import coprs_ns
23
24 from coprs.exceptions import (ActionInProgressException,
25 InsufficientRightsException,
26 UnrepeatableBuildException)
45
46
47
48
49 @coprs_ns.route("/<username>/<coprname>/build/<int:build_id>/")
50 @req_with_copr
51 -def copr_build(copr, build_id):
53
54
55 @coprs_ns.route("/g/<group_name>/<coprname>/build/<int:build_id>/")
56 @req_with_copr
57 -def group_copr_build(copr, build_id):
59
64
65
66
67
68 @coprs_ns.route("/<username>/<coprname>/builds/")
69 @req_with_copr
70 -def copr_builds(copr):
72
73
74 @coprs_ns.route("/g/<group_name>/<coprname>/builds/")
75 @req_with_copr
76 -def group_copr_builds(copr):
78
85
86
87
88
89 @coprs_ns.route("/<username>/<coprname>/add_build/")
90 @login_required
91 @req_with_copr
92 -def copr_add_build(copr, form=None):
95
96
97 @coprs_ns.route("/g/<group_name>/<coprname>/add_build/")
98 @login_required
99 @req_with_copr
100 -def group_copr_add_build(copr, form=None):
103
110
111
112 @coprs_ns.route("/<username>/<coprname>/new_build/", methods=["POST"])
113 @login_required
114 @req_with_copr
115 -def copr_new_build(copr):
122
123
124 @coprs_ns.route("/g/<group_name>/<coprname>/new_build/", methods=["POST"])
125 @login_required
126 @req_with_copr
127 -def group_copr_new_build(copr):
134
137 def factory(**build_options):
138 pkgs = form.pkgs.data.split("\n")
139 for pkg in pkgs:
140 BuildsLogic.create_new_from_url(
141 flask.g.user, copr, pkg,
142 chroot_names=form.selected_chroots,
143 **build_options
144 )
145 for pkg in pkgs:
146 flask.flash("New build has been created: {}".format(pkg), "success")
147
148 form = forms.BuildFormUrlFactory(copr.active_chroots)()
149 return process_new_build(copr, form, factory, render_add_build,
150 add_view, url_on_success, msg_on_success=False)
151
152
153 -def process_new_build(copr, form, create_new_build_factory, add_function, add_view, url_on_success, msg_on_success=True):
154 if form.validate_on_submit():
155 build_options = {
156 "enable_net": form.enable_net.data,
157 "timeout": form.timeout.data,
158 }
159
160 try:
161 create_new_build_factory(**build_options)
162 db.session.commit()
163 except (ActionInProgressException, InsufficientRightsException, UnrepeatableBuildException) as e:
164 db.session.rollback()
165 flask.flash(str(e), "error")
166 else:
167 if msg_on_success:
168 flask.flash("New build has been created.", "success")
169
170 return flask.redirect(url_on_success)
171 else:
172 return add_function(copr, form, add_view)
173
174
175
176
177 @coprs_ns.route("/<username>/<coprname>/add_build_scm/")
178 @login_required
179 @req_with_copr
180 -def copr_add_build_scm(copr, form=None):
183
184
185 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_scm/")
186 @login_required
187 @req_with_copr
188 -def group_copr_add_build_scm(copr, form=None):
191
198
199
200 @coprs_ns.route("/<username>/<coprname>/new_build_scm/", methods=["POST"])
201 @login_required
202 @req_with_copr
203 -def copr_new_build_scm(copr):
208
209
210 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_scm/", methods=["POST"])
211 @login_required
212 @req_with_copr
213 -def group_copr_new_build_scm(copr):
218
234 form = forms.BuildFormScmFactory(copr.active_chroots)()
235 return process_new_build(copr, form, factory, render_add_build_scm, add_view, url_on_success)
236
237
238
239
240 @coprs_ns.route("/<username>/<coprname>/add_build_pypi/")
241 @login_required
242 @req_with_copr
243 -def copr_add_build_pypi(copr, form=None):
246
247
248 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_pypi/")
249 @login_required
250 @req_with_copr
251 -def group_copr_add_build_pypi(copr, form=None):
254
261
262
263 @coprs_ns.route("/<username>/<coprname>/new_build_pypi/", methods=["POST"])
264 @login_required
265 @req_with_copr
266 -def copr_new_build_pypi(copr):
271
272
273 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_pypi/", methods=["POST"])
274 @login_required
275 @req_with_copr
276 -def group_copr_new_build_pypi(copr):
281
294 form = forms.BuildFormPyPIFactory(copr.active_chroots)()
295 return process_new_build(copr, form, factory, render_add_build_pypi, add_view, url_on_success)
296
297
298
299
300 @coprs_ns.route("/<username>/<coprname>/add_build_rubygems/")
301 @login_required
302 @req_with_copr
303 -def copr_add_build_rubygems(copr, form=None):
306
307
308 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_rubygems/")
309 @login_required
310 @req_with_copr
311 -def group_copr_add_build_rubygems(copr, form=None):
314
321
322
323 @coprs_ns.route("/<username>/<coprname>/new_build_rubygems/", methods=["POST"])
324 @login_required
325 @req_with_copr
326 -def copr_new_build_rubygems(copr):
331
332
333 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_rubygems/", methods=["POST"])
334 @login_required
335 @req_with_copr
336 -def group_copr_new_build_rubygems(copr):
341
352 form = forms.BuildFormRubyGemsFactory(copr.active_chroots)()
353 return process_new_build(copr, form, factory, render_add_build_rubygems, add_view, url_on_success)
354
355
356
357 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_custom/", methods=["POST"])
358 @coprs_ns.route("/<username>/<coprname>/new_build_custom/", methods=["POST"])
359 @login_required
360 @req_with_copr
361 -def copr_new_build_custom(copr):
379
380 form = forms.BuildFormCustomFactory(copr.active_chroots)()
381
382 return process_new_build(copr, form, factory, render_add_build_custom,
383 view, url_on_success)
384
385
386
387 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_custom/")
388 @coprs_ns.route("/<username>/<coprname>/add_build_custom/")
389 @login_required
390 @req_with_copr
391 -def copr_add_build_custom(copr, form=None):
394
400
401
402
403
404 @coprs_ns.route("/<username>/<coprname>/add_build_upload/")
405 @login_required
406 @req_with_copr
407 -def copr_add_build_upload(copr, form=None):
410
411
412 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_upload/")
413 @login_required
414 @req_with_copr
415 -def group_copr_add_build_upload(copr, form=None):
418
425
426
427 @coprs_ns.route("/<username>/<coprname>/new_build_upload/", methods=["POST"])
428 @login_required
429 @req_with_copr
430 -def copr_new_build_upload(copr):
435
436
437 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_upload/", methods=["POST"])
438 @login_required
439 @req_with_copr
440 -def group_copr_new_build_upload(copr):
445
456 form = forms.BuildFormUploadFactory(copr.active_chroots)()
457 return process_new_build(copr, form, factory, render_add_build_upload, add_view, url_on_success)
458
459
460
461
462 @coprs_ns.route("/<username>/<coprname>/new_build_rebuild/<int:build_id>/", methods=["POST"])
463 @login_required
464 @req_with_copr
465 -def copr_new_build_rebuild(copr, build_id):
472
473
474 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_rebuild/<int:build_id>/", methods=["POST"])
475 @login_required
476 @req_with_copr
477 -def group_copr_new_build_rebuild(copr, build_id):
484
494 form = forms.BuildFormRebuildFactory.create_form_cls(copr.active_chroots)()
495 return process_new_build(copr, form, factory, render_add_build, view, url_on_success)
496
497
498
499
500 @coprs_ns.route("/<username>/<coprname>/repeat_build/<int:build_id>/",
501 methods=["GET", "POST"])
506
507
508 @coprs_ns.route("/g/<group_name>/<coprname>/repeat_build/<int:build_id>/",
509 methods=["GET", "POST"])
514
517 build = ComplexLogic.get_build_safe(build_id)
518 if not flask.g.user.can_build_in(build.copr):
519 flask.flash("You are not allowed to repeat this build.")
520
521 if build.source_type == helpers.BuildSourceEnum('upload'):
522
523
524 available_chroots = build.chroots
525
526 else:
527
528
529 available_chroots = copr.active_chroots
530
531 form = forms.BuildFormRebuildFactory.create_form_cls(available_chroots)(
532 build_id=build_id, enable_net=build.enable_net)
533
534
535 for ch in available_chroots:
536 field = getattr(form, ch.name)
537 field.data = False
538 chroot_to_build = request.args.get("chroot")
539 app.logger.debug("got param chroot: {}".format(chroot_to_build))
540 if chroot_to_build:
541
542 if hasattr(form, chroot_to_build):
543 getattr(form, chroot_to_build).data = True
544 else:
545 build_chroot_names = set(ch.name for ch in build.chroots)
546 build_failed_chroot_names = set(ch.name for ch in build.get_chroots_by_status([
547 helpers.StatusEnum('failed'), helpers.StatusEnum('canceled'),
548 ]))
549 for ch in available_chroots:
550
551 if (ch.name not in build_chroot_names) or (ch.name in build_failed_chroot_names):
552 getattr(form, ch.name).data = True
553 return flask.render_template(
554 "coprs/detail/add_build/rebuild.html",
555 copr=copr, build=build, form=form)
556
569
570
571 @coprs_ns.route("/<username>/<coprname>/cancel_build/<int:build_id>/",
572 methods=["POST"])
578
579
580 @coprs_ns.route("/g/<group_name>/<coprname>/cancel_build/<int:build_id>/",
581 methods=["POST"])
586
587
588
589
590 @coprs_ns.route("/<username>/<coprname>/delete_build/<int:build_id>/",
591 methods=["POST"])
605