X-Git-Url: http://xvm.mit.edu/gitweb/invirt/packages/invirt-dev.git/blobdiff_plain/e4e24100a77914be7540861e7b667e9e022bf650..fc9beda05f67ce8e101598ae8a7a3500e3e836e9:/invirtibuilder diff --git a/invirtibuilder b/invirtibuilder index 65423ee..f5c3821 100755 --- a/invirtibuilder +++ b/invirtibuilder @@ -7,7 +7,7 @@ attempts to build a particular package. If the build succeeds, the new version of the package is uploaded to the apt repository, tagged in its git repository, and the Invirt -superrepo is updated to point at the new version. +superproject is updated to point at the new version. If the build fails, the Invirtibuilder sends mail with the build log. @@ -20,12 +20,14 @@ Each queue file contains a file of the form pocket package hash principal where pocket is one of the pockets globally configured in -git.pockets. For instance, the pockets in XVM are "prod" and "dev". +build.pockets. For instance, the pockets in XVM are "prod" and "dev". principal is the Kerberos principal that requested the build. """ +from __future__ import with_statement + import contextlib import os import re @@ -95,12 +97,7 @@ def sanitizeVersion(version): def aptCopy(packages, dst_pocket, src_pocket): """Copy a package from one pocket to another.""" - binaries = [] - for line in b.getGitFile(package, commit, 'debian/control').split('\n'): - m = re.match('Package: (.*)$') - if m: - binaries.append(m.group(1)) - + binaries = getBinaries(package, commit) cpatureOutput(['reprepro-env', 'copy', b.pocketToApt(dst_pocket), b.pocketToApt(src_pocket), @@ -137,16 +134,16 @@ def tagSubmodule(pocket, package, ref, principal): hook. Because we reject pushes to tags in the update hook, no push can ever take out a lock on any tags. - I'm sure that long description gives you great confidence in teh + I'm sure that long description gives you great confidence in the legitimacy of my reasoning. """ - if config.git.pockets[pocket].get('allow_backtracking', False): + if not config.build.pockets[pocket].get('allow_backtracking', False): env = dict(os.environ) branch = b.pocketToGit(pocket) version = b.getVersion(package, ref) - env['GIT_COMMITTER_NAME'] = config.git.tagger.name - env['GIT_COMMITTER_EMAIL'] = config.git.tagger.email + env['GIT_COMMITTER_NAME'] = config.build.tagger.name + env['GIT_COMMITTER_EMAIL'] = config.build.tagger.email tag_msg = ('Tag %s of %s\n\n' 'Requested by %s' % (version.full_version, package, @@ -176,19 +173,19 @@ def uploadBuild(pocket, workdir): changes]) -def updateSuperrepo(pocket, package, commit, principal): - """Update the superrepo. +def updateSuperproject(pocket, package, commit, principal): + """Update the superproject. This will create a new commit on the branch for the given pocket that sets the commit for the package submodule to commit. Note that there's no locking issue here, because we disallow all - pushes to the superrepo. + pushes to the superproject. """ - superrepo = os.path.join(b._REPO_DIR, 'packages.git') + superproject = os.path.join(b._REPO_DIR, 'invirt/packages.git') branch = b.pocketToGit(pocket) tree = c.captureOutput(['git', 'ls-tree', branch], - cwd=superrepo) + cwd=superproject) new_tree = re.compile( r'^(160000 commit )[0-9a-f]*(\t%s)$' % package, re.M).sub( @@ -196,7 +193,7 @@ def updateSuperrepo(pocket, package, commit, principal): tree) new_tree_id = c.captureOutput(['git', 'mktree'], - cwd=superrepo, + cwd=superproject, stdin_str=new_tree) commit_msg = ('Update %s to version %s\n\n' @@ -205,17 +202,17 @@ def updateSuperrepo(pocket, package, commit, principal): principal)) new_commit = c.captureOutput( ['git', 'commit-tree', new_tree_hash, '-p', branch], - cwd=superrepo, + cwd=superproject, env=env, stdin_str=commit_msg) c.captureOutput( ['git', 'update-ref', 'refs/heads/%s' % branch, new_commit], - cwd=superrepo) + cwd=superproject) @contextlib.contextmanager -def packageWorkdir(package): +def packageWorkdir(package, commit): """Checkout the package in a temporary working directory. This context manager returns that working directory. The requested @@ -303,7 +300,7 @@ def build(): # do the build ourselves else: db.failed_stage = 'checking out package source' - with packageWorkdir(package) as workdir: + with packageWorkdir(package, commit) as workdir: db.failed_stage = 'preparing source package' packagedir = os.path.join(workdir, package) @@ -332,16 +329,12 @@ def build(): tagSubmodule(pocket, package, commit, principal) db.failed_stage = 'updating submodule branches' updateSubmoduleBranch(pocket, package, commit) - db.failed_stage = 'updating superrepo' - updateSuperrepo(pocket, package, commit, principal) + db.failed_stage = 'updating superproject' + updateSuperproject(pocket, package, commit, principal) db.failed_stage = 'uploading packages to apt repo' uploadBuild(pocket, workdir) db.failed_stage = 'cleaning up' - - # Finally, now that everything is done, remove the - # build queue item - os.unlink(os.path.join(b._QUEUE_DIR, build)) except: db.traceback = traceback.format_exc() else: @@ -351,15 +344,19 @@ def build(): database.session.save_or_update(db) database.session.commit() + # Finally, now that everything is done, remove the + # build queue item + os.unlink(os.path.join(b._QUEUE_DIR, build)) + reportBuild(db) class Invirtibuilder(pyinotify.ProcessEvent): """Process inotify triggers to build new packages.""" - def process_IN_CREATE(self, event): - """Handle a created file or directory. + def process_default(self, event): + """Handle an inotify event. - When an IN_CREATE event comes in, trigger the builder. + When an inotify event comes in, trigger the builder. """ build() @@ -372,7 +369,8 @@ def main(): invirtibuilder = Invirtibuilder() notifier = pyinotify.Notifier(watch_manager, invirtibuilder) watch_manager.add_watch(b._QUEUE_DIR, - pyinotify.EventsCodes.ALL_FLAGS['IN_CREATE']) + pyinotify.EventsCodes.ALL_FLAGS['IN_CREATE'] | + pyinotify.EventsCodes.ALL_FLAGS['IN_MOVED_TO']) # Before inotifying, run any pending builds; otherwise we won't # get notified for them.