Trees | Indices | Help |
---|
|
1 import json 2 import re 3 4 from sqlalchemy import bindparam, Integer, func 5 from sqlalchemy.sql import true, text 6 from sqlalchemy.orm import selectinload 7 8 from coprs import app 9 from coprs import db 10 from coprs import exceptions 11 from coprs import models 12 from coprs import helpers 13 14 from coprs.logic import users_logic 15 from coprs.logic import builds_logic 16 from copr_common.enums import StatusEnum 17 18 log = app.logger22 23 @classmethod 26 27 @classmethod 31 32 @classmethod 36 37 @classmethod76 77 @classmethod39 packages = (models.Package.query.filter_by(copr_dir_id=copr_dir_id) 40 .order_by(models.Package.name).all()) 41 pkg_ids = [package.id for package in packages] 42 builds_ids = models.Build.query \ 43 .filter(models.Build.package_id.in_(pkg_ids)) \ 44 .with_entities(func.max(models.Build.id)) \ 45 .group_by(models.Build.package_id) 46 47 # map package.id => package object in packages array 48 packages_map = {package.id: package for package in packages} 49 50 builds = (models.Build.query.filter(models.Build.id.in_(builds_ids)) 51 .options(selectinload('build_chroots')) 52 .yield_per(1000)) 53 54 for build in builds: 55 class SmallBuild(): 56 pass57 58 if not build.package_id: 59 continue 60 61 if small_build: 62 small_build_object = SmallBuild() 63 for param in ['state', 'status', 'pkg_version', 64 'submitted_on']: 65 # we don't want to keep all the attributes here in memory, and 66 # also we don't need any further info about assigned 67 # build_chroot(s). So we only pick the info we need, and throw 68 # the expensive objects away. 69 setattr(small_build_object, param, getattr(build, param)) 70 packages_map[build.package_id].latest_build = small_build_object 71 else: 72 packages_map[build.package_id].latest_build = build 73 74 75 return packages79 return models.Package.query.filter(models.Package.copr_id == copr_id, 80 models.Package.name == package_name)81 82 @classmethod84 return models.Package.query.filter(models.Package.copr_dir_id == copr_dir_id, 85 models.Package.name == package_name)86 87 @classmethod89 return models.Package.query.join(models.CoprDir).filter( 90 models.CoprDir.id==copr_dir.id, 91 models.Package.name==package_name 92 )93 94 @classmethod96 package = cls.get_by_dir(copr_dir, package_name).first() 97 98 if package: 99 return package 100 101 package = models.Package( 102 name=src_pkg.name, 103 copr=src_pkg.copr, 104 source_type=src_pkg.source_type, 105 source_json=src_pkg.source_json, 106 copr_dir=copr_dir) 107 108 db.session.add(package) 109 return package110 111 @classmethod113 clone_url_stripped = re.sub(r'(\.git)?/*$', '', clone_url) 114 115 packages = (models.Package.query.join(models.Copr) 116 .filter(models.Copr.webhook_secret == webhook_secret) 117 .filter(models.Package.source_type == helpers.BuildSourceEnum("scm")) 118 .filter(models.Package.copr_id == copr_id) 119 .filter(models.Package.webhook_rebuild == true()) 120 .filter(models.Package.source_json.contains(clone_url_stripped))) 121 122 result = [] 123 for package in packages: 124 package_clone_url = package.source_json_dict.get('clone_url', '') 125 package_clone_url_stripped = re.sub(r'(\.git)?/*$', '', package_clone_url) 126 127 if package_clone_url_stripped != clone_url_stripped: 128 continue 129 130 if cls.commits_belong_to_package(package, commits, ref_type, ref): 131 result += [package] 132 133 return result134 135 @classmethod137 if ref_type == "tag": 138 matches = re.search(r'(.*)-[^-]+-[^-]+$', ref) 139 if matches and package.name != matches.group(1): 140 return False 141 else: 142 return True 143 144 committish = package.source_json_dict.get("committish") or '' 145 if committish and not ref.endswith(committish): 146 return False 147 148 for commit in commits: 149 subdir = package.source_json_dict.get('subdirectory') 150 sm = helpers.SubdirMatch(subdir) 151 changed = set() 152 for ch in ['added', 'removed', 'modified']: 153 changed |= set(commit.get(ch, [])) 154 155 for file_path in changed: 156 if sm.match(file_path): 157 return True 158 159 return False160 161 @classmethod162 - def add(cls, user, copr_dir, package_name, source_type=helpers.BuildSourceEnum("unset"), source_json=json.dumps({})):163 users_logic.UsersLogic.raise_if_cant_build_in_copr( 164 user, copr_dir.copr, 165 "You don't have permissions to build in this copr.") 166 167 if cls.exists(copr_dir.id, package_name).all(): 168 raise exceptions.DuplicateException( 169 "Project dir {} already has a package '{}'" 170 .format(copr_dir.full_name, package_name)) 171 172 package = models.Package( 173 name=package_name, 174 copr=copr_dir.copr, 175 copr_dir=copr_dir, 176 source_type=source_type, 177 source_json=source_json, 178 ) 179 180 db.session.add(package) 181 return package182 183 @classmethod185 return (models.Package.query 186 .filter(models.Package.copr_dir_id == copr_dir_id) 187 .filter(models.Package.name == package_name))188 189 190 @classmethod192 if not user.can_edit(package.copr): 193 raise exceptions.InsufficientRightsException( 194 "You are not allowed to delete package `{}`.".format(package.id)) 195 196 to_delete = [] 197 for build in package.builds: 198 to_delete.append(build.id) 199 200 builds_logic.BuildsLogic.delete_builds(user, to_delete) 201 db.session.delete(package)202 203 204 @classmethod206 if not user.can_edit(package.copr): 207 raise exceptions.InsufficientRightsException( 208 "You are not allowed to reset package `{}`.".format(package.id)) 209 210 package.source_json = json.dumps({}) 211 package.source_type = helpers.BuildSourceEnum("unset") 212 213 db.session.add(package)214 215 216 @classmethod217 - def build_package(cls, user, copr, package, chroot_names=None, copr_dirname=None, **build_options):218 if not package.has_source_type_set or not package.source_json: 219 raise exceptions.NoPackageSourceException('Unset default source for package {0}'.format(package.name)) 220 221 build = builds_logic.BuildsLogic.create_new( 222 user, copr, package.source_type, package.source_json, chroot_names, 223 copr_dirname=copr_dirname, package=package, **build_options) 224 return build225 226 227 @classmethod229 new_builds = [] 230 231 batch = models.Batch() 232 db.session.add(batch) 233 234 for package in packages: 235 git_hashes = {} 236 skip_import = False 237 source_build = None 238 239 if (package.source_type == helpers.BuildSourceEnum('upload') or 240 package.source_type == helpers.BuildSourceEnum('link')): 241 source_build = package.last_build() 242 243 if not source_build or not source_build.build_chroots[0].git_hash: 244 raise exceptions.NoPackageSourceException( 245 "Could not get latest git hash for {}".format(package.name)) 246 247 for chroot_name in chroot_names: 248 git_hashes[chroot_name] = source_build.build_chroots[0].git_hash 249 skip_import = True 250 251 new_build = builds_logic.BuildsLogic.create_new( 252 user, 253 copr, 254 package.source_type, 255 package.source_json, 256 chroot_names, 257 package=package, 258 git_hashes=git_hashes, 259 skip_import=skip_import, 260 batch=batch, 261 **build_options) 262 263 if source_build: 264 new_build.package_id = source_build.package_id 265 new_build.pkg_version = source_build.pkg_version 266 267 new_builds.append(new_build) 268 269 return new_builds270 271 @classmethod273 pkgs_to_delete = models.Package.query\ 274 .join(models.Copr, models.Package.copr_id == models.Copr.id)\ 275 .filter(models.Copr.deleted == True) 276 277 counter = 0 278 for pkg in pkgs_to_delete: 279 cls.delete_package(pkg.copr.user, pkg) 280 counter += 1 281 if counter >= 100: 282 db.session.commit() 283 counter = 0 284 285 if counter > 0: 286 db.session.commit()287 288 @classmethod290 builds = {} 291 for chroot in package.chroots: 292 for build in reversed(package.builds): 293 try: 294 build_chroot = build.chroots_dict_by_name[chroot.name] 295 except KeyError: 296 continue 297 if build_chroot.status not in [StatusEnum("succeeded"), StatusEnum("forked")]: 298 continue 299 if build not in builds: 300 builds[build] = [build_chroot] 301 else: 302 builds[build].append(build_chroot) 303 break 304 return builds305
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 | http://epydoc.sourceforge.net |