--- a/testing/docker/recipes/run-task
+++ b/testing/docker/recipes/run-task
@@ -16,16 +16,17 @@ current time to improve log usefulness.
from __future__ import absolute_import, print_function, unicode_literals
import argparse
import datetime
import errno
import grp
import os
import pwd
+import re
import subprocess
import sys
def print_line(prefix, m):
now = datetime.datetime.utcnow()
print('[%s %sZ] %s' % (prefix, now.isoformat(), m), end='')
@@ -69,28 +70,51 @@ def vcs_checkout(args):
base_repo = os.environ.get('GECKO_BASE_REPOSITORY')
# We set the base repository to mozilla-central so tc-vcs doesn't get
# confused. Switch to mozilla-unified because robustcheckout works best
# with it.
if base_repo == 'https://hg.mozilla.org/mozilla-central':
base_repo = b'https://hg.mozilla.org/mozilla-unified'
+ # Specify method to checkout a revision. This defaults to revisions as
+ # SHA-1 strings, but also supports symbolic revisions like `tip` via the
+ # branch flag.
+ if os.environ.get('GECKO_HEAD_REV'):
+ revision_flag = b'--revision'
+ revision = os.environ['GECKO_HEAD_REV']
+ elif os.environ.get('GECKO_HEAD_REF'):
+ revision_flag = b'--branch'
+ revision = os.environ['GECKO_HEAD_REF']
+ else:
+ print('revision is not specified for checkout')
+ sys.exit(1)
+
res = run_and_prefix_output(b'vcs', [
b'/usr/bin/hg', b'robustcheckout',
b'--sharebase', b'/home/worker/hg-shared',
b'--purge',
b'--upstream', base_repo,
- b'--revision', os.environ['GECKO_HEAD_REV'],
+ revision_flag, revision,
os.environ['GECKO_HEAD_REPOSITORY'], args.vcs_checkout
])
if res:
sys.exit(res)
+ # Update the current revision hash and ensure that it is well formed.
+ revision = subprocess.check_output(
+ [b'/usr/bin/hg', b'log',
+ b'--rev', b'.',
+ b'--template', b'{node}'],
+ cwd=args.vcs_checkout)
+
+ assert re.match('^[a-f0-9]{40}$', revision)
+ os.environ['GECKO_HEAD_REV'] = revision
+
def main(args):
print_line('setup', 'run-task started\n')
if os.getuid() != 0:
print('assertion failed: not running as root')
return 1
@@ -149,18 +173,26 @@ def main(args):
# container. We do not bother calling setrlimit() because containers have
# their own limits.
print_line('setup', 'running as %s:%s\n' % (args.user, args.group))
os.setgroups(gids)
os.umask(022)
os.setresgid(gid, gid, gid)
os.setresuid(uid, uid, uid)
+ # Checkout the repository, setting the GECKO_HEAD_REV to the current
+ # revision hash. Revision hashes have priority over symbolic revisions. We
+ # disallow running tasks with symbolic revisions unless they have been
+ # resolved by a checkout.
if checkout:
vcs_checkout(args)
+ elif not os.environ.get('GECKO_HEAD_REV') and \
+ os.environ.get('GECKO_HEAD_REF'):
+ print('task should be defined in terms of non-symbolic revision')
+ return 1
return run_and_prefix_output('task', task_args)
if __name__ == '__main__':
# Unbuffer stdio.
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 0)