Package coprs :: Package views :: Package coprs_ns :: Module coprs_builds
[hide private]
[frames] | no frames]

Source Code for Module coprs.views.coprs_ns.coprs_builds

  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 werkzeug import secure_filename 
  9   
 10  from coprs import app 
 11  from coprs import db 
 12  from coprs import forms 
 13  from coprs import helpers 
 14   
 15  from coprs.logic import builds_logic 
 16  from coprs.logic import coprs_logic 
 17  from coprs.logic.builds_logic import BuildsLogic 
 18  from coprs.logic.complex_logic import ComplexLogic 
 19   
 20  from coprs.views.misc import login_required, page_not_found, req_with_copr, req_with_copr 
 21  from coprs.views.coprs_ns import coprs_ns 
 22   
 23  from coprs.exceptions import (ActionInProgressException, 
 24                                InsufficientRightsException,) 
25 26 27 @coprs_ns.route("/build/<int:build_id>/") 28 -def copr_build_redirect(build_id):
29 build = ComplexLogic.get_build_safe(build_id) 30 copr = build.copr 31 if copr.is_a_group_project: 32 return flask.redirect(url_for( 33 "coprs_ns.group_copr_build", 34 group_name=build.copr.group.name, 35 coprname=build.copr.name, 36 build_id=build_id)) 37 else: 38 return flask.redirect(url_for( 39 "coprs_ns.copr_build", 40 username=build.copr.user.name, 41 coprname=build.copr.name, 42 build_id=build_id))
43
44 45 ################################ Build detail ################################ 46 47 @coprs_ns.route("/<username>/<coprname>/build/<int:build_id>/") 48 @req_with_copr 49 -def copr_build(copr, build_id):
50 return render_copr_build(build_id, copr)
51
52 53 @coprs_ns.route("/g/<group_name>/<coprname>/build/<int:build_id>/") 54 @req_with_copr 55 -def group_copr_build(copr, build_id):
56 return render_copr_build(build_id, copr)
57
58 59 -def render_copr_build(build_id, copr):
60 build = ComplexLogic.get_build_safe(build_id) 61 return render_template("coprs/detail/build.html", build=build, copr=copr)
62
63 64 ################################ Build table ################################ 65 66 @coprs_ns.route("/<username>/<coprname>/builds/") 67 @req_with_copr 68 -def copr_builds(copr):
69 return render_copr_builds(copr)
70
71 72 @coprs_ns.route("/g/<group_name>/<coprname>/builds/") 73 @req_with_copr 74 -def group_copr_builds(copr):
75 return render_copr_builds(copr)
76
77 78 -def render_copr_builds(copr):
79 builds_query = builds_logic.BuildsLogic.get_copr_builds_list(copr=copr) 80 return flask.Response(stream_with_context(helpers.stream_template("coprs/detail/builds.html", 81 copr=copr, 82 builds=list(builds_query))))
83
84 85 ################################ Url builds ################################ 86 87 @coprs_ns.route("/<username>/<coprname>/add_build/") 88 @login_required 89 @req_with_copr 90 -def copr_add_build(copr, form=None):
91 return render_add_build( 92 copr, form, view='coprs_ns.copr_new_build')
93
94 95 @coprs_ns.route("/g/<group_name>/<coprname>/add_build/") 96 @login_required 97 @req_with_copr 98 -def group_copr_add_build(copr, form=None):
99 return render_add_build( 100 copr, form, view='coprs_ns.copr_new_build')
101
102 103 -def render_add_build(copr, form, view):
104 if not form: 105 form = forms.BuildFormUrlFactory(copr.active_chroots)() 106 return flask.render_template("coprs/detail/add_build/url.html", 107 copr=copr, view=view, form=form)
108 109 110 @coprs_ns.route("/<username>/<coprname>/new_build/", methods=["POST"])
111 @login_required 112 @req_with_copr 113 -def copr_new_build(copr):
114 return process_new_build_url( 115 copr, 116 "coprs_ns.copr_new_build", 117 url_on_success=url_for("coprs_ns.copr_builds", 118 username=copr.user.username, coprname=copr.name) 119 )
120 121 122 @coprs_ns.route("/g/<group_name>/<coprname>/new_build/", methods=["POST"])
123 @login_required 124 @req_with_copr 125 -def group_copr_new_build(copr):
126 return process_new_build_url( 127 copr, 128 "coprs_ns.copr_new_build", 129 url_on_success=url_for("coprs_ns.group_copr_builds", 130 group_name=copr.group.name, coprname=copr.name) 131 )
132
133 134 -def process_new_build_url(copr, add_view, url_on_success):
135 def factory(**build_options): 136 pkgs = form.pkgs.data.split("\n") 137 for pkg in pkgs: 138 BuildsLogic.create_new_from_url( 139 flask.g.user, copr, pkg, 140 chroot_names=form.selected_chroots, 141 **build_options 142 ) 143 for pkg in pkgs: 144 flask.flash("New build has been created: {}".format(pkg), "success")
145 146 form = forms.BuildFormUrlFactory(copr.active_chroots)() 147 return process_new_build(copr, form, factory, render_add_build, 148 add_view, url_on_success, msg_on_success=False) 149
150 151 -def process_new_build(copr, form, create_new_build_factory, add_function, add_view, url_on_success, msg_on_success=True):
152 if form.validate_on_submit(): 153 build_options = { 154 "enable_net": form.enable_net.data, 155 "timeout": form.timeout.data, 156 } 157 158 try: 159 create_new_build_factory(**build_options) 160 db.session.commit() 161 except (ActionInProgressException, InsufficientRightsException) as e: 162 db.session.rollback() 163 flask.flash(str(e), "error") 164 else: 165 if msg_on_success: 166 flask.flash("New build has been created.", "success") 167 168 return flask.redirect(url_on_success) 169 else: 170 return add_function(copr, form, add_view)
171
172 173 ################################ SCM builds ######################################### 174 175 @coprs_ns.route("/<username>/<coprname>/add_build_scm/") 176 @login_required 177 @req_with_copr 178 -def copr_add_build_scm(copr, form=None):
179 return render_add_build_scm( 180 copr, form, view='coprs_ns.copr_new_build_scm')
181
182 183 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_scm/") 184 @login_required 185 @req_with_copr 186 -def group_copr_add_build_scm(copr, form=None):
187 return render_add_build_scm( 188 copr, form, view='coprs_ns.copr_new_build_scm')
189
190 191 -def render_add_build_scm(copr, form, view, package=None):
192 if not form: 193 form = forms.BuildFormScmFactory(copr.active_chroots)() 194 return flask.render_template("coprs/detail/add_build/scm.html", 195 copr=copr, form=form, view=view, package=package)
196 197 198 @coprs_ns.route("/<username>/<coprname>/new_build_scm/", methods=["POST"])
199 @login_required 200 @req_with_copr 201 -def copr_new_build_scm(copr):
202 view = 'coprs_ns.copr_new_build_scm' 203 url_on_success = url_for("coprs_ns.copr_builds", 204 username=copr.user.username, coprname=copr.name) 205 return process_new_build_scm(copr, view, url_on_success)
206 207 208 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_scm/", methods=["POST"])
209 @login_required 210 @req_with_copr 211 -def group_copr_new_build_scm(copr):
212 view = 'coprs_ns.copr_new_build_scm' 213 url_on_success = url_for("coprs_ns.group_copr_builds", 214 group_name=copr.group.name, coprname=copr.name) 215 return process_new_build_scm(copr, view, url_on_success)
216
217 218 -def process_new_build_scm(copr, add_view, url_on_success):
219 def factory(**build_options): 220 BuildsLogic.create_new_from_scm( 221 flask.g.user, 222 copr, 223 form.scm_type.data, 224 form.clone_url.data, 225 form.committish.data, 226 form.subdirectory.data, 227 form.spec.data, 228 form.srpm_build_method.data, 229 form.selected_chroots, 230 **build_options 231 )
232 form = forms.BuildFormScmFactory(copr.active_chroots)() 233 return process_new_build(copr, form, factory, render_add_build_scm, add_view, url_on_success) 234
235 236 ################################ PyPI builds ################################ 237 238 @coprs_ns.route("/<username>/<coprname>/add_build_pypi/") 239 @login_required 240 @req_with_copr 241 -def copr_add_build_pypi(copr, form=None):
242 return render_add_build_pypi( 243 copr, form, view='coprs_ns.copr_new_build_pypi')
244
245 246 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_pypi/") 247 @login_required 248 @req_with_copr 249 -def group_copr_add_build_pypi(copr, form=None):
250 return render_add_build_pypi( 251 copr, form, view='coprs_ns.copr_new_build_pypi')
252
253 254 -def render_add_build_pypi(copr, form, view, package=None):
255 if not form: 256 form = forms.BuildFormPyPIFactory(copr.active_chroots)() 257 return flask.render_template("coprs/detail/add_build/pypi.html", 258 copr=copr, form=form, view=view, package=package)
259 260 261 @coprs_ns.route("/<username>/<coprname>/new_build_pypi/", methods=["POST"])
262 @login_required 263 @req_with_copr 264 -def copr_new_build_pypi(copr):
265 view = 'coprs_ns.copr_new_build_pypi' 266 url_on_success = url_for("coprs_ns.copr_builds", 267 username=copr.user.username, coprname=copr.name) 268 return process_new_build_pypi(copr, view, url_on_success)
269 270 271 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_pypi/", methods=["POST"])
272 @login_required 273 @req_with_copr 274 -def group_copr_new_build_pypi(copr):
275 view = 'coprs_ns.copr_new_build_pypi' 276 url_on_success = url_for("coprs_ns.group_copr_builds", 277 group_name=copr.group.name, coprname=copr.name) 278 return process_new_build_pypi(copr, view, url_on_success)
279
280 281 -def process_new_build_pypi(copr, add_view, url_on_success):
282 def factory(**build_options): 283 BuildsLogic.create_new_from_pypi( 284 flask.g.user, 285 copr, 286 form.pypi_package_name.data, 287 form.pypi_package_version.data, 288 form.python_versions.data, 289 form.selected_chroots, 290 **build_options 291 )
292 form = forms.BuildFormPyPIFactory(copr.active_chroots)() 293 return process_new_build(copr, form, factory, render_add_build_pypi, add_view, url_on_success) 294
295 296 ############################### RubyGems builds ############################### 297 298 @coprs_ns.route("/<username>/<coprname>/add_build_rubygems/") 299 @login_required 300 @req_with_copr 301 -def copr_add_build_rubygems(copr, form=None):
302 return render_add_build_rubygems( 303 copr, form, view='coprs_ns.copr_new_build_rubygems')
304
305 306 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_rubygems/") 307 @login_required 308 @req_with_copr 309 -def group_copr_add_build_rubygems(copr, form=None):
310 return render_add_build_rubygems( 311 copr, form, view='coprs_ns.copr_new_build_rubygems')
312
313 314 -def render_add_build_rubygems(copr, form, view, package=None):
315 if not form: 316 form = forms.BuildFormRubyGemsFactory(copr.active_chroots)() 317 return flask.render_template("coprs/detail/add_build/rubygems.html", 318 copr=copr, form=form, view=view, package=package)
319 320 321 @coprs_ns.route("/<username>/<coprname>/new_build_rubygems/", methods=["POST"])
322 @login_required 323 @req_with_copr 324 -def copr_new_build_rubygems(copr):
325 view = 'coprs_ns.copr_new_build_rubygems' 326 url_on_success = url_for("coprs_ns.copr_builds", 327 username=copr.user.username, coprname=copr.name) 328 return process_new_build_rubygems(copr, view, url_on_success)
329 330 331 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_rubygems/", methods=["POST"])
332 @login_required 333 @req_with_copr 334 -def group_copr_new_build_rubygems(copr):
335 view = 'coprs_ns.copr_new_build_rubygems' 336 url_on_success = url_for("coprs_ns.group_copr_builds", 337 group_name=copr.group.name, coprname=copr.name) 338 return process_new_build_rubygems(copr, view, url_on_success)
339
340 341 -def process_new_build_rubygems(copr, add_view, url_on_success):
342 def factory(**build_options): 343 BuildsLogic.create_new_from_rubygems( 344 flask.g.user, 345 copr, 346 form.gem_name.data, 347 form.selected_chroots, 348 **build_options 349 )
350 form = forms.BuildFormRubyGemsFactory(copr.active_chroots)() 351 return process_new_build(copr, form, factory, render_add_build_rubygems, add_view, url_on_success) 352
353 354 ################################ Upload builds ################################ 355 356 @coprs_ns.route("/<username>/<coprname>/add_build_upload/") 357 @login_required 358 @req_with_copr 359 -def copr_add_build_upload(copr, form=None):
360 return render_add_build_upload( 361 copr, form, view='coprs_ns.copr_new_build_upload')
362
363 364 @coprs_ns.route("/g/<group_name>/<coprname>/add_build_upload/") 365 @login_required 366 @req_with_copr 367 -def group_copr_add_build_upload(copr, form=None):
368 return render_add_build_upload( 369 copr, form, view='coprs_ns.copr_new_build_upload')
370
371 372 -def render_add_build_upload(copr, form, view):
373 if not form: 374 form = forms.BuildFormUploadFactory(copr.active_chroots)() 375 return flask.render_template("coprs/detail/add_build/upload.html", 376 copr=copr, form=form, view=view)
377 378 379 @coprs_ns.route("/<username>/<coprname>/new_build_upload/", methods=["POST"])
380 @login_required 381 @req_with_copr 382 -def copr_new_build_upload(copr):
383 view = 'coprs_ns.copr_new_build_upload' 384 url_on_success = url_for("coprs_ns.copr_builds", 385 username=copr.user.username, coprname=copr.name) 386 return process_new_build_upload(copr, view, url_on_success)
387 388 389 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_upload/", methods=["POST"])
390 @login_required 391 @req_with_copr 392 -def group_copr_new_build_upload(copr):
393 view = 'coprs_ns.copr_new_build_upload' 394 url_on_success = url_for("coprs_ns.group_copr_builds", 395 group_name=copr.group.name, coprname=copr.name) 396 return process_new_build_upload(copr, view, url_on_success)
397
398 399 -def process_new_build_upload(copr, add_view, url_on_success):
400 def factory(**build_options): 401 BuildsLogic.create_new_from_upload( 402 flask.g.user, copr, 403 f_uploader=lambda path: form.pkgs.data.save(path), 404 orig_filename=form.pkgs.data.filename, 405 chroot_names=form.selected_chroots, 406 **build_options 407 )
408 form = forms.BuildFormUploadFactory(copr.active_chroots)() 409 return process_new_build(copr, form, factory, render_add_build_upload, add_view, url_on_success) 410 411 412 ################################ Builds rebuilds ################################ 413 414 @coprs_ns.route("/<username>/<coprname>/new_build_rebuild/<int:build_id>/", methods=["POST"])
415 @login_required 416 @req_with_copr 417 -def copr_new_build_rebuild(copr, build_id):
418 view='coprs_ns.copr_new_build' 419 url_on_success = url_for( 420 "coprs_ns.copr_builds", 421 username=copr.user.username, coprname=copr.name) 422 423 return process_rebuild(copr, build_id, view=view, url_on_success=url_on_success)
424 425 426 @coprs_ns.route("/g/<group_name>/<coprname>/new_build_rebuild/<int:build_id>/", methods=["POST"])
427 @login_required 428 @req_with_copr 429 -def group_copr_new_build_rebuild(copr, build_id):
430 view='coprs_ns.copr_new_build' 431 url_on_success = url_for( 432 "coprs_ns.group_copr_builds", 433 group_name=copr.group.name, coprname=copr.name) 434 435 return process_rebuild(copr, build_id, view=view, url_on_success=url_on_success)
436
437 438 -def process_rebuild(copr, build_id, view, url_on_success):
439 def factory(**build_options): 440 source_build = ComplexLogic.get_build_safe(build_id) 441 BuildsLogic.create_new_from_other_build( 442 flask.g.user, copr, source_build, 443 chroot_names=form.selected_chroots, 444 **build_options 445 )
446 form = forms.BuildFormRebuildFactory.create_form_cls(copr.active_chroots)() 447 return process_new_build(copr, form, factory, render_add_build, view, url_on_success) 448 449 450 ################################ Repeat ################################ 451 452 @coprs_ns.route("/<username>/<coprname>/repeat_build/<int:build_id>/", 453 methods=["GET", "POST"])
454 @login_required 455 @req_with_copr 456 -def copr_repeat_build(copr, build_id):
457 return process_copr_repeat_build(build_id, copr)
458 459 460 @coprs_ns.route("/g/<group_name>/<coprname>/repeat_build/<int:build_id>/", 461 methods=["GET", "POST"])
462 @login_required 463 @req_with_copr 464 -def group_copr_repeat_build(copr, build_id):
465 return process_copr_repeat_build(build_id, copr)
466
467 468 -def process_copr_repeat_build(build_id, copr):
469 build = ComplexLogic.get_build_safe(build_id) 470 if not flask.g.user.can_build_in(build.copr): 471 flask.flash("You are not allowed to repeat this build.") 472 473 if build.source_type == helpers.BuildSourceEnum('upload'): 474 # If the original build's source is 'upload', we will show only the 475 # original build's chroots and skip import. 476 available_chroots = build.chroots 477 478 else: 479 # For all other sources, we will show all chroots enabled in the project 480 # and proceed with import. 481 available_chroots = copr.active_chroots 482 483 form = forms.BuildFormRebuildFactory.create_form_cls(available_chroots)( 484 build_id=build_id, enable_net=build.enable_net) 485 486 # remove all checkboxes by default 487 for ch in available_chroots: 488 field = getattr(form, ch.name) 489 field.data = False 490 chroot_to_build = request.args.get("chroot") 491 app.logger.debug("got param chroot: {}".format(chroot_to_build)) 492 if chroot_to_build: 493 # set single checkbox if chroot query arg was provided 494 if hasattr(form, chroot_to_build): 495 getattr(form, chroot_to_build).data = True 496 else: 497 build_chroot_names = set(ch.name for ch in build.chroots) 498 build_failed_chroot_names = set(ch.name for ch in build.get_chroots_by_status([ 499 helpers.StatusEnum('failed'), helpers.StatusEnum('canceled'), 500 ])) 501 for ch in available_chroots: 502 # check checkbox on all the chroots that have not been (successfully) built before 503 if (ch.name not in build_chroot_names) or (ch.name in build_failed_chroot_names): 504 getattr(form, ch.name).data = True 505 return flask.render_template( 506 "coprs/detail/add_build/rebuild.html", 507 copr=copr, build=build, form=form)
508
509 510 ################################ Cancel ################################ 511 512 -def process_cancel_build(build):
513 try: 514 builds_logic.BuildsLogic.cancel_build(flask.g.user, build) 515 except InsufficientRightsException as e: 516 flask.flash(str(e), "error") 517 else: 518 db.session.commit() 519 flask.flash("Build {} has been canceled successfully.".format(build.id), "success") 520 return flask.redirect(helpers.url_for_copr_builds(build.copr))
521 522 523 @coprs_ns.route("/<username>/<coprname>/cancel_build/<int:build_id>/", 524 methods=["POST"])
525 @login_required 526 -def copr_cancel_build(username, coprname, build_id):
527 # only the user who ran the build can cancel it 528 build = ComplexLogic.get_build_safe(build_id) 529 return process_cancel_build(build)
530 531 532 @coprs_ns.route("/g/<group_name>/<coprname>/cancel_build/<int:build_id>/", 533 methods=["POST"])
534 @login_required 535 -def group_copr_cancel_build(group_name, coprname, build_id):
536 build = ComplexLogic.get_build_safe(build_id) 537 return process_cancel_build(build)
538 539 540 ################################ Delete ################################ 541 542 @coprs_ns.route("/<username>/<coprname>/delete_build/<int:build_id>/", 543 methods=["POST"])
544 @login_required 545 -def copr_delete_build(username, coprname, build_id):
546 build = ComplexLogic.get_build_safe(build_id) 547 548 try: 549 builds_logic.BuildsLogic.delete_build(flask.g.user, build) 550 except (InsufficientRightsException, ActionInProgressException) as e: 551 flask.flash(str(e), "error") 552 else: 553 db.session.commit() 554 flask.flash("Build has been deleted successfully.", "success") 555 556 return flask.redirect(helpers.url_for_copr_builds(build.copr))
557