blob: d91962d2cbbcc7ccf4d633b582ca56a737e14430 [file] [log] [blame]
Don Garrettbe3608b2018-06-05 17:10:09 -07001# Copyright 2018 The Chromium OS Authors. All rights reserved.
2# 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
Don Garrettbe3608b2018-06-05 17:10:09 -07006"""Generate LUCI Scheduler config file.
7
8This generates the LUCI Scheduler configuration file for ChromeOS builds based
9on the chromeos_config contents.
10
Don Garrettff45f4b2018-10-04 09:08:01 -070011Changes to chromite/config/luci-scheduler.cfg will be autodeployed:
Mike Nicholsb575c612021-04-09 10:04:43 -060012 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 -070013
Don Garrettc8323dc2018-08-22 15:58:26 -070014Notes:
15 Normal builds are scheduled based on the builder values for
16 'schedule' and 'triggered_gitiles' in config/chromeos_config.py.
17
18 Branched builds are scheduled based on the function
19 chromeos_config.BranchScheduleConfig()
Don Garrettbe3608b2018-06-05 17:10:09 -070020"""
Don Garrettff45f4b2018-10-04 09:08:01 -070021# pylint: enable=line-too-long
Don Garrettbe3608b2018-06-05 17:10:09 -070022
Don Garrettbe3608b2018-06-05 17:10:09 -070023import sys
24
Don Garrett8dace272018-07-19 14:07:42 -070025from chromite.config import chromeos_config
Don Garrettbe3608b2018-06-05 17:10:09 -070026from chromite.lib import commandline
27from chromite.lib import config_lib
28
29
30_CONFIG_HEADER = """# Defines buckets on luci-scheduler.appspot.com.
31#
32# For schema of this file and documentation see ProjectConfig message in
Mike Frysinger92dc6492021-02-17 16:01:09 -050033# https://github.com/luci/luci-go/blob/HEAD/scheduler/appengine/messages/config.proto
Don Garrettbe3608b2018-06-05 17:10:09 -070034
35# Generated with chromite/scripts/gen_luci_scheduler
36
Don Garrettff45f4b2018-10-04 09:08:01 -070037# Autodeployed with:
Mike Nicholsb575c612021-04-09 10:04:43 -060038# 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 -070039
Don Garrettbe3608b2018-06-05 17:10:09 -070040acl_sets {
41 name: "default"
42 acls {
43 role: READER
44 granted_to: "group:googlers"
45 }
46 acls {
47 role: OWNER
48 granted_to: "group:project-chromeos-admins"
49 }
Jason D. Clintona9e374a2018-10-18 18:41:00 -060050 acls {
51 role: TRIGGERER
52 granted_to: "group:mdb/chromeos-build-access"
LaMont Jones48ddfd92020-09-16 13:46:41 -060053 }
54 acls {
55 role: TRIGGERER
LaMont Jonesd1bb0002020-09-16 09:35:10 -060056 granted_to: "group:project-chromeos-buildbucket-schedulers"
Jason D. Clintona9e374a2018-10-18 18:41:00 -060057 }
Don Garrettbe3608b2018-06-05 17:10:09 -070058}
59"""
60
Don Garrett9a0d90c2018-10-30 12:47:14 -070061def buildJobName(build_config):
62 if 'schedule_branch' in build_config:
63 return '%s-%s' % (build_config.schedule_branch, build_config.name)
64 else:
65 return build_config.name
66
Don Garrettbe3608b2018-06-05 17:10:09 -070067
68def genSchedulerJob(build_config):
69 """Generate the luci scheduler job for a given build config.
70
71 Args:
72 build_config: config_lib.BuildConfig.
73
74 Returns:
75 Multiline string to include in the luci scheduler configuration.
76 """
Don Garrett9a0d90c2018-10-30 12:47:14 -070077 job_name = buildJobName(build_config)
Don Garrett73148e52018-08-17 16:54:46 -070078 if 'schedule_branch' in build_config:
79 branch = build_config.schedule_branch
Don Garrett73148e52018-08-17 16:54:46 -070080 else:
Mike Frysinger62a02452021-03-16 03:48:34 -040081 branch = 'main'
Don Garrett73148e52018-08-17 16:54:46 -070082
83 tags = {
84 'cbb_branch': branch,
85 'cbb_config': build_config.name,
86 'cbb_display_label': build_config.display_label,
87 'cbb_workspace_branch': build_config.workspace_branch,
Yoshisato Yanagisawa16285b42018-09-19 14:00:58 +090088 'cbb_goma_client_type': build_config.goma_client_type,
Don Garrett73148e52018-08-17 16:54:46 -070089 }
90
91 # Filter out tags with no value set.
Mike Frysinger0bdbc102019-06-13 15:27:29 -040092 tags = {k: v for k, v in tags.items() if v}
Don Garrett73148e52018-08-17 16:54:46 -070093
94
95 tag_lines = [' tags: "%s:%s"' % (k, tags[k])
96 for k in sorted(tags.keys())]
97 prop_lines = [' properties: "%s:%s"' % (k, tags[k])
98 for k in sorted(tags.keys())]
99
Don Garrettbe3608b2018-06-05 17:10:09 -0700100 # TODO: Move --buildbot arg into recipe, and remove from here.
101 template = """
102job {
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
Don Garrettbe3608b2018-06-05 17:10:09 -0700118 return template % {
Don Garrett8dace272018-07-19 14:07:42 -0700119 'job_name': job_name,
Don Garrettbe3608b2018-06-05 17:10:09 -0700120 'builder': build_config.luci_builder,
Don Garrettbe3608b2018-06-05 17:10:09 -0700121 'schedule': build_config.schedule,
Don Garrett73148e52018-08-17 16:54:46 -0700122 'tag_lines': '\n'.join(tag_lines),
123 'prop_lines': '\n'.join(prop_lines),
Don Garrettbe3608b2018-06-05 17:10:09 -0700124 }
125
126
David Burgercba0d272020-06-24 16:21:26 -0600127def genSchedulerTrigger(trigger_name, repo, refs, path_regexps, builds):
Don Garrettbe3608b2018-06-05 17:10:09 -0700128 """Generate the luci scheduler job for a given build config.
129
130 Args:
131 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.
David Burgercba0d272020-06-24 16:21:26 -0600134 path_regexps: Iterable of path regular expressions of files to trigger on
135 or falsy to trigger on everything.
Don Garrettbe3608b2018-06-05 17:10:09 -0700136 builds: Iterable of build config names to trigger.
137
138 Returns:
139 Multiline string to include in the luci scheduler configuration.
140 """
141 template = """
142trigger {
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"""
David Burgercba0d272020-06-24 16:21:26 -0600154 if path_regexps:
155 path_regexps = '\n' + '\n'.join(' path_regexps: "%s"' %
156 r for r in path_regexps)
157 else:
158 path_regexps = ''
Don Garrettbe3608b2018-06-05 17:10:09 -0700159 return template % {
160 'trigger_name': trigger_name,
161 'repo': repo,
162 'refs': '\n'.join(' refs: "%s"' % r for r in refs),
David Burgercba0d272020-06-24 16:21:26 -0600163 'path_regexps': path_regexps,
Don Garrettbe3608b2018-06-05 17:10:09 -0700164 'triggers': '\n'.join(' triggers: "%s"' % b for b in builds),
165 }
166
167
Don Garrett8dace272018-07-19 14:07:42 -0700168def genLuciSchedulerConfig(site_config, branch_config):
Don Garrettbe3608b2018-06-05 17:10:09 -0700169 """Generate a luciSchedulerConfig as a string.
170
171 Args:
172 site_config: A config_lib.SiteConfig instance.
Don Garrett8dace272018-07-19 14:07:42 -0700173 branch_config: A list of BuildConfig instances to schedule.
Don Garrettbe3608b2018-06-05 17:10:09 -0700174
175 Returns:
176 The complete scheduler configuration contents as a string.
177 """
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 = {}
183
184 jobs = []
Don Garrettbe3608b2018-06-05 17:10:09 -0700185
Don Garrett8dace272018-07-19 14:07:42 -0700186 # Order the configs consistently.
187 configs = [site_config[name] for name in sorted(site_config)] + branch_config
188
189 for config in configs:
Don Garrettbe3608b2018-06-05 17:10:09 -0700190 # Populate jobs.
191 if config.schedule:
192 jobs.append(genSchedulerJob(config))
193
194 # Populate trigger_collection.
195 if config.triggered_gitiles:
David Burgercba0d272020-06-24 16:21:26 -0600196 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 = (gitiles_url, tuple(ref_list), tuple(path_regexps))
Don Garrettbe3608b2018-06-05 17:10:09 -0700203 trigger_collection.setdefault(gitiles_key, set())
Don Garrett9a0d90c2018-10-30 12:47:14 -0700204 trigger_collection[gitiles_key].add(buildJobName(config))
Don Garrettbe3608b2018-06-05 17:10:09 -0700205
206 # Populate triggers.
207 triggers = []
208 trigger_counter = 0
209 for gitiles_key in sorted(trigger_collection):
210 builds = sorted(trigger_collection[gitiles_key])
211
212 trigger_name = 'trigger_%s' % trigger_counter
David Burgercba0d272020-06-24 16:21:26 -0600213 gitiles_url, refs, path_regexps = gitiles_key
Don Garrettbe3608b2018-06-05 17:10:09 -0700214 triggers.append(genSchedulerTrigger(
David Burgercba0d272020-06-24 16:21:26 -0600215 trigger_name, gitiles_url, refs, path_regexps, builds))
Don Garrettbe3608b2018-06-05 17:10:09 -0700216 trigger_counter += 1
217
218 return ''.join([_CONFIG_HEADER] + triggers + jobs)
219
220
221def GetParser():
222 """Creates the argparse parser."""
223 parser = commandline.ArgumentParser(description=__doc__)
224
225 parser.add_argument('-o', '--file_out', type='path',
226 help='Write output to specified file.')
227
228 return parser
229
230
231def main(argv):
232 parser = GetParser()
233 options = parser.parse_args(argv)
234 options.Freeze()
235
236 site_config = config_lib.GetConfig()
Don Garrett8dace272018-07-19 14:07:42 -0700237 branch_config = chromeos_config.BranchScheduleConfig()
Don Garrettbe3608b2018-06-05 17:10:09 -0700238
239 with (open(options.file_out, 'w') if options.file_out else sys.stdout) as fh:
Don Garrett8dace272018-07-19 14:07:42 -0700240 fh.write(genLuciSchedulerConfig(site_config, branch_config))