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 ref = payload.get("ref", "") 120 121 if package.source_type_text == "git_and_tito": 122 branch = package.source_json_dict["git_branch"] 123 if branch and not ref.endswith("/"+branch): 124 return False 125 elif package.source_type_text == "mock_scm": 126 branch = package.source_json_dict["scm_branch"] 127 if branch and not ref.endswith("/"+branch): 128 return False 129 130 commits = payload.get("commits", []) 131 132 if package.source_type_text == "git_and_tito": 133 path_match = False 134 for commit in commits: 135 for file_path in commit['added'] + commit['removed'] + commit['modified']: 136 if cls.path_belong_to_package(package, file_path): 137 path_match = True 138 break 139 if not path_match: 140 return False 141 142 return True
143 144 @classmethod
145 - def path_belong_to_package(cls, package, file_path):
146 if package.source_type_text == "git_and_tito": 147 data = package.source_json_dict 148 return file_path.startswith(data["git_dir"] or '') 149 else: 150 return True
151 152 @classmethod
153 - def add(cls, user, copr, package_name, source_type=helpers.BuildSourceEnum("unset"), source_json=json.dumps({})):
154 users_logic.UsersLogic.raise_if_cant_build_in_copr( 155 user, copr, 156 "You don't have permissions to build in this copr.") 157 158 if cls.exists(copr.id, package_name).all(): 159 raise exceptions.DuplicateException( 160 "Project {}/{} already has a package '{}'" 161 .format(copr.owner_name, copr.name, package_name)) 162 163 package = models.Package( 164 name=package_name, 165 copr_id=copr.id, 166 source_type=source_type, 167 source_json=source_json 168 ) 169 170 db.session.add(package) 171 172 return package
173 174 @classmethod
175 - def exists(cls, copr_id, package_name):
176 return (models.Package.query 177 .filter(models.Package.copr_id == copr_id) 178 .filter(models.Package.name == package_name))
179 180 181 @classmethod
182 - def delete_package(cls, user, package):
183 if not user.can_edit(package.copr): 184 raise exceptions.InsufficientRightsException( 185 "You are not allowed to delete package `{}`.".format(package.id)) 186 187 for build in package.builds: 188 builds_logic.BuildsLogic.delete_build(user, build) 189 190 db.session.delete(package)
191 192 193 @classmethod
194 - def reset_package(cls, user, package):
195 if not user.can_edit(package.copr): 196 raise exceptions.InsufficientRightsException( 197 "You are not allowed to reset package `{}`.".format(package.id)) 198 199 package.source_json = json.dumps({}) 200 package.source_type = helpers.BuildSourceEnum("unset") 201 202 db.session.add(package)
203 204 205 @classmethod
206 - def build_package(cls, user, copr, package, chroot_names=None, **build_options):
207 if not package.has_source_type_set or not package.source_json: 208 raise NoPackageSourceException('Unset default source for package {package}'.format(package.name)) 209 return builds_logic.BuildsLogic.create_new(user, copr, package.source_type, package.source_json, chroot_names, **build_options)
210