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