Trees | Indices | Help |
---|
|
1 import time 2 3 from sqlalchemy import and_ 4 from sqlalchemy.sql import func 5 from sqlalchemy import asc 6 from sqlalchemy.event import listen 7 from sqlalchemy.orm.attributes import NEVER_SET 8 from sqlalchemy.orm.exc import NoResultFound 9 from sqlalchemy.orm.attributes import get_history 10 11 from coprs import db 12 from coprs import exceptions 13 from coprs import helpers 14 from coprs import models 15 from coprs.exceptions import MalformedArgumentException 16 from coprs.logic import users_logic 17 from coprs.whoosheers import CoprWhoosheer 18 19 from coprs.logic.actions_logic import ActionsLogic 20 from coprs.logic.users_logic import UsersLogic24 """ 25 Used for manipulating Coprs. 26 27 All methods accept user object as a first argument, 28 as this may be needed in future. 29 """ 30 31 @classmethod35433 """ Return all coprs without those which are deleted. """ 34 query = (db.session.query(models.Copr) 35 .join(models.Copr.user) 36 .options(db.contains_eager(models.Copr.user)) 37 .filter(models.Copr.deleted == False)) 38 return query39 40 @classmethod 43 44 @classmethod46 query = (query.outerjoin(models.Copr.builds) 47 .options(db.contains_eager(models.Copr.builds)) 48 .order_by(models.Build.submitted_on.desc())) 49 return query50 51 @classmethod53 query = (query.outerjoin(*models.Copr.mock_chroots.attr) 54 .options(db.contains_eager(*models.Copr.mock_chroots.attr)) 55 .order_by(models.MockChroot.os_release.asc()) 56 .order_by(models.MockChroot.os_version.asc()) 57 .order_by(models.MockChroot.arch.asc())) 58 return query59 60 @classmethod62 with_builds = kwargs.get("with_builds", False) 63 with_mock_chroots = kwargs.get("with_mock_chroots", False) 64 65 query = ( 66 cls.get_all() 67 .filter(models.Copr.name == coprname) 68 .filter(models.User.username == username) 69 ) 70 71 if with_builds: 72 query = cls.attach_build(query) 73 74 if with_mock_chroots: 75 query = cls.attach_mock_chroots(query) 76 77 return query78 79 @classmethod81 with_builds = kwargs.get("with_builds", False) 82 with_mock_chroots = kwargs.get("with_mock_chroots", False) 83 84 query = ( 85 cls.get_all() 86 .filter(models.Copr.group_id == group_id) 87 ) 88 89 if with_builds: 90 query = cls.attach_build(query) 91 92 if with_mock_chroots: 93 query = cls.attach_mock_chroots(query) 94 95 return query96 97 @classmethod99 query = cls.get_multiple_by_group_id(group_id, **kwargs) 100 query = query.filter(models.Copr.name == coprname) 101 102 return query103 104 @classmethod106 query = ( 107 db.session.query(models.Copr) 108 .join(models.Copr.user) 109 .outerjoin(models.Group) 110 .options(db.contains_eager(models.Copr.user)) 111 ) 112 113 if not include_deleted: 114 query = query.filter(models.Copr.deleted.is_(False)) 115 116 if not include_unlisted_on_hp: 117 query = query.filter(models.Copr.unlisted_on_hp.is_(False)) 118 119 return query120 121 @classmethod123 if desc: 124 query = query.order_by(models.Copr.id.desc()) 125 else: 126 query = query.order_by(models.Copr.id.asc()) 127 return query128 129 # user_relation="owned", username=username, with_mock_chroots=False 130 @classmethod 134 135 @classmethod 138 139 @classmethod141 # should be already joined with the User table 142 return query.filter(models.User.username == username)143 144 @classmethod146 # should be already joined with the Group table 147 return query.filter(models.Group.name == group_name)148 149 @classmethod 152 153 @classmethod155 return (query.outerjoin(models.Copr.builds) 156 .options(db.contains_eager(models.Copr.builds)) 157 .order_by(models.Build.submitted_on.desc()))158 159 @classmethod161 return (query.outerjoin(*models.Copr.mock_chroots.attr) 162 .options(db.contains_eager(*models.Copr.mock_chroots.attr)) 163 .order_by(models.MockChroot.os_release.asc()) 164 .order_by(models.MockChroot.os_version.asc()) 165 .order_by(models.MockChroot.arch.asc()))166 167 @classmethod 170 171 @classmethod173 if user.admin: 174 db.session.add(copr) 175 pass 176 else: 177 raise exceptions.InsufficientRightsException( 178 "User is not a system admin")179 180 @classmethod182 query = (models.Copr.query.join(models.User) 183 .filter(models.Copr.deleted == False)) 184 if "/" in search_string: # copr search by its full name 185 if search_string[0] == '@': # searching for @group/project 186 group_name = "%{}%".format(search_string.split("/")[0][1:]) 187 project = "%{}%".format(search_string.split("/")[1]) 188 query = query.filter(and_(models.Group.name.ilike(group_name), 189 models.Copr.name.ilike(project), 190 models.Group.id == models.Copr.group_id)) 191 query = query.order_by(asc(func.length(models.Group.name)+func.length(models.Copr.name))) 192 else: # searching for user/project 193 user_name = "%{}%".format(search_string.split("/")[0]) 194 project = "%{}%".format(search_string.split("/")[1]) 195 query = query.filter(and_(models.User.username.ilike(user_name), 196 models.Copr.name.ilike(project), 197 models.User.id == models.Copr.user_id)) 198 query = query.order_by(asc(func.length(models.User.username)+func.length(models.Copr.name))) 199 else: # fulltext search 200 query = query.whooshee_search(search_string, whoosheer=CoprWhoosheer) 201 return query202 203 @classmethod204 - def add(cls, user, name, selected_chroots, repos=None, description=None, 205 instructions=None, check_for_duplicates=False, group=None, persistent=False, 206 auto_prune=True, use_bootstrap_container=False, follow_fedora_branching=False, **kwargs):207 208 if not user.admin and persistent: 209 raise exceptions.NonAdminCannotCreatePersistentProject() 210 211 if not user.admin and not auto_prune: 212 raise exceptions.NonAdminCannotDisableAutoPrunning() 213 214 copr = models.Copr(name=name, 215 repos=repos or u"", 216 user_id=user.id, 217 description=description or u"", 218 instructions=instructions or u"", 219 created_on=int(time.time()), 220 persistent=persistent, 221 auto_prune=auto_prune, 222 use_bootstrap_container=use_bootstrap_container, 223 follow_fedora_branching=follow_fedora_branching, 224 **kwargs) 225 226 if group is not None: 227 UsersLogic.raise_if_not_in_group(user, group) 228 copr.group = group 229 230 # form validation checks for duplicates 231 cls.new(user, copr, check_for_duplicates=check_for_duplicates) 232 CoprChrootsLogic.new_from_names(copr, selected_chroots) 233 234 db.session.flush() 235 ActionsLogic.send_create_gpg_key(copr) 236 237 return copr238 239 @classmethod241 if check_for_duplicates: 242 if copr.group is None and cls.exists_for_user(user, copr.name).all(): 243 raise exceptions.DuplicateException( 244 "Copr: '{0}/{1}' already exists".format(user.name, copr.name)) 245 elif copr.group: 246 db.session.flush() # otherwise copr.id is not set from sequence 247 if cls.exists_for_group(copr.group, copr.name).filter(models.Copr.id != copr.id).all(): 248 db.session.rollback() 249 raise exceptions.DuplicateException( 250 "Copr: '@{0}/{1}' already exists".format(copr.group.name, copr.name)) 251 db.session.add(copr)252 253 @classmethod255 # we should call get_history before other requests, otherwise 256 # the changes would be forgotten 257 if get_history(copr, "name").has_changes(): 258 raise MalformedArgumentException("Change name of the project is forbidden") 259 260 users_logic.UsersLogic.raise_if_cant_update_copr( 261 user, copr, "Only owners and admins may update their projects.") 262 263 if not user.admin and not copr.auto_prune: 264 raise exceptions.NonAdminCannotDisableAutoPrunning() 265 266 db.session.add(copr)267 268 @classmethod270 """ 271 Deletes copr without termination of ongoing builds. 272 """ 273 cls.raise_if_cant_delete(user, copr) 274 # TODO: do we want to dump the information somewhere, so that we can 275 # search it in future? 276 cls.raise_if_unfinished_blocking_action( 277 copr, "Can't delete this project," 278 " another operation is in progress: {action}") 279 280 cls.create_delete_action(copr) 281 copr.deleted = True 282 283 return copr284 285 @classmethod287 action = models.Action(action_type=helpers.ActionTypeEnum("delete"), 288 object_type="copr", 289 object_id=copr.id, 290 old_value=copr.full_name, 291 new_value="", 292 created_on=int(time.time())) 293 db.session.add(action) 294 return action295 296 @classmethod298 existing = (models.Copr.query 299 .filter(models.Copr.name == coprname) 300 .filter(models.Copr.user_id == user.id)) 301 302 if not incl_deleted: 303 existing = existing.filter(models.Copr.deleted == False) 304 305 return cls.filter_without_group_projects(existing)306 307 @classmethod309 existing = (models.Copr.query 310 .filter(models.Copr.name == coprname) 311 .filter(models.Copr.group_id == group.id)) 312 313 if not incl_deleted: 314 existing = existing.filter(models.Copr.deleted == False) 315 316 return existing317 318 @classmethod320 blocking_actions = [helpers.ActionTypeEnum("rename"), 321 helpers.ActionTypeEnum("delete")] 322 323 actions = (models.Action.query 324 .filter(models.Action.object_type == "copr") 325 .filter(models.Action.object_id == copr.id) 326 .filter(models.Action.result == 327 helpers.BackendResultEnum("waiting")) 328 .filter(models.Action.action_type.in_(blocking_actions))) 329 330 return actions331 332 @classmethod334 """ 335 Raise ActionInProgressException if given copr has an unfinished 336 action. Return None otherwise. 337 """ 338 339 unfinished_actions = cls.unfinished_blocking_actions_for(copr).all() 340 if unfinished_actions: 341 raise exceptions.ActionInProgressException( 342 message, unfinished_actions[0])343 344 @classmethod357 @classmethod415359 query = (models.CoprPermission.query 360 .filter(models.CoprPermission.copr == copr) 361 .filter(models.CoprPermission.user == searched_user)) 362 363 return query364 365 @classmethod367 query = models.CoprPermission.query.filter( 368 models.CoprPermission.copr == copr) 369 370 return query371 372 @classmethod 375 376 @classmethod379 380 users_logic.UsersLogic.raise_if_cant_update_copr( 381 user, copr, "Only owners and admins may update" 382 " their projects permissions.") 383 384 (models.CoprPermission.query 385 .filter(models.CoprPermission.copr_id == copr.id) 386 .filter(models.CoprPermission.user_id == copr_permission.user_id) 387 .update({"copr_builder": new_builder, 388 "copr_admin": new_admin}))389 390 @classmethod392 if copr_permission: 393 # preserve approved permissions if set 394 if (not new_builder or 395 copr_permission.copr_builder != helpers.PermissionEnum("approved")): 396 397 copr_permission.copr_builder = new_builder 398 399 if (not new_admin or 400 copr_permission.copr_admin != helpers.PermissionEnum("approved")): 401 402 copr_permission.copr_admin = new_admin 403 else: 404 perm = models.CoprPermission( 405 user=user, 406 copr=copr, 407 copr_builder=new_builder, 408 copr_admin=new_admin) 409 410 cls.new(perm)411 412 @classmethod418 """ Emit createrepo action when auto_createrepo re-enabled""" 419 if old_value_acr == NEVER_SET: 420 # created new copr, not interesting 421 return 422 if not old_value_acr and value_acr: 423 # re-enabled 424 ActionsLogic.send_createrepo( 425 target_copr.owner_name, 426 target_copr.name, 427 chroots=[chroot.name for chroot in target_copr.active_chroots] 428 )429 430 431 listen(models.Copr.auto_createrepo, 'set', on_auto_createrepo_change, 432 active_history=True, retval=False) 446449 @classmethod599451 452 db_chroots = models.MockChroot.query.all() 453 mock_chroots = [] 454 for ch in db_chroots: 455 if ch.name in names: 456 mock_chroots.append(ch) 457 458 return mock_chroots459 460 @classmethod462 mc = MockChrootsLogic.get_from_name(chroot_name, active_only=True).one() 463 query = ( 464 models.CoprChroot.query.join(models.MockChroot) 465 .filter(models.CoprChroot.copr_id == copr.id) 466 .filter(models.MockChroot.id == mc.id) 467 ) 468 return query469 470 @classmethod472 """ 473 :rtype: models.CoprChroot 474 """ 475 try: 476 return cls.get_by_name(copr, chroot_name).one() 477 except NoResultFound: 478 return None479 480 @classmethod 483 484 @classmethod486 for mock_chroot in cls.mock_chroots_from_names(names): 487 db.session.add( 488 models.CoprChroot(copr=copr, mock_chroot=mock_chroot))489 490 @classmethod491 - def create_chroot(cls, user, copr, mock_chroot, 492 buildroot_pkgs=None, repos=None, comps=None, comps_name=None, module_md=None, module_md_name=None):493 """ 494 :type user: models.User 495 :type mock_chroot: models.MockChroot 496 """ 497 if buildroot_pkgs is None: 498 buildroot_pkgs = "" 499 if repos is None: 500 repos = "" 501 UsersLogic.raise_if_cant_update_copr( 502 user, copr, 503 "Only owners and admins may update their projects.") 504 505 chroot = models.CoprChroot(copr=copr, mock_chroot=mock_chroot) 506 cls._update_chroot(buildroot_pkgs, repos, comps, comps_name, module_md, module_md_name, chroot) 507 return chroot508 509 @classmethod510 - def update_chroot(cls, user, copr_chroot, 511 buildroot_pkgs=None, repos=None, comps=None, comps_name=None, module_md=None, module_md_name=None):512 """ 513 :type user: models.User 514 :type copr_chroot: models.CoprChroot 515 """ 516 UsersLogic.raise_if_cant_update_copr( 517 user, copr_chroot.copr, 518 "Only owners and admins may update their projects.") 519 520 cls._update_chroot(buildroot_pkgs, repos, comps, comps_name, module_md, module_md_name, copr_chroot) 521 return copr_chroot522 523 @classmethod524 - def _update_chroot(cls, buildroot_pkgs, repos, comps, comps_name, module_md, module_md_name, copr_chroot):525 if buildroot_pkgs is not None: 526 copr_chroot.buildroot_pkgs = buildroot_pkgs 527 528 if repos is not None: 529 copr_chroot.repos = repos.replace("\n", " ") 530 531 if comps_name is not None: 532 copr_chroot.update_comps(comps) 533 copr_chroot.comps_name = comps_name 534 ActionsLogic.send_update_comps(copr_chroot) 535 536 if module_md_name is not None: 537 copr_chroot.update_module_md(module_md) 538 copr_chroot.module_md_name = module_md_name 539 ActionsLogic.send_update_module_md(copr_chroot) 540 541 db.session.add(copr_chroot)542 543 @classmethod545 UsersLogic.raise_if_cant_update_copr( 546 user, copr, 547 "Only owners and admins may update their projects.") 548 current_chroots = copr.mock_chroots 549 new_chroots = cls.mock_chroots_from_names(names) 550 # add non-existing 551 for mock_chroot in new_chroots: 552 if mock_chroot not in current_chroots: 553 db.session.add( 554 models.CoprChroot(copr=copr, mock_chroot=mock_chroot)) 555 556 # delete no more present 557 to_remove = [] 558 for mock_chroot in current_chroots: 559 if mock_chroot not in new_chroots: 560 # can't delete here, it would change current_chroots and break 561 # iteration 562 to_remove.append(mock_chroot) 563 564 for mc in to_remove: 565 copr.mock_chroots.remove(mc)566 567 @classmethod569 UsersLogic.raise_if_cant_update_copr( 570 user, copr_chroot.copr, 571 "Only owners and admins may update their projects.") 572 573 copr_chroot.comps_name = None 574 copr_chroot.comps_zlib = None 575 ActionsLogic.send_update_comps(copr_chroot) 576 db.session.add(copr_chroot)577 578 @classmethod580 UsersLogic.raise_if_cant_update_copr( 581 user, copr_chroot.copr, 582 "Only owners and admins may update their projects.") 583 584 copr_chroot.module_md_name = None 585 copr_chroot.module_md_zlib = None 586 ActionsLogic.send_update_module_md(copr_chroot) 587 db.session.add(copr_chroot)588 589 @classmethod591 """ 592 :param models.CoprChroot chroot: 593 """ 594 UsersLogic.raise_if_cant_update_copr( 595 user, copr_chroot.copr, 596 "Only owners and admins may update their projects.") 597 598 db.session.delete(copr_chroot)602 @classmethod704604 if noarch and not arch: 605 return (models.MockChroot.query 606 .filter(models.MockChroot.os_release == os_release, 607 models.MockChroot.os_version == os_version)) 608 609 return (models.MockChroot.query 610 .filter(models.MockChroot.os_release == os_release, 611 models.MockChroot.os_version == os_version, 612 models.MockChroot.arch == arch))613 614 @classmethod616 """ 617 chroot_name should be os-version-architecture, e.g. fedora-rawhide-x86_64 618 the architecture could be optional with noarch=True 619 620 Return MockChroot object for textual representation of chroot 621 """ 622 623 name_tuple = cls.tuple_from_name(chroot_name, noarch=noarch) 624 return cls.get(name_tuple[0], name_tuple[1], name_tuple[2], 625 active_only=active_only, noarch=noarch)626 627 @classmethod629 query = models.MockChroot.query 630 if active_only: 631 query = query.filter(models.MockChroot.is_active == True) 632 return query633 634 @classmethod636 name_tuple = cls.tuple_from_name(name) 637 if cls.get(*name_tuple).first(): 638 raise exceptions.DuplicateException( 639 "Mock chroot with this name already exists.") 640 new_chroot = models.MockChroot(os_release=name_tuple[0], 641 os_version=name_tuple[1], 642 arch=name_tuple[2]) 643 cls.new(new_chroot) 644 return new_chroot645 646 @classmethod 649 650 @classmethod652 name_tuple = cls.tuple_from_name(name) 653 mock_chroot = cls.get(*name_tuple).first() 654 if not mock_chroot: 655 raise exceptions.NotFoundException( 656 "Mock chroot with this name doesn't exist.") 657 658 mock_chroot.is_active = is_active 659 cls.update(mock_chroot) 660 return mock_chroot661 662 @classmethod 665 666 @classmethod668 name_tuple = cls.tuple_from_name(name) 669 mock_chroot = cls.get(*name_tuple).first() 670 if not mock_chroot: 671 raise exceptions.NotFoundException( 672 "Mock chroot with this name doesn't exist.") 673 674 cls.delete(mock_chroot)675 676 @classmethod 679 680 @classmethod682 """ 683 input should be os-version-architecture, e.g. fedora-rawhide-x86_64 684 685 the architecture could be optional with noarch=True 686 687 returns ("os", "version", "arch") or ("os", "version", None) 688 """ 689 split_name = name.split("-") 690 valid = False 691 if noarch and len(split_name) in [2, 3]: 692 valid = True 693 if not noarch and len(split_name) == 3: 694 valid = True 695 696 if not valid: 697 raise MalformedArgumentException( 698 "Chroot name is not valid") 699 700 if noarch and len(split_name) == 2: 701 split_name.append(None) 702 703 return tuple(split_name)
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 | http://epydoc.sourceforge.net |