Package coprs :: Package logic :: Module packages_logic
[hide private]
[frames] | no frames]

Source Code for Module coprs.logic.packages_logic

  1  import json 
  2  import time 
  3  from sqlalchemy import or_ 
  4  from sqlalchemy import and_, bindparam, Integer 
  5  from sqlalchemy.sql import false, true, text 
  6   
  7  from coprs import app 
  8  from coprs import db 
  9  from coprs import exceptions 
 10  from coprs import models 
 11  from coprs import helpers 
 12  from coprs import forms 
 13   
 14  from coprs.logic import coprs_logic 
 15  from coprs.logic import users_logic 
 16  from coprs.logic import builds_logic 
 17   
 18  from coprs.constants import DEFAULT_BUILD_TIMEOUT 
 19   
 20  log = app.logger 
21 22 23 -class PackagesLogic(object):
24 25 @classmethod
26 - def get_by_id(cls, package_id):
28 29 @classmethod
30 - def get_all(cls, copr_id):
31 return (models.Package.query 32 .filter(models.Package.copr_id == copr_id))
33 34 @classmethod
35 - def get_copr_packages_list(cls, copr):
36 query_select = """ 37 SELECT package.name, build.pkg_version, build.submitted_on, package.webhook_rebuild, order_to_status(subquery2.min_order_for_a_build) AS status 38 FROM package 39 LEFT OUTER JOIN (select MAX(build.id) as max_build_id_for_a_package, package_id 40 FROM build 41 WHERE build.copr_id = :copr_id 42 GROUP BY package_id) as subquery1 ON subquery1.package_id = package.id 43 LEFT OUTER JOIN build ON build.id = subquery1.max_build_id_for_a_package 44 LEFT OUTER JOIN (select build_id, min(status_to_order(status)) as min_order_for_a_build 45 FROM build_chroot 46 GROUP BY build_id) as subquery2 ON subquery2.build_id = subquery1.max_build_id_for_a_package 47 WHERE package.copr_id = :copr_id; 48 """ 49 50 if db.engine.url.drivername == "sqlite": 51 def sqlite_status_to_order(x): 52 if x == 0: 53 return 0 54 elif x == 3: 55 return 1 56 elif x == 6: 57 return 2 58 elif x == 7: 59 return 3 60 elif x == 4: 61 return 4 62 elif x == 1: 63 return 5 64 elif x == 5: 65 return 6 66 return 1000
67 68 def sqlite_order_to_status(x): 69 if x == 0: 70 return 0 71 elif x == 1: 72 return 3 73 elif x == 2: 74 return 6 75 elif x == 3: 76 return 7 77 elif x == 4: 78 return 4 79 elif x == 5: 80 return 1 81 elif x == 6: 82 return 5 83 return 1000
84 85 conn = db.engine.connect() 86 conn.connection.create_function("status_to_order", 1, sqlite_status_to_order) 87 conn.connection.create_function("order_to_status", 1, sqlite_order_to_status) 88 statement = text(query_select) 89 statement.bindparams(bindparam("copr_id", Integer)) 90 result = conn.execute(statement, {"copr_id": copr.id}) 91 else: 92 statement = text(query_select) 93 statement.bindparams(bindparam("copr_id", Integer)) 94 result = db.engine.execute(statement, {"copr_id": copr.id}) 95 96 return result 97 98 @classmethod
99 - def get(cls, copr_id, package_name):
100 return models.Package.query.filter(models.Package.copr_id == copr_id, 101 models.Package.name == package_name)
102 103 @classmethod
104 - def get_for_webhook_rebuild(cls, copr_id, webhook_secret, clone_url, payload):
105 packages = (models.Package.query.join(models.Copr) 106 .filter(models.Copr.webhook_secret == webhook_secret) 107 .filter(models.Package.copr_id == copr_id) 108 .filter(models.Package.webhook_rebuild == true()) 109 .filter(models.Package.source_json.contains(clone_url))) 110 111 result = [] 112 for package in packages: 113 if cls.commits_belong_to_package(package, payload): 114 result += [package] 115 return result
116 117 @classmethod
118 - def commits_belong_to_package(cls, package, payload):
119 if payload.get("ref_type", None) == "tag": 120 return True 121 122 ref = payload.get("ref", "") 123 124 if package.source_type_text == "git_and_tito": 125 branch = package.source_json_dict["git_branch"] 126 if branch and not ref.endswith("/"+branch): 127 return False 128 elif package.source_type_text == "mock_scm": 129 branch = package.source_json_dict["scm_branch"] 130 if branch and not ref.endswith("/"+branch): 131 return False 132 133 commits = payload.get("commits", []) 134 135 if package.source_type_text == "git_and_tito": 136 path_match = False 137 for commit in commits: 138 for file_path in commit['added'] + commit['removed'] + commit['modified']: 139 if cls.path_belong_to_package(package, file_path): 140 path_match = True 141 break 142 if not path_match: 143 return False 144 145 return True
146 147 @classmethod
148 - def path_belong_to_package(cls, package, file_path):
149 if package.source_type_text == "git_and_tito": 150 data = package.source_json_dict 151 return file_path.startswith(data["git_dir"] or '') 152 else: 153 return True
154 155 @classmethod
156 - def add(cls, user, copr, package_name, source_type=helpers.BuildSourceEnum("unset"), source_json=json.dumps({})):
157 users_logic.UsersLogic.raise_if_cant_build_in_copr( 158 user, copr, 159 "You don't have permissions to build in this copr.") 160 161 if cls.exists(copr.id, package_name).all(): 162 raise exceptions.DuplicateException( 163 "Project {}/{} already has a package '{}'" 164 .format(copr.owner_name, copr.name, package_name)) 165 166 package = models.Package( 167 name=package_name, 168 copr_id=copr.id, 169 source_type=source_type, 170 source_json=source_json 171 ) 172 173 db.session.add(package) 174 175 return package
176 177 @classmethod
178 - def exists(cls, copr_id, package_name):
179 return (models.Package.query 180 .filter(models.Package.copr_id == copr_id) 181 .filter(models.Package.name == package_name))
182 183 184 @classmethod
185 - def delete_package(cls, user, package):
186 if not user.can_edit(package.copr): 187 raise exceptions.InsufficientRightsException( 188 "You are not allowed to delete package `{}`.".format(package.id)) 189 190 for build in package.builds: 191 builds_logic.BuildsLogic.delete_build(user, build) 192 193 db.session.delete(package)
194 195 196 @classmethod
197 - def reset_package(cls, user, package):
198 if not user.can_edit(package.copr): 199 raise exceptions.InsufficientRightsException( 200 "You are not allowed to reset package `{}`.".format(package.id)) 201 202 package.source_json = json.dumps({}) 203 package.source_type = helpers.BuildSourceEnum("unset") 204 205 db.session.add(package)
206 207 208 @classmethod
209 - def build_package(cls, user, copr, package, chroot_names=None, **build_options):
210 if not package.has_source_type_set or not package.source_json: 211 raise NoPackageSourceException('Unset default source for package {package}'.format(package.name)) 212 return builds_logic.BuildsLogic.create_new(user, copr, package.source_type, package.source_json, chroot_names, **build_options)
213