| Index: luci_hacks/trigger_luci_job.py
|
| diff --git a/luci_hacks/trigger_luci_job.py b/luci_hacks/trigger_luci_job.py
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..84cdec8da15ca4bc131709f18747432ae928af67
|
| --- /dev/null
|
| +++ b/luci_hacks/trigger_luci_job.py
|
| @@ -0,0 +1,128 @@
|
| +#!/usr/bin/env python
|
| +# Copyright (c) 2015 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +
|
| +"""Tool to send a recipe job to run on Swarming."""
|
| +
|
| +
|
| +import argparse
|
| +import base64
|
| +import json
|
| +import os
|
| +import re
|
| +import subprocess
|
| +import sys
|
| +import zlib
|
| +
|
| +
|
| +SWARMING_URL = 'https://chromium.googlesource.com/external/swarming.client.git'
|
| +CLIENT_LOCATION = os.path.expanduser('~/.swarming_client')
|
| +THIS_DIR = os.path.dirname(os.path.abspath(__file__))
|
| +ISOLATE = os.path.join(THIS_DIR, 'luci_recipe_run.isolate')
|
| +
|
| +# This is put in place in order to not need to parse this information from
|
| +# master.cfg. In the LUCI future this would all be stored in a luci.cfg
|
| +# file alongside the repo.
|
| +RECIPE_MAPPING = {
|
| + 'Infra Linux Trusty 64 Tester':
|
| + ('tryserver.infra', 'infra/infra_repo_trybot', 'Ubuntu-14.04'),
|
| + 'Infra Linux Precise 32 Tester':
|
| + ('tryserver.infra', 'infra/infra_repo_trybot', 'Ubuntu-12.04'),
|
| + 'Infra Mac Tester':
|
| + ('tryserver.infra', 'infra/infra_repo_trybot', 'Mac'),
|
| + 'Infra Win Tester':
|
| + ('tryserver.infra', 'infra/infra_repo_trybot', 'Win'),
|
| + 'Infra Windows Tester':
|
| + ('tryserver.infra', 'infra/infra_repo_trybot', 'Win'),
|
| + 'Infra Presubmit':
|
| + ('tryserver.infra', 'run_presubmit', 'Linux')
|
| +}
|
| +
|
| +
|
| +def parse_args(args):
|
| + # Once Clank switches to bot_update, bot_update would no longer require
|
| + # master/builder detection, and we can remove the master/builder from the args
|
| + parser = argparse.ArgumentParser()
|
| + parser.add_argument('--builder', required=True)
|
| + parser.add_argument('--issue',required=True)
|
| + parser.add_argument('--patchset', required=True)
|
| + parser.add_argument('--revision', default='HEAD')
|
| + parser.add_argument('--patch_project')
|
| +
|
| + return parser.parse_args(args)
|
| +
|
| +
|
| +def ensure_swarming_client():
|
| + if not os.path.exists(CLIENT_LOCATION):
|
| + parent, target = os.path.split(CLIENT_LOCATION)
|
| + subprocess.check_call(['git', 'clone', SWARMING_URL, target], cwd=parent)
|
| + else:
|
| + subprocess.check_call(['git', 'pull'], cwd=CLIENT_LOCATION)
|
| +
|
| +
|
| +def archive_isolate(isolate):
|
| + isolate_py = os.path.join(CLIENT_LOCATION, 'isolate.py')
|
| + cmd = [
|
| + sys.executable, isolate_py, 'archive',
|
| + '--isolated=%sd' % isolate,
|
| + '--isolate-server', 'https://isolateserver.appspot.com',
|
| + '--isolate=%s' % isolate]
|
| + out = subprocess.check_output(cmd)
|
| + return out.split()[0].strip()
|
| +
|
| +
|
| +def trigger_swarm(isolated, platform, build_props, factory_props):
|
| + # TODO: Make this trigger DM instead.
|
| + swarm_py = os.path.join(CLIENT_LOCATION, 'swarming.py')
|
| + build_props_gz = base64.b64encode(zlib.compress(json.dumps(build_props)))
|
| + fac_props_gz = base64.b64encode(zlib.compress(json.dumps(factory_props)))
|
| + cmd = [
|
| + sys.executable, swarm_py, 'trigger', isolated,
|
| + '--isolate-server', 'isolateserver.appspot.com',
|
| + '--swarming', 'chromium-swarm-dev.appspot.com',
|
| + '-d', 'os', platform,
|
| + '--',
|
| + '--factory-properties-gz=%s' % fac_props_gz,
|
| + '--build-properties-gz=%s' % build_props_gz
|
| + ]
|
| + out = subprocess.check_output(cmd)
|
| + m = re.search(
|
| + r'https://chromium-swarm-dev.appspot.com/user/task/(.*)', out)
|
| + return m.group(1)
|
| +
|
| +
|
| +def trigger(builder, revision, issue, patchset, project):
|
| + """Constructs/uploads an isolated file and send the job to swarming."""
|
| + master, recipe, platform = RECIPE_MAPPING[builder]
|
| + build_props = {
|
| + 'buildnumber': 1,
|
| + 'buildername': builder,
|
| + 'recipe': recipe,
|
| + 'mastername': master,
|
| + 'slavename': 'fakeslave',
|
| + 'revision': revision,
|
| + 'patch_project': project,
|
| + }
|
| + if issue:
|
| + build_props['issue'] = issue
|
| + if patchset:
|
| + build_props['patchset'] = patchset
|
| + factory_props = {
|
| + 'recipe': recipe
|
| + }
|
| + ensure_swarming_client()
|
| + arun_isolated = archive_isolate(ISOLATE)
|
| + task = trigger_swarm(arun_isolated, platform, build_props, factory_props)
|
| + print 'https://luci-milo.appspot.com/swarming/%s' % task
|
| +
|
| +
|
| +def main(args):
|
| + args = parse_args(args)
|
| + trigger(args.builder, args.revision, args.issue,
|
| + args.patchset, args.patch_project)
|
| +
|
| +
|
| +if __name__ == '__main__':
|
| + sys.exit(main(sys.argv[1:]))
|
|
|