blob: a0c6a0104d81f7a8c26501ab38e591909e0e38fc [file] [log] [blame]
Don Garrettbe3608b2018-06-05 17:10:09 -07001# -*- coding: utf-8 -*-
2# Copyright 2018 The Chromium OS 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
Don Garrettff45f4b2018-10-04 09:08:01 -07006# pylint: disable=line-too-long
Don Garrettbe3608b2018-06-05 17:10:09 -07007"""Generate LUCI Scheduler config file.
8
9This generates the LUCI Scheduler configuration file for ChromeOS builds based
10on the chromeos_config contents.
11
Don Garrettff45f4b2018-10-04 09:08:01 -070012Changes to chromite/config/luci-scheduler.cfg will be autodeployed:
13 http://cros-goldeneye/chromeos/legoland/builderHistory?buildConfig=luci-scheduler-updater
Don Garrettbe3608b2018-06-05 17:10:09 -070014
Don Garrettc8323dc2018-08-22 15:58:26 -070015Notes:
16 Normal builds are scheduled based on the builder values for
17 'schedule' and 'triggered_gitiles' in config/chromeos_config.py.
18
19 Branched builds are scheduled based on the function
20 chromeos_config.BranchScheduleConfig()
Don Garrettbe3608b2018-06-05 17:10:09 -070021"""
Don Garrettff45f4b2018-10-04 09:08:01 -070022# pylint: enable=line-too-long
Don Garrettbe3608b2018-06-05 17:10:09 -070023
24from __future__ import print_function
25
26import sys
27
Don Garrett8dace272018-07-19 14:07:42 -070028from chromite.config import chromeos_config
Don Garrettbe3608b2018-06-05 17:10:09 -070029from chromite.lib import commandline
30from chromite.lib import config_lib
31
32
Mike Frysinger74a6cc82020-02-14 14:16:22 -050033assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'
34
35
Don Garrettbe3608b2018-06-05 17:10:09 -070036_CONFIG_HEADER = """# Defines buckets on luci-scheduler.appspot.com.
37#
38# For schema of this file and documentation see ProjectConfig message in
Mike Frysinger92dc6492021-02-17 16:01:09 -050039# https://github.com/luci/luci-go/blob/HEAD/scheduler/appengine/messages/config.proto
Don Garrettbe3608b2018-06-05 17:10:09 -070040
41# Generated with chromite/scripts/gen_luci_scheduler
42
Don Garrettff45f4b2018-10-04 09:08:01 -070043# Autodeployed with:
44# http://cros-goldeneye/chromeos/legoland/builderHistory?buildConfig=luci-scheduler-updater
45
Don Garrettbe3608b2018-06-05 17:10:09 -070046acl_sets {
47 name: "default"
48 acls {
49 role: READER
50 granted_to: "group:googlers"
51 }
52 acls {
53 role: OWNER
54 granted_to: "group:project-chromeos-admins"
55 }
Jason D. Clintona9e374a2018-10-18 18:41:00 -060056 acls {
57 role: TRIGGERER
58 granted_to: "group:mdb/chromeos-build-access"
LaMont Jones48ddfd92020-09-16 13:46:41 -060059 }
60 acls {
61 role: TRIGGERER
LaMont Jonesd1bb0002020-09-16 09:35:10 -060062 granted_to: "group:project-chromeos-buildbucket-schedulers"
Jason D. Clintona9e374a2018-10-18 18:41:00 -060063 }
Don Garrettbe3608b2018-06-05 17:10:09 -070064}
65"""
66
Don Garrett9a0d90c2018-10-30 12:47:14 -070067def buildJobName(build_config):
68 if 'schedule_branch' in build_config:
69 return '%s-%s' % (build_config.schedule_branch, build_config.name)
70 else:
71 return build_config.name
72
Don Garrettbe3608b2018-06-05 17:10:09 -070073
74def genSchedulerJob(build_config):
75 """Generate the luci scheduler job for a given build config.
76
77 Args:
78 build_config: config_lib.BuildConfig.
79
80 Returns:
81 Multiline string to include in the luci scheduler configuration.
82 """
Don Garrett9a0d90c2018-10-30 12:47:14 -070083 job_name = buildJobName(build_config)
Don Garrett73148e52018-08-17 16:54:46 -070084 if 'schedule_branch' in build_config:
85 branch = build_config.schedule_branch
Don Garrett73148e52018-08-17 16:54:46 -070086 else:
Mike Frysinger62a02452021-03-16 03:48:34 -040087 branch = 'main'
Don Garrett73148e52018-08-17 16:54:46 -070088
89 tags = {
90 'cbb_branch': branch,
91 'cbb_config': build_config.name,
92 'cbb_display_label': build_config.display_label,
93 'cbb_workspace_branch': build_config.workspace_branch,
Yoshisato Yanagisawa16285b42018-09-19 14:00:58 +090094 'cbb_goma_client_type': build_config.goma_client_type,
Don Garrett73148e52018-08-17 16:54:46 -070095 }
96
97 # Filter out tags with no value set.
Mike Frysinger0bdbc102019-06-13 15:27:29 -040098 tags = {k: v for k, v in tags.items() if v}
Don Garrett73148e52018-08-17 16:54:46 -070099
100
101 tag_lines = [' tags: "%s:%s"' % (k, tags[k])
102 for k in sorted(tags.keys())]
103 prop_lines = [' properties: "%s:%s"' % (k, tags[k])
104 for k in sorted(tags.keys())]
105
Don Garrettbe3608b2018-06-05 17:10:09 -0700106 # TODO: Move --buildbot arg into recipe, and remove from here.
107 template = """
108job {
Don Garrett8dace272018-07-19 14:07:42 -0700109 id: "%(job_name)s"
Vadim Shtayura6398e002021-01-11 12:02:11 -0800110 realm: "cbb-jobs"
Don Garrettbe3608b2018-06-05 17:10:09 -0700111 acl_sets: "default"
112 schedule: "%(schedule)s"
113 buildbucket: {
114 server: "cr-buildbucket.appspot.com"
115 bucket: "luci.chromeos.general"
116 builder: "%(builder)s"
Don Garrett73148e52018-08-17 16:54:46 -0700117%(tag_lines)s
118%(prop_lines)s
Don Garrettbe3608b2018-06-05 17:10:09 -0700119 properties: "cbb_extra_args:[\\"--buildbot\\"]"
120 }
121}
122"""
Don Garrett8dace272018-07-19 14:07:42 -0700123
Don Garrettbe3608b2018-06-05 17:10:09 -0700124 return template % {
Don Garrett8dace272018-07-19 14:07:42 -0700125 'job_name': job_name,
Don Garrettbe3608b2018-06-05 17:10:09 -0700126 'builder': build_config.luci_builder,
Don Garrettbe3608b2018-06-05 17:10:09 -0700127 'schedule': build_config.schedule,
Don Garrett73148e52018-08-17 16:54:46 -0700128 'tag_lines': '\n'.join(tag_lines),
129 'prop_lines': '\n'.join(prop_lines),
Don Garrettbe3608b2018-06-05 17:10:09 -0700130 }
131
132
David Burgercba0d272020-06-24 16:21:26 -0600133def genSchedulerTrigger(trigger_name, repo, refs, path_regexps, builds):
Don Garrettbe3608b2018-06-05 17:10:09 -0700134 """Generate the luci scheduler job for a given build config.
135
136 Args:
137 trigger_name: Name of the trigger as a string.
138 repo: Gitiles URL git git repository.
139 refs: Iterable of git refs to check. May use regular expressions.
David Burgercba0d272020-06-24 16:21:26 -0600140 path_regexps: Iterable of path regular expressions of files to trigger on
141 or falsy to trigger on everything.
Don Garrettbe3608b2018-06-05 17:10:09 -0700142 builds: Iterable of build config names to trigger.
143
144 Returns:
145 Multiline string to include in the luci scheduler configuration.
146 """
147 template = """
148trigger {
149 id: "%(trigger_name)s"
Vadim Shtayura6398e002021-01-11 12:02:11 -0800150 realm: "cbb-jobs"
Don Garrettbe3608b2018-06-05 17:10:09 -0700151 acl_sets: "default"
152 schedule: "with 5m interval"
153 gitiles: {
154 repo: "%(repo)s"
David Burgercba0d272020-06-24 16:21:26 -0600155%(refs)s%(path_regexps)s
Don Garrettbe3608b2018-06-05 17:10:09 -0700156 }
157%(triggers)s
158}
159"""
David Burgercba0d272020-06-24 16:21:26 -0600160 if path_regexps:
161 path_regexps = '\n' + '\n'.join(' path_regexps: "%s"' %
162 r for r in path_regexps)
163 else:
164 path_regexps = ''
Don Garrettbe3608b2018-06-05 17:10:09 -0700165 return template % {
166 'trigger_name': trigger_name,
167 'repo': repo,
168 'refs': '\n'.join(' refs: "%s"' % r for r in refs),
David Burgercba0d272020-06-24 16:21:26 -0600169 'path_regexps': path_regexps,
Don Garrettbe3608b2018-06-05 17:10:09 -0700170 'triggers': '\n'.join(' triggers: "%s"' % b for b in builds),
171 }
172
173
Don Garrett8dace272018-07-19 14:07:42 -0700174def genLuciSchedulerConfig(site_config, branch_config):
Don Garrettbe3608b2018-06-05 17:10:09 -0700175 """Generate a luciSchedulerConfig as a string.
176
177 Args:
178 site_config: A config_lib.SiteConfig instance.
Don Garrett8dace272018-07-19 14:07:42 -0700179 branch_config: A list of BuildConfig instances to schedule.
Don Garrettbe3608b2018-06-05 17:10:09 -0700180
181 Returns:
182 The complete scheduler configuration contents as a string.
183 """
184 # Trigger collection is used to collect together trigger information, so
185 # we can reuse the same trigger for multiple builds as needed.
186 # It maps gitiles_key to a set of build_names.
187 # A gitiles_key = (gitiles_url, tuple(ref_list))
188 trigger_collection = {}
189
190 jobs = []
Don Garrettbe3608b2018-06-05 17:10:09 -0700191
Don Garrett8dace272018-07-19 14:07:42 -0700192 # Order the configs consistently.
193 configs = [site_config[name] for name in sorted(site_config)] + branch_config
194
195 for config in configs:
Don Garrettbe3608b2018-06-05 17:10:09 -0700196 # Populate jobs.
197 if config.schedule:
198 jobs.append(genSchedulerJob(config))
199
200 # Populate trigger_collection.
201 if config.triggered_gitiles:
David Burgercba0d272020-06-24 16:21:26 -0600202 for trigger in config.triggered_gitiles:
203 try:
204 gitiles_url, ref_list, path_regexps = trigger
205 except ValueError:
206 gitiles_url, ref_list = trigger
207 path_regexps = []
208 gitiles_key = (gitiles_url, tuple(ref_list), tuple(path_regexps))
Don Garrettbe3608b2018-06-05 17:10:09 -0700209 trigger_collection.setdefault(gitiles_key, set())
Don Garrett9a0d90c2018-10-30 12:47:14 -0700210 trigger_collection[gitiles_key].add(buildJobName(config))
Don Garrettbe3608b2018-06-05 17:10:09 -0700211
212 # Populate triggers.
213 triggers = []
214 trigger_counter = 0
215 for gitiles_key in sorted(trigger_collection):
216 builds = sorted(trigger_collection[gitiles_key])
217
218 trigger_name = 'trigger_%s' % trigger_counter
David Burgercba0d272020-06-24 16:21:26 -0600219 gitiles_url, refs, path_regexps = gitiles_key
Don Garrettbe3608b2018-06-05 17:10:09 -0700220 triggers.append(genSchedulerTrigger(
David Burgercba0d272020-06-24 16:21:26 -0600221 trigger_name, gitiles_url, refs, path_regexps, builds))
Don Garrettbe3608b2018-06-05 17:10:09 -0700222 trigger_counter += 1
223
224 return ''.join([_CONFIG_HEADER] + triggers + jobs)
225
226
227def GetParser():
228 """Creates the argparse parser."""
229 parser = commandline.ArgumentParser(description=__doc__)
230
231 parser.add_argument('-o', '--file_out', type='path',
232 help='Write output to specified file.')
233
234 return parser
235
236
237def main(argv):
238 parser = GetParser()
239 options = parser.parse_args(argv)
240 options.Freeze()
241
242 site_config = config_lib.GetConfig()
Don Garrett8dace272018-07-19 14:07:42 -0700243 branch_config = chromeos_config.BranchScheduleConfig()
Don Garrettbe3608b2018-06-05 17:10:09 -0700244
245 with (open(options.file_out, 'w') if options.file_out else sys.stdout) as fh:
Don Garrett8dace272018-07-19 14:07:42 -0700246 fh.write(genLuciSchedulerConfig(site_config, branch_config))