Trees | Indices | Help |
---|
|
1 import os 2 import time 3 4 from sqlalchemy import and_ 5 from sqlalchemy.sql import func 6 from sqlalchemy import asc 7 from sqlalchemy.event import listen 8 from sqlalchemy.orm.attributes import NEVER_SET 9 from sqlalchemy.orm.exc import NoResultFound 10 from sqlalchemy.orm.attributes import get_history 11 12 from coprs import db 13 from coprs import exceptions 14 from coprs import helpers 15 from coprs import models 16 from coprs.exceptions import MalformedArgumentException 17 from coprs.logic import users_logic 18 from coprs.whoosheers import CoprWhoosheer 19 from coprs.helpers import fix_protocol_for_backend 20 21 from coprs.logic.actions_logic import ActionsLogic 22 from coprs.logic.users_logic import UsersLogic26 """ 27 Used for manipulating Coprs. 28 29 All methods accept user object as a first argument, 30 as this may be needed in future. 31 """ 32 33 @classmethod37035 """ Return all coprs without those which are deleted. """ 36 query = (db.session.query(models.Copr) 37 .join(models.Copr.user) 38 .options(db.contains_eager(models.Copr.user)) 39 .filter(models.Copr.deleted == False)) 40 return query41 42 @classmethod 45 46 @classmethod48 query = (query.outerjoin(models.Copr.builds) 49 .options(db.contains_eager(models.Copr.builds)) 50 .order_by(models.Build.submitted_on.desc())) 51 return query52 53 @classmethod55 query = (query.outerjoin(*models.Copr.mock_chroots.attr) 56 .options(db.contains_eager(*models.Copr.mock_chroots.attr)) 57 .order_by(models.MockChroot.os_release.asc()) 58 .order_by(models.MockChroot.os_version.asc()) 59 .order_by(models.MockChroot.arch.asc())) 60 return query61 62 @classmethod64 with_builds = kwargs.get("with_builds", False) 65 with_mock_chroots = kwargs.get("with_mock_chroots", False) 66 67 query = ( 68 cls.get_all() 69 .filter(models.User.username == username) 70 ) 71 72 if with_builds: 73 query = cls.attach_build(query) 74 75 if with_mock_chroots: 76 query = cls.attach_mock_chroots(query) 77 78 return query79 80 @classmethod82 with_builds = kwargs.get("with_builds", False) 83 with_mock_chroots = kwargs.get("with_mock_chroots", False) 84 85 query = ( 86 cls.get_all() 87 .filter(models.Copr.group_id == group_id) 88 ) 89 90 if with_builds: 91 query = cls.attach_build(query) 92 93 if with_mock_chroots: 94 query = cls.attach_mock_chroots(query) 95 96 return query97 98 @classmethod100 query = cls.get_multiple_by_username(username, **kwargs) 101 query = query.filter(models.Copr.name == coprname) 102 return query103 104 @classmethod106 query = cls.get_multiple_by_group_id(group_id, **kwargs) 107 query = query.filter(models.Copr.name == coprname) 108 return query109 110 @classmethod112 query = ( 113 db.session.query(models.Copr) 114 .join(models.Copr.user) 115 .outerjoin(models.Group) 116 .options(db.contains_eager(models.Copr.user)) 117 ) 118 119 if not include_deleted: 120 query = query.filter(models.Copr.deleted.is_(False)) 121 122 if not include_unlisted_on_hp: 123 query = query.filter(models.Copr.unlisted_on_hp.is_(False)) 124 125 return query126 127 @classmethod129 if desc: 130 query = query.order_by(models.Copr.id.desc()) 131 else: 132 query = query.order_by(models.Copr.id.asc()) 133 return query134 135 # user_relation="owned", username=username, with_mock_chroots=False 136 @classmethod 140 141 @classmethod 144 145 @classmethod147 # should be already joined with the User table 148 return query.filter(models.User.username == username)149 150 @classmethod152 # should be already joined with the Group table 153 return query.filter(models.Group.name == group_name)154 155 @classmethod 158 159 @classmethod161 return (query.outerjoin(models.Copr.builds) 162 .options(db.contains_eager(models.Copr.builds)) 163 .order_by(models.Build.submitted_on.desc()))164 165 @classmethod167 return (query.outerjoin(*models.Copr.mock_chroots.attr) 168 .options(db.contains_eager(*models.Copr.mock_chroots.attr)) 169 .order_by(models.MockChroot.os_release.asc()) 170 .order_by(models.MockChroot.os_version.asc()) 171 .order_by(models.MockChroot.arch.asc()))172 173 @classmethod 176 177 @classmethod179 if user.admin: 180 db.session.add(copr) 181 pass 182 else: 183 raise exceptions.InsufficientRightsException( 184 "User is not a system admin")185 186 @classmethod188 query = (models.Copr.query.join(models.User) 189 .filter(models.Copr.deleted == False)) 190 if "/" in search_string: # copr search by its full name 191 if search_string[0] == '@': # searching for @group/project 192 group_name = "%{}%".format(search_string.split("/")[0][1:]) 193 project = "%{}%".format(search_string.split("/")[1]) 194 query = query.filter(and_(models.Group.name.ilike(group_name), 195 models.Copr.name.ilike(project), 196 models.Group.id == models.Copr.group_id)) 197 query = query.order_by(asc(func.length(models.Group.name)+func.length(models.Copr.name))) 198 else: # searching for user/project 199 user_name = "%{}%".format(search_string.split("/")[0]) 200 project = "%{}%".format(search_string.split("/")[1]) 201 query = query.filter(and_(models.User.username.ilike(user_name), 202 models.Copr.name.ilike(project), 203 models.User.id == models.Copr.user_id)) 204 query = query.order_by(asc(func.length(models.User.username)+func.length(models.Copr.name))) 205 else: # fulltext search 206 query = query.whooshee_search(search_string, whoosheer=CoprWhoosheer) 207 return query208 209 @classmethod210 - def add(cls, user, name, selected_chroots, repos=None, description=None, 211 instructions=None, check_for_duplicates=False, group=None, persistent=False, 212 auto_prune=True, use_bootstrap_container=False, follow_fedora_branching=False, **kwargs):213 214 if not user.admin and persistent: 215 raise exceptions.NonAdminCannotCreatePersistentProject() 216 217 if not user.admin and not auto_prune: 218 raise exceptions.NonAdminCannotDisableAutoPrunning() 219 220 # form validation checks for duplicates 221 cls.new(user, name, group, check_for_duplicates=check_for_duplicates) 222 223 copr = models.Copr(name=name, 224 repos=repos or u"", 225 user=user, 226 description=description or u"", 227 instructions=instructions or u"", 228 created_on=int(time.time()), 229 persistent=persistent, 230 auto_prune=auto_prune, 231 use_bootstrap_container=use_bootstrap_container, 232 follow_fedora_branching=follow_fedora_branching, 233 **kwargs) 234 235 236 if group is not None: 237 UsersLogic.raise_if_not_in_group(user, group) 238 copr.group = group 239 240 copr_dir = models.CoprDir( 241 main=True, 242 name=name, 243 copr=copr) 244 245 db.session.add(copr_dir) 246 db.session.add(copr) 247 248 CoprChrootsLogic.new_from_names( 249 copr, selected_chroots) 250 251 db.session.flush() 252 ActionsLogic.send_create_gpg_key(copr) 253 254 return copr255 256 @classmethod258 if check_for_duplicates: 259 if group is None and cls.exists_for_user(user, copr_name).all(): 260 raise exceptions.DuplicateException( 261 "Copr: '{0}/{1}' already exists".format(user.name, copr_name)) 262 elif group: 263 if cls.exists_for_group(group, copr_name).all(): 264 db.session.rollback() 265 raise exceptions.DuplicateException( 266 "Copr: '@{0}/{1}' already exists".format(group.name, copr_name))267 268 @classmethod270 # we should call get_history before other requests, otherwise 271 # the changes would be forgotten 272 if get_history(copr, "name").has_changes(): 273 raise MalformedArgumentException("Change name of the project is forbidden") 274 275 users_logic.UsersLogic.raise_if_cant_update_copr( 276 user, copr, "Only owners and admins may update their projects.") 277 278 if not user.admin and not copr.auto_prune: 279 raise exceptions.NonAdminCannotDisableAutoPrunning() 280 281 db.session.add(copr)282 283 @classmethod285 """ 286 Deletes copr without termination of ongoing builds. 287 """ 288 cls.raise_if_cant_delete(user, copr) 289 # TODO: do we want to dump the information somewhere, so that we can 290 # search it in future? 291 cls.raise_if_unfinished_blocking_action( 292 copr, "Can't delete this project," 293 " another operation is in progress: {action}") 294 295 ActionsLogic.send_delete_copr(copr) 296 CoprDirsLogic.delete_all_by_copr(copr) 297 298 copr.deleted = True 299 return copr300 301 @classmethod303 existing = (models.Copr.query 304 .filter(models.Copr.name == coprname) 305 .filter(models.Copr.user_id == user.id)) 306 307 if not incl_deleted: 308 existing = existing.filter(models.Copr.deleted == False) 309 310 return cls.filter_without_group_projects(existing)311 312 @classmethod314 existing = (models.Copr.query 315 .filter(models.Copr.name == coprname) 316 .filter(models.Copr.group_id == group.id)) 317 318 if not incl_deleted: 319 existing = existing.filter(models.Copr.deleted == False) 320 321 return existing322 323 @classmethod325 blocking_actions = [helpers.ActionTypeEnum("delete")] 326 327 actions = (models.Action.query 328 .filter(models.Action.object_type == "copr") 329 .filter(models.Action.object_id == copr.id) 330 .filter(models.Action.result == 331 helpers.BackendResultEnum("waiting")) 332 .filter(models.Action.action_type.in_(blocking_actions))) 333 334 return actions335 336 @classmethod338 repos = {} 339 release_tmpl = "{chroot.os_release}-{chroot.os_version}-{chroot.arch}" 340 build = models.Build.query.filter(models.Build.copr_id == copr.id).first() 341 if build or empty: 342 for chroot in copr.active_chroots: 343 release = release_tmpl.format(chroot=chroot) 344 repos[release] = fix_protocol_for_backend( 345 os.path.join(copr.repo_url, release + '/')) 346 return repos347 348 @classmethod350 """ 351 Raise ActionInProgressException if given copr has an unfinished 352 action. Return None otherwise. 353 """ 354 355 unfinished_actions = cls.unfinished_blocking_actions_for(copr).all() 356 if unfinished_actions: 357 raise exceptions.ActionInProgressException( 358 message, unfinished_actions[0])359 360 @classmethod373 @classmethod431375 query = (models.CoprPermission.query 376 .filter(models.CoprPermission.copr == copr) 377 .filter(models.CoprPermission.user == searched_user)) 378 379 return query380 381 @classmethod383 query = models.CoprPermission.query.filter( 384 models.CoprPermission.copr == copr) 385 386 return query387 388 @classmethod 391 392 @classmethod395 396 users_logic.UsersLogic.raise_if_cant_update_copr( 397 user, copr, "Only owners and admins may update" 398 " their projects permissions.") 399 400 (models.CoprPermission.query 401 .filter(models.CoprPermission.copr_id == copr.id) 402 .filter(models.CoprPermission.user_id == copr_permission.user_id) 403 .update({"copr_builder": new_builder, 404 "copr_admin": new_admin}))405 406 @classmethod408 if copr_permission: 409 # preserve approved permissions if set 410 if (not new_builder or 411 copr_permission.copr_builder != helpers.PermissionEnum("approved")): 412 413 copr_permission.copr_builder = new_builder 414 415 if (not new_admin or 416 copr_permission.copr_admin != helpers.PermissionEnum("approved")): 417 418 copr_permission.copr_admin = new_admin 419 else: 420 perm = models.CoprPermission( 421 user=user, 422 copr=copr, 423 copr_builder=new_builder, 424 copr_admin=new_admin) 425 426 cls.new(perm)427 428 @classmethod434 @classmethod468436 copr_dir = cls.get_by_copr(copr, dirname).first() 437 438 if copr_dir: 439 return copr_dir 440 441 copr_dir = models.CoprDir( 442 name=dirname, copr=copr, main=main) 443 444 db.session.add(copr_dir) 445 return copr_dir446 447 @classmethod449 return (db.session.query(models.CoprDir) 450 .join(models.Copr) 451 .filter(models.Copr.id==copr.id) 452 .filter(models.CoprDir.name==dirname))453 454 @classmethod456 return (db.session.query(models.CoprDir) 457 .filter(models.CoprDir.name==dirname) 458 .filter(models.CoprDir.ownername==ownername))459 460 @classmethod 463 464 @classmethod471 """ Emit createrepo action when auto_createrepo re-enabled""" 472 if old_value_acr == NEVER_SET: 473 # created new copr, not interesting 474 return 475 if not old_value_acr and value_acr: 476 # re-enabled 477 ActionsLogic.send_createrepo(target_copr)478 479 480 listen(models.Copr.auto_createrepo, 'set', on_auto_createrepo_change, 481 active_history=True, retval=False) 495498 @classmethod654500 501 db_chroots = models.MockChroot.query.all() 502 mock_chroots = [] 503 for ch in db_chroots: 504 if ch.name in names: 505 mock_chroots.append(ch) 506 507 return mock_chroots508 509 @classmethod511 mc = MockChrootsLogic.get_from_name(chroot_name, active_only=True).one() 512 query = ( 513 models.CoprChroot.query.join(models.MockChroot) 514 .filter(models.CoprChroot.copr_id == copr.id) 515 .filter(models.MockChroot.id == mc.id) 516 ) 517 return query518 519 @classmethod521 """ 522 :rtype: models.CoprChroot 523 """ 524 try: 525 return cls.get_by_name(copr, chroot_name).one() 526 except NoResultFound: 527 return None528 529 @classmethod 532 533 @classmethod535 for mock_chroot in cls.mock_chroots_from_names(names): 536 db.session.add( 537 models.CoprChroot(copr=copr, mock_chroot=mock_chroot))538 539 @classmethod540 - def create_chroot(cls, user, copr, mock_chroot, 541 buildroot_pkgs=None, repos=None, comps=None, comps_name=None, module_md=None, module_md_name=None, with_opts="", without_opts=""):542 """ 543 :type user: models.User 544 :type mock_chroot: models.MockChroot 545 """ 546 if buildroot_pkgs is None: 547 buildroot_pkgs = "" 548 if repos is None: 549 repos = "" 550 UsersLogic.raise_if_cant_update_copr( 551 user, copr, 552 "Only owners and admins may update their projects.") 553 554 chroot = models.CoprChroot(copr=copr, mock_chroot=mock_chroot) 555 cls._update_chroot(buildroot_pkgs, repos, comps, comps_name, module_md, module_md_name, chroot, with_opts, without_opts) 556 return chroot557 558 @classmethod559 - def update_chroot(cls, user, copr_chroot, 560 buildroot_pkgs=None, repos=None, comps=None, comps_name=None, module_md=None, module_md_name=None, with_opts="", without_opts=""):561 """ 562 :type user: models.User 563 :type copr_chroot: models.CoprChroot 564 """ 565 UsersLogic.raise_if_cant_update_copr( 566 user, copr_chroot.copr, 567 "Only owners and admins may update their projects.") 568 569 cls._update_chroot(buildroot_pkgs, repos, comps, comps_name, module_md, module_md_name, copr_chroot, with_opts, without_opts) 570 return copr_chroot571 572 @classmethod573 - def _update_chroot(cls, buildroot_pkgs, repos, comps, comps_name, module_md, module_md_name, copr_chroot, with_opts, without_opts):574 if buildroot_pkgs is not None: 575 copr_chroot.buildroot_pkgs = buildroot_pkgs 576 577 if repos is not None: 578 copr_chroot.repos = repos.replace("\n", " ") 579 580 if with_opts is not None: 581 copr_chroot.with_opts = with_opts 582 583 if without_opts is not None: 584 copr_chroot.without_opts = without_opts 585 586 if comps_name is not None: 587 copr_chroot.update_comps(comps) 588 copr_chroot.comps_name = comps_name 589 ActionsLogic.send_update_comps(copr_chroot) 590 591 if module_md_name is not None: 592 copr_chroot.update_module_md(module_md) 593 copr_chroot.module_md_name = module_md_name 594 ActionsLogic.send_update_module_md(copr_chroot) 595 596 db.session.add(copr_chroot)597 598 @classmethod600 UsersLogic.raise_if_cant_update_copr( 601 user, copr, 602 "Only owners and admins may update their projects.") 603 current_chroots = copr.mock_chroots 604 new_chroots = cls.mock_chroots_from_names(names) 605 # add non-existing 606 for mock_chroot in new_chroots: 607 if mock_chroot not in current_chroots: 608 db.session.add( 609 models.CoprChroot(copr=copr, mock_chroot=mock_chroot)) 610 611 # delete no more present 612 to_remove = [] 613 for mock_chroot in current_chroots: 614 if mock_chroot not in new_chroots: 615 # can't delete here, it would change current_chroots and break 616 # iteration 617 to_remove.append(mock_chroot) 618 619 for mc in to_remove: 620 copr.mock_chroots.remove(mc)621 622 @classmethod624 UsersLogic.raise_if_cant_update_copr( 625 user, copr_chroot.copr, 626 "Only owners and admins may update their projects.") 627 628 copr_chroot.comps_name = None 629 copr_chroot.comps_zlib = None 630 ActionsLogic.send_update_comps(copr_chroot) 631 db.session.add(copr_chroot)632 633 @classmethod635 UsersLogic.raise_if_cant_update_copr( 636 user, copr_chroot.copr, 637 "Only owners and admins may update their projects.") 638 639 copr_chroot.module_md_name = None 640 copr_chroot.module_md_zlib = None 641 ActionsLogic.send_update_module_md(copr_chroot) 642 db.session.add(copr_chroot)643 644 @classmethod646 """ 647 :param models.CoprChroot chroot: 648 """ 649 UsersLogic.raise_if_cant_update_copr( 650 user, copr_chroot.copr, 651 "Only owners and admins may update their projects.") 652 653 db.session.delete(copr_chroot)657 @classmethod760659 if noarch and not arch: 660 return (models.MockChroot.query 661 .filter(models.MockChroot.os_release == os_release, 662 models.MockChroot.os_version == os_version)) 663 664 return (models.MockChroot.query 665 .filter(models.MockChroot.os_release == os_release, 666 models.MockChroot.os_version == os_version, 667 models.MockChroot.arch == arch))668 669 @classmethod671 """ 672 chroot_name should be os-version-architecture, e.g. fedora-rawhide-x86_64 673 the architecture could be optional with noarch=True 674 675 Return MockChroot object for textual representation of chroot 676 """ 677 678 name_tuple = cls.tuple_from_name(chroot_name, noarch=noarch) 679 return cls.get(name_tuple[0], name_tuple[1], name_tuple[2], 680 active_only=active_only, noarch=noarch)681 682 @classmethod684 query = models.MockChroot.query 685 if active_only: 686 query = query.filter(models.MockChroot.is_active == True) 687 return query688 689 @classmethod691 name_tuple = cls.tuple_from_name(name) 692 if cls.get(*name_tuple).first(): 693 raise exceptions.DuplicateException( 694 "Mock chroot with this name already exists.") 695 new_chroot = models.MockChroot(os_release=name_tuple[0], 696 os_version=name_tuple[1], 697 arch=name_tuple[2]) 698 cls.new(new_chroot) 699 return new_chroot700 701 @classmethod 704 705 @classmethod707 name_tuple = cls.tuple_from_name(name) 708 mock_chroot = cls.get(*name_tuple).first() 709 if not mock_chroot: 710 raise exceptions.NotFoundException( 711 "Mock chroot with this name doesn't exist.") 712 713 mock_chroot.is_active = is_active 714 cls.update(mock_chroot) 715 return mock_chroot716 717 @classmethod 720 721 @classmethod723 name_tuple = cls.tuple_from_name(name) 724 mock_chroot = cls.get(*name_tuple).first() 725 if not mock_chroot: 726 raise exceptions.NotFoundException( 727 "Mock chroot with this name doesn't exist.") 728 729 cls.delete(mock_chroot)730 731 @classmethod 734 735 @classmethod737 """ 738 input should be os-version-architecture, e.g. fedora-rawhide-x86_64 739 740 the architecture could be optional with noarch=True 741 742 returns ("os", "version", "arch") or ("os", "version", None) 743 """ 744 split_name = name.rsplit("-", 1) if noarch else name.rsplit("-", 2) 745 746 valid = False 747 if noarch and len(split_name) in [2, 3]: 748 valid = True 749 if not noarch and len(split_name) == 3: 750 valid = True 751 752 if not valid: 753 raise MalformedArgumentException( 754 "Chroot name is not valid") 755 756 if noarch and len(split_name) == 2: 757 split_name.append(None) 758 759 return tuple(split_name)
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 | http://epydoc.sourceforge.net |