blob: 23adf9115bcc2892dd6f364df370e0b836733713 [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2018 The ChromiumOS Authors
Don Garrettbe3608b2018-06-05 17:10:09 -07002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
Don Garrettff45f4b2018-10-04 09:08:01 -07005# pylint: disable=line-too-long
Mike Frysingera2527f82023-02-03 04:32:15 -05006
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:
Mike Nicholsb575c612021-04-09 10:04:43 -060013 https://data.corp.google.com/sites/chromeos_ci_cros_ci_builds/utility/?f=board_name:in: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.
Don Garrettbe3608b2018-06-05 17:10:09 -070018"""
Mike Frysinger93afe3e2023-09-05 14:18:52 -040019
Don Garrettff45f4b2018-10-04 09:08:01 -070020# pylint: enable=line-too-long
Don Garrettbe3608b2018-06-05 17:10:09 -070021
Don Garrettbe3608b2018-06-05 17:10:09 -070022import sys
23
24from chromite.lib import commandline
25from chromite.lib import config_lib
26
27
28_CONFIG_HEADER = """# Defines buckets on luci-scheduler.appspot.com.
29#
30# For schema of this file and documentation see ProjectConfig message in
Mike Frysinger92dc6492021-02-17 16:01:09 -050031# https://github.com/luci/luci-go/blob/HEAD/scheduler/appengine/messages/config.proto
Don Garrettbe3608b2018-06-05 17:10:09 -070032
33# Generated with chromite/scripts/gen_luci_scheduler
34
Don Garrettff45f4b2018-10-04 09:08:01 -070035# Autodeployed with:
Mike Nicholsb575c612021-04-09 10:04:43 -060036# https://data.corp.google.com/sites/chromeos_ci_cros_ci_builds/utility/?f=board_name:in:luci-scheduler-updater
Don Garrettff45f4b2018-10-04 09:08:01 -070037
Don Garrettbe3608b2018-06-05 17:10:09 -070038acl_sets {
39 name: "default"
40 acls {
41 role: READER
42 granted_to: "group:googlers"
43 }
44 acls {
45 role: OWNER
46 granted_to: "group:project-chromeos-admins"
47 }
Jason D. Clintona9e374a2018-10-18 18:41:00 -060048 acls {
49 role: TRIGGERER
50 granted_to: "group:mdb/chromeos-build-access"
LaMont Jones48ddfd92020-09-16 13:46:41 -060051 }
52 acls {
53 role: TRIGGERER
LaMont Jonesd1bb0002020-09-16 09:35:10 -060054 granted_to: "group:project-chromeos-buildbucket-schedulers"
Jason D. Clintona9e374a2018-10-18 18:41:00 -060055 }
Don Garrettbe3608b2018-06-05 17:10:09 -070056}
57"""
58
Alex Klein1699fab2022-09-08 08:46:06 -060059
Don Garrett9a0d90c2018-10-30 12:47:14 -070060def buildJobName(build_config):
Alex Klein1699fab2022-09-08 08:46:06 -060061 if "schedule_branch" in build_config:
62 return "%s-%s" % (build_config.schedule_branch, build_config.name)
63 else:
64 return build_config.name
Don Garrett9a0d90c2018-10-30 12:47:14 -070065
Don Garrettbe3608b2018-06-05 17:10:09 -070066
67def genSchedulerJob(build_config):
Alex Klein1699fab2022-09-08 08:46:06 -060068 """Generate the luci scheduler job for a given build config.
Don Garrettbe3608b2018-06-05 17:10:09 -070069
Alex Klein1699fab2022-09-08 08:46:06 -060070 Args:
Trent Apted66736d82023-05-25 10:38:28 +100071 build_config: config_lib.BuildConfig.
Don Garrettbe3608b2018-06-05 17:10:09 -070072
Alex Klein1699fab2022-09-08 08:46:06 -060073 Returns:
Trent Apted66736d82023-05-25 10:38:28 +100074 Multiline string to include in the luci scheduler configuration.
Alex Klein1699fab2022-09-08 08:46:06 -060075 """
76 job_name = buildJobName(build_config)
77 if "schedule_branch" in build_config:
78 branch = build_config.schedule_branch
79 else:
80 branch = "main"
Don Garrett73148e52018-08-17 16:54:46 -070081
Alex Klein1699fab2022-09-08 08:46:06 -060082 tags = {
83 "cbb_branch": branch,
84 "cbb_config": build_config.name,
85 "cbb_display_label": build_config.display_label,
86 "cbb_workspace_branch": build_config.workspace_branch,
Mike Frysinger6976b832023-07-10 12:14:50 -040087 "cbb_goma_client_type": None,
Alex Klein1699fab2022-09-08 08:46:06 -060088 }
Don Garrett73148e52018-08-17 16:54:46 -070089
Alex Klein1699fab2022-09-08 08:46:06 -060090 # Filter out tags with no value set.
91 tags = {k: v for k, v in tags.items() if v}
Don Garrett73148e52018-08-17 16:54:46 -070092
Alex Klein1699fab2022-09-08 08:46:06 -060093 tag_lines = [
94 ' tags: "%s:%s"' % (k, tags[k]) for k in sorted(tags.keys())
95 ]
96 prop_lines = [
97 ' properties: "%s:%s"' % (k, tags[k]) for k in sorted(tags.keys())
98 ]
Don Garrett73148e52018-08-17 16:54:46 -070099
Alex Klein1699fab2022-09-08 08:46:06 -0600100 # TODO: Move --buildbot arg into recipe, and remove from here.
101 template = """
Don Garrettbe3608b2018-06-05 17:10:09 -0700102job {
Don Garrett8dace272018-07-19 14:07:42 -0700103 id: "%(job_name)s"
Vadim Shtayura6398e002021-01-11 12:02:11 -0800104 realm: "cbb-jobs"
Don Garrettbe3608b2018-06-05 17:10:09 -0700105 acl_sets: "default"
106 schedule: "%(schedule)s"
107 buildbucket: {
108 server: "cr-buildbucket.appspot.com"
Vadim Shtayura959cb0f2022-02-03 12:45:58 -0800109 bucket: "general"
Don Garrettbe3608b2018-06-05 17:10:09 -0700110 builder: "%(builder)s"
Don Garrett73148e52018-08-17 16:54:46 -0700111%(tag_lines)s
112%(prop_lines)s
Don Garrettbe3608b2018-06-05 17:10:09 -0700113 properties: "cbb_extra_args:[\\"--buildbot\\"]"
114 }
115}
116"""
Don Garrett8dace272018-07-19 14:07:42 -0700117
Alex Klein1699fab2022-09-08 08:46:06 -0600118 return template % {
119 "job_name": job_name,
120 "builder": build_config.luci_builder,
121 "schedule": build_config.schedule,
122 "tag_lines": "\n".join(tag_lines),
123 "prop_lines": "\n".join(prop_lines),
124 }
Don Garrettbe3608b2018-06-05 17:10:09 -0700125
126
David Burgercba0d272020-06-24 16:21:26 -0600127def genSchedulerTrigger(trigger_name, repo, refs, path_regexps, builds):
Alex Klein1699fab2022-09-08 08:46:06 -0600128 """Generate the luci scheduler job for a given build config.
Don Garrettbe3608b2018-06-05 17:10:09 -0700129
Alex Klein1699fab2022-09-08 08:46:06 -0600130 Args:
Trent Apted66736d82023-05-25 10:38:28 +1000131 trigger_name: Name of the trigger as a string.
132 repo: Gitiles URL git git repository.
133 refs: Iterable of git refs to check. May use regular expressions.
134 path_regexps: Iterable of path regular expressions of files to trigger
135 on or falsey to trigger on everything.
136 builds: Iterable of build config names to trigger.
Don Garrettbe3608b2018-06-05 17:10:09 -0700137
Alex Klein1699fab2022-09-08 08:46:06 -0600138 Returns:
Trent Apted66736d82023-05-25 10:38:28 +1000139 Multiline string to include in the luci scheduler configuration.
Alex Klein1699fab2022-09-08 08:46:06 -0600140 """
141 template = """
Don Garrettbe3608b2018-06-05 17:10:09 -0700142trigger {
143 id: "%(trigger_name)s"
Vadim Shtayura6398e002021-01-11 12:02:11 -0800144 realm: "cbb-jobs"
Don Garrettbe3608b2018-06-05 17:10:09 -0700145 acl_sets: "default"
146 schedule: "with 5m interval"
147 gitiles: {
148 repo: "%(repo)s"
David Burgercba0d272020-06-24 16:21:26 -0600149%(refs)s%(path_regexps)s
Don Garrettbe3608b2018-06-05 17:10:09 -0700150 }
151%(triggers)s
152}
153"""
Alex Klein1699fab2022-09-08 08:46:06 -0600154 if path_regexps:
155 path_regexps = "\n" + "\n".join(
156 ' path_regexps: "%s"' % r for r in path_regexps
157 )
158 else:
159 path_regexps = ""
160 return template % {
161 "trigger_name": trigger_name,
162 "repo": repo,
163 "refs": "\n".join(' refs: "%s"' % r for r in refs),
164 "path_regexps": path_regexps,
165 "triggers": "\n".join(' triggers: "%s"' % b for b in builds),
166 }
Don Garrettbe3608b2018-06-05 17:10:09 -0700167
168
George Burgess IV3b98be72023-09-12 14:20:43 -0600169def genLuciSchedulerConfig(site_config):
Alex Klein1699fab2022-09-08 08:46:06 -0600170 """Generate a luciSchedulerConfig as a string.
Don Garrettbe3608b2018-06-05 17:10:09 -0700171
Alex Klein1699fab2022-09-08 08:46:06 -0600172 Args:
Trent Apted66736d82023-05-25 10:38:28 +1000173 site_config: A config_lib.SiteConfig instance.
Don Garrettbe3608b2018-06-05 17:10:09 -0700174
Alex Klein1699fab2022-09-08 08:46:06 -0600175 Returns:
Trent Apted66736d82023-05-25 10:38:28 +1000176 The complete scheduler configuration contents as a string.
Alex Klein1699fab2022-09-08 08:46:06 -0600177 """
178 # Trigger collection is used to collect together trigger information, so
179 # we can reuse the same trigger for multiple builds as needed.
180 # It maps gitiles_key to a set of build_names.
181 # A gitiles_key = (gitiles_url, tuple(ref_list))
182 trigger_collection = {}
Don Garrettbe3608b2018-06-05 17:10:09 -0700183
Alex Klein1699fab2022-09-08 08:46:06 -0600184 jobs = []
Don Garrettbe3608b2018-06-05 17:10:09 -0700185
Alex Klein1699fab2022-09-08 08:46:06 -0600186 # Order the configs consistently.
George Burgess IV3b98be72023-09-12 14:20:43 -0600187 configs = [site_config[name] for name in sorted(site_config)]
Don Garrett8dace272018-07-19 14:07:42 -0700188
Alex Klein1699fab2022-09-08 08:46:06 -0600189 for config in configs:
190 # Populate jobs.
191 if config.schedule:
192 jobs.append(genSchedulerJob(config))
Don Garrettbe3608b2018-06-05 17:10:09 -0700193
Alex Klein1699fab2022-09-08 08:46:06 -0600194 # Populate trigger_collection.
195 if config.triggered_gitiles:
196 for trigger in config.triggered_gitiles:
197 try:
198 gitiles_url, ref_list, path_regexps = trigger
199 except ValueError:
200 gitiles_url, ref_list = trigger
201 path_regexps = []
202 gitiles_key = (
203 gitiles_url,
204 tuple(ref_list),
205 tuple(path_regexps),
206 )
207 trigger_collection.setdefault(gitiles_key, set())
208 trigger_collection[gitiles_key].add(buildJobName(config))
Don Garrettbe3608b2018-06-05 17:10:09 -0700209
Alex Klein1699fab2022-09-08 08:46:06 -0600210 # Populate triggers.
211 triggers = []
212 trigger_counter = 0
213 for gitiles_key in sorted(trigger_collection):
214 builds = sorted(trigger_collection[gitiles_key])
Don Garrettbe3608b2018-06-05 17:10:09 -0700215
Alex Klein1699fab2022-09-08 08:46:06 -0600216 trigger_name = "trigger_%s" % trigger_counter
217 gitiles_url, refs, path_regexps = gitiles_key
218 triggers.append(
219 genSchedulerTrigger(
220 trigger_name, gitiles_url, refs, path_regexps, builds
221 )
222 )
223 trigger_counter += 1
Don Garrettbe3608b2018-06-05 17:10:09 -0700224
Alex Klein1699fab2022-09-08 08:46:06 -0600225 return "".join([_CONFIG_HEADER] + triggers + jobs)
Don Garrettbe3608b2018-06-05 17:10:09 -0700226
227
228def GetParser():
Alex Klein1699fab2022-09-08 08:46:06 -0600229 """Creates the argparse parser."""
230 parser = commandline.ArgumentParser(description=__doc__)
Don Garrettbe3608b2018-06-05 17:10:09 -0700231
Alex Klein1699fab2022-09-08 08:46:06 -0600232 parser.add_argument(
233 "-o", "--file_out", type="path", help="Write output to specified file."
234 )
Don Garrettbe3608b2018-06-05 17:10:09 -0700235
Alex Klein1699fab2022-09-08 08:46:06 -0600236 return parser
Don Garrettbe3608b2018-06-05 17:10:09 -0700237
238
239def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600240 parser = GetParser()
241 options = parser.parse_args(argv)
242 options.Freeze()
Don Garrettbe3608b2018-06-05 17:10:09 -0700243
Alex Klein1699fab2022-09-08 08:46:06 -0600244 site_config = config_lib.GetConfig()
Alex Klein1699fab2022-09-08 08:46:06 -0600245 with (
Mike Frysinger31fdddd2023-02-24 15:50:55 -0500246 open(options.file_out, "w", encoding="utf-8")
247 if options.file_out
248 else sys.stdout
Alex Klein1699fab2022-09-08 08:46:06 -0600249 ) as fh:
George Burgess IV3b98be72023-09-12 14:20:43 -0600250 fh.write(genLuciSchedulerConfig(site_config))