OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/env python | |
2 # Copyright (c) 2015 The Chromium Authors. All rights reserved. | |
3 # Use of this source code is governed by a BSD-style license that can be | |
4 # found in the LICENSE file. | |
5 | |
6 | |
7 """Tool to send a recipe job to run on Swarming.""" | |
8 | |
9 | |
10 import argparse | |
11 import base64 | |
12 import json | |
13 import os | |
14 import re | |
15 import subprocess | |
16 import sys | |
17 import zlib | |
18 | |
19 | |
20 SWARMING_URL = 'https://chromium.googlesource.com/external/swarming.client.git' | |
21 CLIENT_LOCATION = os.path.expanduser('~/.swarming_client') | |
22 THIS_DIR = os.path.dirname(os.path.abspath(__file__)) | |
23 ISOLATE = os.path.join(THIS_DIR, 'luci_recipe_run.isolate') | |
24 | |
25 # This is put in place in order to not need to parse this information from | |
26 # master.cfg. In the LUCI future this would all be stored in a luci.cfg | |
27 # file alongside the repo. | |
28 RECIPE_MAPPING = { | |
29 'Infra Linux Trusty 64 Tester': | |
30 ('tryserver.infra', 'infra/infra_repo_trybot', 'Ubuntu-14.04'), | |
31 'Infra Linux Precise 32 Tester': | |
32 ('tryserver.infra', 'infra/infra_repo_trybot', 'Ubuntu-12.04'), | |
33 'Infra Mac Tester': | |
34 ('tryserver.infra', 'infra/infra_repo_trybot', 'Mac'), | |
35 'Infra Win Tester': | |
36 ('tryserver.infra', 'infra/infra_repo_trybot', 'Win'), | |
37 'Infra Windows Tester': | |
38 ('tryserver.infra', 'infra/infra_repo_trybot', 'Win'), | |
39 'Infra Presubmit': | |
40 ('tryserver.infra', 'run_presubmit', 'Linux') | |
41 } | |
42 | |
43 | |
44 def parse_args(args): | |
45 # Once Clank switches to bot_update, bot_update would no longer require | |
46 # master/builder detection, and we can remove the master/builder from the args . | |
47 parser = argparse.ArgumentParser() | |
48 parser.add_argument('--builder', required=True) | |
49 parser.add_argument('--issue',required=True) | |
50 parser.add_argument('--patchset', required=True) | |
51 parser.add_argument('--revision', default='HEAD') | |
52 | |
53 return parser.parse_args(args) | |
54 | |
55 | |
56 def ensure_swarming_client(): | |
57 if not os.path.exists(CLIENT_LOCATION): | |
58 parent, target = os.path.split(CLIENT_LOCATION) | |
59 subprocess.check_call(['git', 'clone', SWARMING_URL, target], cwd=parent) | |
60 else: | |
61 subprocess.check_call(['git', 'pull'], cwd=CLIENT_LOCATION) | |
62 | |
63 | |
64 def archive_isolate(ISOLATE): | |
estaab
2015/09/15 23:05:14
lowercase here (and within this func), we're alrea
| |
65 isolate_py = os.path.join(CLIENT_LOCATION, 'isolate.py') | |
66 cmd = [ | |
67 sys.executable, isolate_py, 'archive', | |
68 '--isolated=%sd' % ISOLATE, | |
69 '--isolate-server', 'https://isolateserver.appspot.com', | |
estaab
2015/09/15 23:05:14
make constant at top of file (and for URLs below)
| |
70 '--isolate=%s' % ISOLATE] | |
71 out = subprocess.check_output(cmd) | |
72 return out.split()[0].strip() | |
73 | |
74 | |
75 def trigger_swarm(isolated, platform, build_props, factory_props): | |
76 # TODO: Make this trigger DM instead. | |
77 swarm_py = os.path.join(CLIENT_LOCATION, 'swarming.py') | |
78 build_props_gz = base64.b64encode(zlib.compress(json.dumps(build_props))) | |
79 fac_props_gz = base64.b64encode(zlib.compress(json.dumps(factory_props))) | |
80 cmd = [ | |
81 sys.executable, swarm_py, 'trigger', isolated, | |
82 '--isolate-server', 'isolateserver.appspot.com', | |
83 '--swarming', 'chromium-swarm-dev.appspot.com', | |
84 '-d', 'os', platform, | |
85 '--', | |
86 '--factory-properties-gz=%s' % fac_props_gz, | |
87 '--build-properties-gz=%s' % build_props_gz | |
88 ] | |
89 out = subprocess.check_output(cmd) | |
90 m = re.search( | |
estaab
2015/09/15 23:05:14
if not m:
logging.error("Couldn't find task id i
| |
91 r'https://chromium-swarm-dev.appspot.com/user/task/(.*)', out) | |
92 return m.group(1) | |
93 | |
94 | |
95 def trigger(builder, revision, issue, patchset, project): | |
96 """Constructs/uploads an isolated file and send the job to swarming.""" | |
97 master, recipe, platform = RECIPE_MAPPING[builder] | |
estaab
2015/09/15 23:05:14
.get(builder) and check for None and log a helpful
| |
98 build_props = { | |
99 'buildnumber': 1, | |
100 'buildername': builder, | |
101 'recipe': recipe, | |
102 'mastername': master, | |
103 'slavename': 'fakeslave', | |
104 'revision': revision, | |
105 'patch_project': project, | |
106 } | |
107 if issue: | |
108 build_props['issue'] = issue | |
109 if patchset: | |
110 build_props['patchset'] = patchset | |
111 factory_props = { | |
112 'recipe': recipe | |
113 } | |
114 ensure_swarming_client() | |
115 arun_isolated = archive_isolate(ISOLATE) | |
116 task = trigger_swarm(arun_isolated, platform, build_props, factory_props) | |
117 print 'https://luci-milo.appspot.com/swarming/%s' % task | |
estaab
2015/09/15 23:05:14
Nice.
| |
118 | |
119 | |
120 def main(args): | |
121 args = parse_args(args) | |
122 trigger(args.builder, args.revision) | |
123 | |
124 | |
125 if __name__ == '__main__': | |
126 sys.exit(main(sys.argv[1:])) | |
OLD | NEW |