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 @classmethod35333 """ 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, **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 **kwargs) 224 225 if group is not None: 226 UsersLogic.raise_if_not_in_group(user, group) 227 copr.group = group 228 229 # form validation checks for duplicates 230 cls.new(user, copr, check_for_duplicates=check_for_duplicates) 231 CoprChrootsLogic.new_from_names(copr, selected_chroots) 232 233 db.session.flush() 234 ActionsLogic.send_create_gpg_key(copr) 235 236 return copr237 238 @classmethod240 if check_for_duplicates: 241 if copr.group is None and cls.exists_for_user(user, copr.name).all(): 242 raise exceptions.DuplicateException( 243 "Copr: '{0}/{1}' already exists".format(user.name, copr.name)) 244 elif copr.group: 245 db.session.flush() # otherwise copr.id is not set from sequence 246 if cls.exists_for_group(copr.group, copr.name).filter(models.Copr.id != copr.id).all(): 247 db.session.rollback() 248 raise exceptions.DuplicateException( 249 "Copr: '@{0}/{1}' already exists".format(copr.group.name, copr.name)) 250 db.session.add(copr)251 252 @classmethod254 # we should call get_history before other requests, otherwise 255 # the changes would be forgotten 256 if get_history(copr, "name").has_changes(): 257 raise MalformedArgumentException("Change name of the project is forbidden") 258 259 users_logic.UsersLogic.raise_if_cant_update_copr( 260 user, copr, "Only owners and admins may update their projects.") 261 262 if not user.admin and not copr.auto_prune: 263 raise exceptions.NonAdminCannotDisableAutoPrunning() 264 265 db.session.add(copr)266 267 @classmethod269 """ 270 Deletes copr without termination of ongoing builds. 271 """ 272 cls.raise_if_cant_delete(user, copr) 273 # TODO: do we want to dump the information somewhere, so that we can 274 # search it in future? 275 cls.raise_if_unfinished_blocking_action( 276 copr, "Can't delete this project," 277 " another operation is in progress: {action}") 278 279 cls.create_delete_action(copr) 280 copr.deleted = True 281 282 return copr283 284 @classmethod286 action = models.Action(action_type=helpers.ActionTypeEnum("delete"), 287 object_type="copr", 288 object_id=copr.id, 289 old_value=copr.full_name, 290 new_value="", 291 created_on=int(time.time())) 292 db.session.add(action) 293 return action294 295 @classmethod297 existing = (models.Copr.query 298 .filter(models.Copr.name == coprname) 299 .filter(models.Copr.user_id == user.id)) 300 301 if not incl_deleted: 302 existing = existing.filter(models.Copr.deleted == False) 303 304 return cls.filter_without_group_projects(existing)305 306 @classmethod308 existing = (models.Copr.query 309 .filter(models.Copr.name == coprname) 310 .filter(models.Copr.group_id == group.id)) 311 312 if not incl_deleted: 313 existing = existing.filter(models.Copr.deleted == False) 314 315 return existing316 317 @classmethod319 blocking_actions = [helpers.ActionTypeEnum("rename"), 320 helpers.ActionTypeEnum("delete")] 321 322 actions = (models.Action.query 323 .filter(models.Action.object_type == "copr") 324 .filter(models.Action.object_id == copr.id) 325 .filter(models.Action.result == 326 helpers.BackendResultEnum("waiting")) 327 .filter(models.Action.action_type.in_(blocking_actions))) 328 329 return actions330 331 @classmethod333 """ 334 Raise ActionInProgressException if given copr has an unfinished 335 action. Return None otherwise. 336 """ 337 338 unfinished_actions = cls.unfinished_blocking_actions_for(copr).all() 339 if unfinished_actions: 340 raise exceptions.ActionInProgressException( 341 message, unfinished_actions[0])342 343 @classmethod356 @classmethod414358 query = (models.CoprPermission.query 359 .filter(models.CoprPermission.copr == copr) 360 .filter(models.CoprPermission.user == searched_user)) 361 362 return query363 364 @classmethod366 query = models.CoprPermission.query.filter( 367 models.CoprPermission.copr == copr) 368 369 return query370 371 @classmethod 374 375 @classmethod378 379 users_logic.UsersLogic.raise_if_cant_update_copr( 380 user, copr, "Only owners and admins may update" 381 " their projects permissions.") 382 383 (models.CoprPermission.query 384 .filter(models.CoprPermission.copr_id == copr.id) 385 .filter(models.CoprPermission.user_id == copr_permission.user_id) 386 .update({"copr_builder": new_builder, 387 "copr_admin": new_admin}))388 389 @classmethod391 if copr_permission: 392 # preserve approved permissions if set 393 if (not new_builder or 394 copr_permission.copr_builder != helpers.PermissionEnum("approved")): 395 396 copr_permission.copr_builder = new_builder 397 398 if (not new_admin or 399 copr_permission.copr_admin != helpers.PermissionEnum("approved")): 400 401 copr_permission.copr_admin = new_admin 402 else: 403 perm = models.CoprPermission( 404 user=user, 405 copr=copr, 406 copr_builder=new_builder, 407 copr_admin=new_admin) 408 409 cls.new(perm)410 411 @classmethod417 """ Emit createrepo action when auto_createrepo re-enabled""" 418 if old_value_acr == NEVER_SET: 419 # created new copr, not interesting 420 return 421 if not old_value_acr and value_acr: 422 # re-enabled 423 ActionsLogic.send_createrepo( 424 target_copr.owner_name, 425 target_copr.name, 426 chroots=[chroot.name for chroot in target_copr.active_chroots] 427 )428 429 430 listen(models.Copr.auto_createrepo, 'set', on_auto_createrepo_change, 431 active_history=True, retval=False) 445448 @classmethod598450 451 db_chroots = models.MockChroot.query.all() 452 mock_chroots = [] 453 for ch in db_chroots: 454 if ch.name in names: 455 mock_chroots.append(ch) 456 457 return mock_chroots458 459 @classmethod461 mc = MockChrootsLogic.get_from_name(chroot_name, active_only=True).one() 462 query = ( 463 models.CoprChroot.query.join(models.MockChroot) 464 .filter(models.CoprChroot.copr_id == copr.id) 465 .filter(models.MockChroot.id == mc.id) 466 ) 467 return query468 469 @classmethod471 """ 472 :rtype: models.CoprChroot 473 """ 474 try: 475 return cls.get_by_name(copr, chroot_name).one() 476 except NoResultFound: 477 return None478 479 @classmethod 482 483 @classmethod485 for mock_chroot in cls.mock_chroots_from_names(names): 486 db.session.add( 487 models.CoprChroot(copr=copr, mock_chroot=mock_chroot))488 489 @classmethod490 - def create_chroot(cls, user, copr, mock_chroot, 491 buildroot_pkgs=None, repos=None, comps=None, comps_name=None, module_md=None, module_md_name=None):492 """ 493 :type user: models.User 494 :type mock_chroot: models.MockChroot 495 """ 496 if buildroot_pkgs is None: 497 buildroot_pkgs = "" 498 if repos is None: 499 repos = "" 500 UsersLogic.raise_if_cant_update_copr( 501 user, copr, 502 "Only owners and admins may update their projects.") 503 504 chroot = models.CoprChroot(copr=copr, mock_chroot=mock_chroot) 505 cls._update_chroot(buildroot_pkgs, repos, comps, comps_name, module_md, module_md_name, chroot) 506 return chroot507 508 @classmethod509 - def update_chroot(cls, user, copr_chroot, 510 buildroot_pkgs=None, repos=None, comps=None, comps_name=None, module_md=None, module_md_name=None):511 """ 512 :type user: models.User 513 :type copr_chroot: models.CoprChroot 514 """ 515 UsersLogic.raise_if_cant_update_copr( 516 user, copr_chroot.copr, 517 "Only owners and admins may update their projects.") 518 519 cls._update_chroot(buildroot_pkgs, repos, comps, comps_name, module_md, module_md_name, copr_chroot) 520 return copr_chroot521 522 @classmethod523 - def _update_chroot(cls, buildroot_pkgs, repos, comps, comps_name, module_md, module_md_name, copr_chroot):524 if buildroot_pkgs is not None: 525 copr_chroot.buildroot_pkgs = buildroot_pkgs 526 527 if repos is not None: 528 copr_chroot.repos = repos.replace("\n", " ") 529 530 if comps_name is not None: 531 copr_chroot.update_comps(comps) 532 copr_chroot.comps_name = comps_name 533 ActionsLogic.send_update_comps(copr_chroot) 534 535 if module_md_name is not None: 536 copr_chroot.update_module_md(module_md) 537 copr_chroot.module_md_name = module_md_name 538 ActionsLogic.send_update_module_md(copr_chroot) 539 540 db.session.add(copr_chroot)541 542 @classmethod544 UsersLogic.raise_if_cant_update_copr( 545 user, copr, 546 "Only owners and admins may update their projects.") 547 current_chroots = copr.mock_chroots 548 new_chroots = cls.mock_chroots_from_names(names) 549 # add non-existing 550 for mock_chroot in new_chroots: 551 if mock_chroot not in current_chroots: 552 db.session.add( 553 models.CoprChroot(copr=copr, mock_chroot=mock_chroot)) 554 555 # delete no more present 556 to_remove = [] 557 for mock_chroot in current_chroots: 558 if mock_chroot not in new_chroots: 559 # can't delete here, it would change current_chroots and break 560 # iteration 561 to_remove.append(mock_chroot) 562 563 for mc in to_remove: 564 copr.mock_chroots.remove(mc)565 566 @classmethod568 UsersLogic.raise_if_cant_update_copr( 569 user, copr_chroot.copr, 570 "Only owners and admins may update their projects.") 571 572 copr_chroot.comps_name = None 573 copr_chroot.comps_zlib = None 574 ActionsLogic.send_update_comps(copr_chroot) 575 db.session.add(copr_chroot)576 577 @classmethod579 UsersLogic.raise_if_cant_update_copr( 580 user, copr_chroot.copr, 581 "Only owners and admins may update their projects.") 582 583 copr_chroot.module_md_name = None 584 copr_chroot.module_md_zlib = None 585 ActionsLogic.send_update_module_md(copr_chroot) 586 db.session.add(copr_chroot)587 588 @classmethod590 """ 591 :param models.CoprChroot chroot: 592 """ 593 UsersLogic.raise_if_cant_update_copr( 594 user, copr_chroot.copr, 595 "Only owners and admins may update their projects.") 596 597 db.session.delete(copr_chroot)601 @classmethod703603 if noarch and not arch: 604 return (models.MockChroot.query 605 .filter(models.MockChroot.os_release == os_release, 606 models.MockChroot.os_version == os_version)) 607 608 return (models.MockChroot.query 609 .filter(models.MockChroot.os_release == os_release, 610 models.MockChroot.os_version == os_version, 611 models.MockChroot.arch == arch))612 613 @classmethod615 """ 616 chroot_name should be os-version-architecture, e.g. fedora-rawhide-x86_64 617 the architecture could be optional with noarch=True 618 619 Return MockChroot object for textual representation of chroot 620 """ 621 622 name_tuple = cls.tuple_from_name(chroot_name, noarch=noarch) 623 return cls.get(name_tuple[0], name_tuple[1], name_tuple[2], 624 active_only=active_only, noarch=noarch)625 626 @classmethod628 query = models.MockChroot.query 629 if active_only: 630 query = query.filter(models.MockChroot.is_active == True) 631 return query632 633 @classmethod635 name_tuple = cls.tuple_from_name(name) 636 if cls.get(*name_tuple).first(): 637 raise exceptions.DuplicateException( 638 "Mock chroot with this name already exists.") 639 new_chroot = models.MockChroot(os_release=name_tuple[0], 640 os_version=name_tuple[1], 641 arch=name_tuple[2]) 642 cls.new(new_chroot) 643 return new_chroot644 645 @classmethod 648 649 @classmethod651 name_tuple = cls.tuple_from_name(name) 652 mock_chroot = cls.get(*name_tuple).first() 653 if not mock_chroot: 654 raise exceptions.NotFoundException( 655 "Mock chroot with this name doesn't exist.") 656 657 mock_chroot.is_active = is_active 658 cls.update(mock_chroot) 659 return mock_chroot660 661 @classmethod 664 665 @classmethod667 name_tuple = cls.tuple_from_name(name) 668 mock_chroot = cls.get(*name_tuple).first() 669 if not mock_chroot: 670 raise exceptions.NotFoundException( 671 "Mock chroot with this name doesn't exist.") 672 673 cls.delete(mock_chroot)674 675 @classmethod 678 679 @classmethod681 """ 682 input should be os-version-architecture, e.g. fedora-rawhide-x86_64 683 684 the architecture could be optional with noarch=True 685 686 returns ("os", "version", "arch") or ("os", "version", None) 687 """ 688 split_name = name.split("-") 689 valid = False 690 if noarch and len(split_name) in [2, 3]: 691 valid = True 692 if not noarch and len(split_name) == 3: 693 valid = True 694 695 if not valid: 696 raise MalformedArgumentException( 697 "Chroot name is not valid") 698 699 if noarch and len(split_name) == 2: 700 split_name.append(None) 701 702 return tuple(split_name)
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 | http://epydoc.sourceforge.net |