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 @classmethod35233 """ 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, **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 **kwargs) 223 224 if group is not None: 225 UsersLogic.raise_if_not_in_group(user, group) 226 copr.group = group 227 228 # form validation checks for duplicates 229 cls.new(user, copr, check_for_duplicates=check_for_duplicates) 230 CoprChrootsLogic.new_from_names(copr, selected_chroots) 231 232 db.session.flush() 233 ActionsLogic.send_create_gpg_key(copr) 234 235 return copr236 237 @classmethod239 if check_for_duplicates: 240 if copr.group is None and cls.exists_for_user(user, copr.name).all(): 241 raise exceptions.DuplicateException( 242 "Copr: '{0}/{1}' already exists".format(user.name, copr.name)) 243 elif copr.group: 244 db.session.flush() # otherwise copr.id is not set from sequence 245 if cls.exists_for_group(copr.group, copr.name).filter(models.Copr.id != copr.id).all(): 246 db.session.rollback() 247 raise exceptions.DuplicateException( 248 "Copr: '@{0}/{1}' already exists".format(copr.group.name, copr.name)) 249 db.session.add(copr)250 251 @classmethod253 # we should call get_history before other requests, otherwise 254 # the changes would be forgotten 255 if get_history(copr, "name").has_changes(): 256 raise MalformedArgumentException("Change name of the project is forbidden") 257 258 users_logic.UsersLogic.raise_if_cant_update_copr( 259 user, copr, "Only owners and admins may update their projects.") 260 261 if not user.admin and not copr.auto_prune: 262 raise exceptions.NonAdminCannotDisableAutoPrunning() 263 264 db.session.add(copr)265 266 @classmethod268 """ 269 Deletes copr without termination of ongoing builds. 270 """ 271 cls.raise_if_cant_delete(user, copr) 272 # TODO: do we want to dump the information somewhere, so that we can 273 # search it in future? 274 cls.raise_if_unfinished_blocking_action( 275 copr, "Can't delete this project," 276 " another operation is in progress: {action}") 277 278 cls.create_delete_action(copr) 279 copr.deleted = True 280 281 return copr282 283 @classmethod285 action = models.Action(action_type=helpers.ActionTypeEnum("delete"), 286 object_type="copr", 287 object_id=copr.id, 288 old_value=copr.full_name, 289 new_value="", 290 created_on=int(time.time())) 291 db.session.add(action) 292 return action293 294 @classmethod296 existing = (models.Copr.query 297 .filter(models.Copr.name == coprname) 298 .filter(models.Copr.user_id == user.id)) 299 300 if not incl_deleted: 301 existing = existing.filter(models.Copr.deleted == False) 302 303 return cls.filter_without_group_projects(existing)304 305 @classmethod307 existing = (models.Copr.query 308 .filter(models.Copr.name == coprname) 309 .filter(models.Copr.group_id == group.id)) 310 311 if not incl_deleted: 312 existing = existing.filter(models.Copr.deleted == False) 313 314 return existing315 316 @classmethod318 blocking_actions = [helpers.ActionTypeEnum("rename"), 319 helpers.ActionTypeEnum("delete")] 320 321 actions = (models.Action.query 322 .filter(models.Action.object_type == "copr") 323 .filter(models.Action.object_id == copr.id) 324 .filter(models.Action.result == 325 helpers.BackendResultEnum("waiting")) 326 .filter(models.Action.action_type.in_(blocking_actions))) 327 328 return actions329 330 @classmethod332 """ 333 Raise ActionInProgressException if given copr has an unfinished 334 action. Return None otherwise. 335 """ 336 337 unfinished_actions = cls.unfinished_blocking_actions_for(copr).all() 338 if unfinished_actions: 339 raise exceptions.ActionInProgressException( 340 message, unfinished_actions[0])341 342 @classmethod355 @classmethod413357 query = (models.CoprPermission.query 358 .filter(models.CoprPermission.copr == copr) 359 .filter(models.CoprPermission.user == searched_user)) 360 361 return query362 363 @classmethod365 query = models.CoprPermission.query.filter( 366 models.CoprPermission.copr == copr) 367 368 return query369 370 @classmethod 373 374 @classmethod377 378 users_logic.UsersLogic.raise_if_cant_update_copr( 379 user, copr, "Only owners and admins may update" 380 " their projects permissions.") 381 382 (models.CoprPermission.query 383 .filter(models.CoprPermission.copr_id == copr.id) 384 .filter(models.CoprPermission.user_id == copr_permission.user_id) 385 .update({"copr_builder": new_builder, 386 "copr_admin": new_admin}))387 388 @classmethod390 if copr_permission: 391 # preserve approved permissions if set 392 if (not new_builder or 393 copr_permission.copr_builder != helpers.PermissionEnum("approved")): 394 395 copr_permission.copr_builder = new_builder 396 397 if (not new_admin or 398 copr_permission.copr_admin != helpers.PermissionEnum("approved")): 399 400 copr_permission.copr_admin = new_admin 401 else: 402 perm = models.CoprPermission( 403 user=user, 404 copr=copr, 405 copr_builder=new_builder, 406 copr_admin=new_admin) 407 408 cls.new(perm)409 410 @classmethod416 """ Emit createrepo action when auto_createrepo re-enabled""" 417 if old_value_acr == NEVER_SET: 418 # created new copr, not interesting 419 return 420 if not old_value_acr and value_acr: 421 # re-enabled 422 ActionsLogic.send_createrepo( 423 target_copr.owner_name, 424 target_copr.name, 425 chroots=[chroot.name for chroot in target_copr.active_chroots] 426 )427 428 429 listen(models.Copr.auto_createrepo, 'set', on_auto_createrepo_change, 430 active_history=True, retval=False)434 @classmethod584436 437 db_chroots = models.MockChroot.query.all() 438 mock_chroots = [] 439 for ch in db_chroots: 440 if ch.name in names: 441 mock_chroots.append(ch) 442 443 return mock_chroots444 445 @classmethod447 mc = MockChrootsLogic.get_from_name(chroot_name, active_only=True).one() 448 query = ( 449 models.CoprChroot.query.join(models.MockChroot) 450 .filter(models.CoprChroot.copr_id == copr.id) 451 .filter(models.MockChroot.id == mc.id) 452 ) 453 return query454 455 @classmethod457 """ 458 :rtype: models.CoprChroot 459 """ 460 try: 461 return cls.get_by_name(copr, chroot_name).one() 462 except NoResultFound: 463 return None464 465 @classmethod 468 469 @classmethod471 for mock_chroot in cls.mock_chroots_from_names(names): 472 db.session.add( 473 models.CoprChroot(copr=copr, mock_chroot=mock_chroot))474 475 @classmethod476 - def create_chroot(cls, user, copr, mock_chroot, 477 buildroot_pkgs=None, repos=None, comps=None, comps_name=None, module_md=None, module_md_name=None):478 """ 479 :type user: models.User 480 :type mock_chroot: models.MockChroot 481 """ 482 if buildroot_pkgs is None: 483 buildroot_pkgs = "" 484 if repos is None: 485 repos = "" 486 UsersLogic.raise_if_cant_update_copr( 487 user, copr, 488 "Only owners and admins may update their projects.") 489 490 chroot = models.CoprChroot(copr=copr, mock_chroot=mock_chroot) 491 cls._update_chroot(buildroot_pkgs, repos, comps, comps_name, module_md, module_md_name, chroot) 492 return chroot493 494 @classmethod495 - def update_chroot(cls, user, copr_chroot, 496 buildroot_pkgs=None, repos=None, comps=None, comps_name=None, module_md=None, module_md_name=None):497 """ 498 :type user: models.User 499 :type copr_chroot: models.CoprChroot 500 """ 501 UsersLogic.raise_if_cant_update_copr( 502 user, copr_chroot.copr, 503 "Only owners and admins may update their projects.") 504 505 cls._update_chroot(buildroot_pkgs, repos, comps, comps_name, module_md, module_md_name, copr_chroot) 506 return copr_chroot507 508 @classmethod509 - def _update_chroot(cls, buildroot_pkgs, repos, comps, comps_name, module_md, module_md_name, copr_chroot):510 if buildroot_pkgs is not None: 511 copr_chroot.buildroot_pkgs = buildroot_pkgs 512 513 if repos is not None: 514 copr_chroot.repos = repos.replace("\n", " ") 515 516 if comps_name is not None: 517 copr_chroot.update_comps(comps) 518 copr_chroot.comps_name = comps_name 519 ActionsLogic.send_update_comps(copr_chroot) 520 521 if module_md_name is not None: 522 copr_chroot.update_module_md(module_md) 523 copr_chroot.module_md_name = module_md_name 524 ActionsLogic.send_update_module_md(copr_chroot) 525 526 db.session.add(copr_chroot)527 528 @classmethod530 UsersLogic.raise_if_cant_update_copr( 531 user, copr, 532 "Only owners and admins may update their projects.") 533 current_chroots = copr.mock_chroots 534 new_chroots = cls.mock_chroots_from_names(names) 535 # add non-existing 536 for mock_chroot in new_chroots: 537 if mock_chroot not in current_chroots: 538 db.session.add( 539 models.CoprChroot(copr=copr, mock_chroot=mock_chroot)) 540 541 # delete no more present 542 to_remove = [] 543 for mock_chroot in current_chroots: 544 if mock_chroot not in new_chroots: 545 # can't delete here, it would change current_chroots and break 546 # iteration 547 to_remove.append(mock_chroot) 548 549 for mc in to_remove: 550 copr.mock_chroots.remove(mc)551 552 @classmethod554 UsersLogic.raise_if_cant_update_copr( 555 user, copr_chroot.copr, 556 "Only owners and admins may update their projects.") 557 558 copr_chroot.comps_name = None 559 copr_chroot.comps_zlib = None 560 ActionsLogic.send_update_comps(copr_chroot) 561 db.session.add(copr_chroot)562 563 @classmethod565 UsersLogic.raise_if_cant_update_copr( 566 user, copr_chroot.copr, 567 "Only owners and admins may update their projects.") 568 569 copr_chroot.module_md_name = None 570 copr_chroot.module_md_zlib = None 571 ActionsLogic.send_update_module_md(copr_chroot) 572 db.session.add(copr_chroot)573 574 @classmethod576 """ 577 :param models.CoprChroot chroot: 578 """ 579 UsersLogic.raise_if_cant_update_copr( 580 user, copr_chroot.copr, 581 "Only owners and admins may update their projects.") 582 583 db.session.delete(copr_chroot)587 @classmethod689589 if noarch and not arch: 590 return (models.MockChroot.query 591 .filter(models.MockChroot.os_release == os_release, 592 models.MockChroot.os_version == os_version)) 593 594 return (models.MockChroot.query 595 .filter(models.MockChroot.os_release == os_release, 596 models.MockChroot.os_version == os_version, 597 models.MockChroot.arch == arch))598 599 @classmethod601 """ 602 chroot_name should be os-version-architecture, e.g. fedora-rawhide-x86_64 603 the architecture could be optional with noarch=True 604 605 Return MockChroot object for textual representation of chroot 606 """ 607 608 name_tuple = cls.tuple_from_name(chroot_name, noarch=noarch) 609 return cls.get(name_tuple[0], name_tuple[1], name_tuple[2], 610 active_only=active_only, noarch=noarch)611 612 @classmethod614 query = models.MockChroot.query 615 if active_only: 616 query = query.filter(models.MockChroot.is_active == True) 617 return query618 619 @classmethod621 name_tuple = cls.tuple_from_name(name) 622 if cls.get(*name_tuple).first(): 623 raise exceptions.DuplicateException( 624 "Mock chroot with this name already exists.") 625 new_chroot = models.MockChroot(os_release=name_tuple[0], 626 os_version=name_tuple[1], 627 arch=name_tuple[2]) 628 cls.new(new_chroot) 629 return new_chroot630 631 @classmethod 634 635 @classmethod637 name_tuple = cls.tuple_from_name(name) 638 mock_chroot = cls.get(*name_tuple).first() 639 if not mock_chroot: 640 raise exceptions.NotFoundException( 641 "Mock chroot with this name doesn't exist.") 642 643 mock_chroot.is_active = is_active 644 cls.update(mock_chroot) 645 return mock_chroot646 647 @classmethod 650 651 @classmethod653 name_tuple = cls.tuple_from_name(name) 654 mock_chroot = cls.get(*name_tuple).first() 655 if not mock_chroot: 656 raise exceptions.NotFoundException( 657 "Mock chroot with this name doesn't exist.") 658 659 cls.delete(mock_chroot)660 661 @classmethod 664 665 @classmethod667 """ 668 input should be os-version-architecture, e.g. fedora-rawhide-x86_64 669 670 the architecture could be optional with noarch=True 671 672 returns ("os", "version", "arch") or ("os", "version", None) 673 """ 674 split_name = name.split("-") 675 valid = False 676 if noarch and len(split_name) in [2, 3]: 677 valid = True 678 if not noarch and len(split_name) == 3: 679 valid = True 680 681 if not valid: 682 raise MalformedArgumentException( 683 "Chroot name is not valid") 684 685 if noarch and len(split_name) == 2: 686 split_name.append(None) 687 688 return tuple(split_name)
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 on Mon Dec 5 22:37:26 2016 | http://epydoc.sourceforge.net |