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)
34
35
36
37
38 @coprs_ns.route("/<username>/<coprname>/build/<int:build_id>/")
39 @coprs_ns.route("/g/<group_name>/<coprname>/build/<int:build_id>/")
40 @req_with_copr
41 -def copr_build(copr, build_id):
43
48
49
50
51
52 @coprs_ns.route("/<username>/<coprname>/builds/")
53 @coprs_ns.route("/g/<group_name>/<coprname>/builds/")
54 @req_with_copr
55 -def copr_builds(copr):
57
64
65
66
67
68 @coprs_ns.route("/<username>/<coprname>/add_build/")
69 @coprs_ns.route("/g/<group_name>/<coprname>/add_build/")
70 @login_required
71 @req_with_copr
72 -def copr_add_build(copr, form=None):
75
82
83
84 @coprs_ns.route("/<username>/<coprname>/new_build/", methods=["POST"])
85 @coprs_ns.route("/g/<group_name>/<coprname>/new_build/", methods=["POST"])
86 @login_required
87 @req_with_copr
88 -def copr_new_build(copr):
93
96 def factory(**build_options):
97 pkgs = form.pkgs.data.split("\n")
98 for pkg in pkgs:
99 BuildsLogic.create_new_from_url(
100 flask.g.user, copr, pkg,
101 chroot_names=form.selected_chroots,
102 **build_options
103 )
104 for pkg in pkgs:
105 flask.flash("New build has been created: {}".format(pkg), "success")
106
107 form = forms.BuildFormUrlFactory(copr.active_chroots)()
108 return process_new_build(copr, form, factory, render_add_build,
109 add_view, url_on_success, msg_on_success=False)
110
111
112 -def process_new_build(copr, form, create_new_build_factory, add_function, add_view, url_on_success, msg_on_success=True):
113 if form.validate_on_submit():
114 build_options = {
115 "enable_net": form.enable_net.data,
116 "timeout": form.timeout.data,
117 }
118
119 try:
120 create_new_build_factory(**build_options)
121 db.session.commit()
122 except (ActionInProgressException, InsufficientRightsException, UnrepeatableBuildException) as e:
123 db.session.rollback()
124 flask.flash(str(e), "error")
125 else:
126 if msg_on_success:
127 flask.flash("New build has been created.", "success")
128
129 return flask.redirect(url_on_success)
130 else:
131 return add_function(copr, form, add_view)
132
133
134
135
136 @coprs_ns.route("/<username>/<coprname>/add_build_scm/")
137 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_scm/")
138 @login_required
139 @req_with_copr
140 -def copr_add_build_scm(copr, form=None):
143
150
151
152 @coprs_ns.route("/<username>/<coprname>/new_build_scm/", methods=["POST"])
153 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_scm/", methods=["POST"])
154 @login_required
155 @req_with_copr
156 -def copr_new_build_scm(copr):
160
176 form = forms.BuildFormScmFactory(copr.active_chroots)()
177 return process_new_build(copr, form, factory, render_add_build_scm, add_view, url_on_success)
178
179
180
181
182 @coprs_ns.route("/<username>/<coprname>/add_build_pypi/")
183 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_pypi/")
184 @login_required
185 @req_with_copr
186 -def copr_add_build_pypi(copr, form=None):
189
196
197
198 @coprs_ns.route("/<username>/<coprname>/new_build_pypi/", methods=["POST"])
199 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_pypi/", methods=["POST"])
200 @login_required
201 @req_with_copr
202 -def copr_new_build_pypi(copr):
206
219 form = forms.BuildFormPyPIFactory(copr.active_chroots)()
220 return process_new_build(copr, form, factory, render_add_build_pypi, add_view, url_on_success)
221
222
223
224
225 @coprs_ns.route("/<username>/<coprname>/add_build_rubygems/")
226 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_rubygems/")
227 @login_required
228 @req_with_copr
229 -def copr_add_build_rubygems(copr, form=None):
232
239
240
241 @coprs_ns.route("/<username>/<coprname>/new_build_rubygems/", methods=["POST"])
242 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_rubygems/", methods=["POST"])
243 @login_required
244 @req_with_copr
245 -def copr_new_build_rubygems(copr):
249
260 form = forms.BuildFormRubyGemsFactory(copr.active_chroots)()
261 return process_new_build(copr, form, factory, render_add_build_rubygems, add_view, url_on_success)
262
263
264
265 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_custom/", methods=["POST"])
266 @coprs_ns.route("/<username>/<coprname>/new_build_custom/", methods=["POST"])
267 @login_required
268 @req_with_copr
269 -def copr_new_build_custom(copr):
270 """ Handle the build request and redirect back. """
271
272
273 view = 'coprs_ns.copr_new_build_custom'
274 url_on_success = helpers.copr_url('coprs_ns.copr_add_build_custom', copr)
275
276 def factory(**build_options):
277 def cleanup_script(string):
278
279
280
281
282 string = string.replace('\r\n', '\n')
283
284
285 if not string.endswith('\n'):
286 string += '\n'
287
288 return string
289
290 BuildsLogic.create_new_from_custom(
291 flask.g.user,
292 copr,
293 cleanup_script(form.script.data),
294 form.chroot.data,
295 form.builddeps.data,
296 form.resultdir.data,
297 chroot_names=form.selected_chroots,
298 **build_options
299 )
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