- Timestamp:
- Nov 22, 2009, 4:07:20 PM (15 years ago)
- Location:
- trunk/packages/invirt-dev
- Files:
-
- 3 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/packages/invirt-dev/invirtibuilder
r2542 r2543 35 35 import pyinotify 36 36 37 from invirt.config import structs as config 37 import invirt.builder as b 38 38 from invirt import database 39 39 40 40 41 _QUEUE_DIR = '/var/lib/invirt-dev/queue'42 _REPO_DIR = '/srv/git'43 _LOG_DIR = '/var/log/invirt/builds'44 _HOOKS_DIR = '/usr/share/invirt-dev/build.d'45 46 47 41 DISTRIBUTION = 'hardy' 48 49 50 class InvalidBuild(ValueError):51 pass52 53 54 def captureOutput(popen_args, stdin_str=None, *args, **kwargs):55 """Capture stdout from a command.56 57 This method will proxy the arguments to subprocess.Popen. It58 returns the output from the command if the call succeeded and59 raises an exception if the process returns a non-0 value.60 61 This is intended to be a variant on the subprocess.check_call62 function that also allows you access to the output from the63 command.64 """65 if 'stdin' not in kwargs:66 kwargs['stdin'] = subprocess.PIPE67 if 'stdout' not in kwargs:68 kwargs['stdout'] = subprocess.PIPE69 if 'stderr' not in kwargs:70 kwargs['stderr'] = subprocess.STDOUT71 p = subprocess.Popen(popen_args, *args, **kwargs)72 out, _ = p.communicate(stdin_str)73 if p.returncode:74 raise subprocess.CalledProcessError(p.returncode, popen_args, out)75 return out76 77 78 def getRepo(package):79 """Return the path to the git repo for a given package."""80 return os.path.join(_REPO_DIR, 'packages', '%s.git' % package)81 82 83 def pocketToGit(pocket):84 """Map a pocket in the configuration to a git branch."""85 return config.git.pockets[pocket].get('git', pocket)86 87 88 def pocketToApt(pocket):89 """Map a pocket in the configuration to an apt repo pocket."""90 return config.git.pockets[pocket].get('apt', pocket)91 92 93 def getGitFile(package, ref, path):94 """Return the contents of a path from a git ref in a package."""95 return captureOutput(['git', 'cat-file', 'blob', '%s:%s' % (ref, path)],96 cwd=getRepo(package))97 98 99 def getChangelog(package, ref):100 """Get a changelog object for a given ref in a given package.101 102 This returns a debian_bundle.changelog.Changelog object for a103 given ref of a given package.104 """105 return changelog.Changelog(getGitFile(package, ref, 'debian/changelog'))106 107 108 def getVersion(package, ref):109 """Get the version of a given package at a particular ref."""110 return getChangelog(package, ref).get_version()111 42 112 43 … … 146 77 147 78 148 def validateBuild(pocket, package, commit):149 """Given the parameters of a new build, validate that build.150 151 The checks this function performs vary based on whether or not the152 pocket is configured with allow_backtracking.153 154 A build of a pocket without allow_backtracking set must be a155 fast-forward of the previous revision, and the most recent version156 in the changelog most be strictly greater than the version157 currently in the repository.158 159 In all cases, this revision of the package can only have the same160 version number as any other revision currently in the apt161 repository if they have the same commit ID.162 163 If it's unspecified, it is assumed that pocket do not164 allow_backtracking.165 166 If this build request fails validation, this function will raise a167 InvalidBuild exception, with information about why the validation168 failed.169 170 If this build request can be satisfied by copying the package from171 another pocket, then this function returns that pocket. Otherwise,172 it returns True.173 """174 package_repo = getRepo(package)175 new_version = getVersion(package, commit)176 177 for p in config.git.pockets:178 if p == pocket:179 continue180 181 b = pocketToGit(p)182 current_commit = captureOutput(['git', 'rev-parse', b],183 cwd=package_repo)184 current_version = getVersion(package, b)185 186 if current_version == new_version:187 if current_commit == commit:188 return p189 else:190 raise InvalidBuild('Version %s of %s already available in '191 'pocket %s from commit %s' %192 (new_version, package, p, current_commit))193 194 if config.git.pockets[pocket].get('allow_backtracking', False):195 branch = pocketToGit(pocket)196 current_version = getVersion(package, branch)197 if new_version <= current_version:198 raise InvalidBuild('New version %s of %s is not newer than '199 'version %s currently in pocket %s' %200 (new_version, package, current_version, pocket))201 202 # Almost by definition, A is a fast-forward of B if B..A is203 # empty204 if not captureOutput(['git', 'rev-list', '%s..%s' % (commit, branch)]):205 raise InvalidBuild('New commit %s of %s is not a fast-forward of'206 'commit currently in pocket %s' %207 (commit, package, pocket))208 209 210 79 def sanitizeVersion(version): 211 80 """Sanitize a Debian package version for use as a git tag. … … 221 90 """Copy a package from one pocket to another.""" 222 91 binaries = [] 223 for line in getGitFile(package, commit, 'debian/control').split('\n'):92 for line in b.getGitFile(package, commit, 'debian/control').split('\n'): 224 93 m = re.match('Package: (.*)$') 225 94 if m: … … 227 96 228 97 cpatureOutput(['reprepro-env', 'copy', 229 pocketToApt(dst_pocket),230 pocketToApt(src_pocket),98 b.pocketToApt(dst_pocket), 99 b.pocketToApt(src_pocket), 231 100 package] + binaries) 232 101 … … 238 107 args.append('-A') 239 108 args.append(getDscName(package, ref)) 240 c aptureOutput(args, cwd=workdir, stdout=None)109 c.captureOutput(args, cwd=workdir, stdout=None) 241 110 242 111 … … 267 136 if config.git.pockets[pocket].get('allow_backtracking', False): 268 137 env = dict(os.environ) 269 branch = pocketToGit(pocket)270 version = getVersion(package, ref)138 branch = b.pocketToGit(pocket) 139 version = b.getVersion(package, ref) 271 140 272 141 env['GIT_COMMITTER_NAME'] = config.git.tagger.name … … 277 146 principal)) 278 147 279 c aptureOutput(148 c.captureOutput( 280 149 ['git', 'tag', '-m', tag_msg, commit], 281 150 stdout=None, … … 285 154 def updateSubmoduleBranch(pocket, package, ref): 286 155 """Update the appropriately named branch in the submodule.""" 287 branch = pocketToGit(pocket)288 c aptureOutput(156 branch = b.pocketToGit(pocket) 157 c.captureOutput( 289 158 ['git', 'update-ref', 'refs/heads/%s' % branch, ref]) 290 159 … … 292 161 def uploadBuild(pocket, workdir): 293 162 """Upload all build products in the work directory.""" 294 apt = pocketToApt(pocket)163 apt = b.pocketToApt(pocket) 295 164 for changes in glob.glob(os.path.join(workdir, '*.changes')): 296 c aptureOutput(['reprepro-env',165 c.captureOutput(['reprepro-env', 297 166 'include', 298 167 '--ignore=wrongdistribution', … … 310 179 pushes to the superrepo. 311 180 """ 312 superrepo = os.path.join( _REPO_DIR, 'packages.git')313 branch = pocketToGit(pocket)314 tree = c aptureOutput(['git', 'ls-tree', branch],181 superrepo = os.path.join(b._REPO_DIR, 'packages.git') 182 branch = b.pocketToGit(pocket) 183 tree = c.captureOutput(['git', 'ls-tree', branch], 315 184 cwd=superrepo) 316 185 … … 320 189 tree) 321 190 322 new_tree_id = c aptureOutput(['git', 'mktree'],191 new_tree_id = c.captureOutput(['git', 'mktree'], 323 192 cwd=superrepo, 324 193 stdin_str=new_tree) … … 328 197 version.full_version, 329 198 principal)) 330 new_commit = c aptureOutput(199 new_commit = c.captureOutput( 331 200 ['git', 'commit-tree', new_tree_hash, '-p', branch], 332 201 cwd=superrepo, … … 334 203 stdin_str=commit_msg) 335 204 336 c aptureOutput(205 c.captureOutput( 337 206 ['git', 'update-ref', 'refs/heads/%s' % branch, new_commit], 338 207 cwd=superrepo) … … 354 223 p_archive = subprocess.Popen( 355 224 ['git', 'archive', 356 '--remote=file://%s' % getRepo(package),225 '--remote=file://%s' % b.getRepo(package), 357 226 '--prefix=%s' % package, 358 227 commit, … … 376 245 """Run hooks to report the results of a build attempt.""" 377 246 378 c aptureOutput(['run-parts',247 c.captureOutput(['run-parts', 379 248 '--arg=%s' % build.build_id, 380 249 '--', 381 _HOOKS_DIR])250 b._HOOKS_DIR]) 382 251 383 252 … … 390 259 while True: 391 260 stage = 'processing incoming job' 392 queue = os.listdir( _QUEUE_DIR)261 queue = os.listdir(b._QUEUE_DIR) 393 262 if not queue: 394 263 break 395 264 396 265 build = min(queue) 397 job = open(os.path.join( _QUEUE_DIR, build)).read().strip()266 job = open(os.path.join(b._QUEUE_DIR, build)).read().strip() 398 267 pocket, package, commit, principal = job.split() 399 268 … … 413 282 src = validateBuild(pocket, package, commit) 414 283 415 db.version = str( getVersion(package, commit))284 db.version = str(b.getVersion(package, commit)) 416 285 417 286 # If validateBuild returns something other than True, then … … 439 308 # environment scrubbing. Since we're not, debuild 440 309 # complains about not having an orig.tar.gz 441 c aptureOutput(['dpkg-buildpackage', '-us', '-uc', '-S'],310 c.captureOutput(['dpkg-buildpackage', '-us', '-uc', '-S'], 442 311 cwd=packagedir, 443 312 stdout=None) … … 447 316 sbuildAll(package, commit, workdir) 448 317 finally: 449 logdir = os.path.join( _LOG_DIR, db.build_id)318 logdir = os.path.join(b._LOG_DIR, db.build_id) 450 319 if not os.path.exists(logdir): 451 320 os.makedirs(logdir) … … 466 335 # Finally, now that everything is done, remove the 467 336 # build queue item 468 os.unlink(os.path.join( _QUEUE_DIR, build))337 os.unlink(os.path.join(b._QUEUE_DIR, build)) 469 338 except: 470 339 db.traceback = traceback.format_exc() … … 496 365 invirtibuilder = Invirtibuilder() 497 366 notifier = pyinotify.Notifier(watch_manager, invirtibuilder) 498 watch_manager.add_watch( _QUEUE_DIR,367 watch_manager.add_watch(b._QUEUE_DIR, 499 368 pyinotify.EventsCodes.ALL_FLAGS['IN_CREATE']) 500 369
Note: See TracChangeset
for help on using the changeset viewer.