blob: e6031c17a2e88e5b4aa665b3f2db36684ab75938 [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
33_CONFIG_HEADER = """# Defines buckets on luci-scheduler.appspot.com.
34#
35# For schema of this file and documentation see ProjectConfig message in
36# https://github.com/luci/luci-go/blob/master/scheduler/appengine/messages/config.proto
37
38# Generated with chromite/scripts/gen_luci_scheduler
39
Don Garrettff45f4b2018-10-04 09:08:01 -070040# Autodeployed with:
41# http://cros-goldeneye/chromeos/legoland/builderHistory?buildConfig=luci-scheduler-updater
42
Don Garrettbe3608b2018-06-05 17:10:09 -070043acl_sets {
44 name: "default"
45 acls {
46 role: READER
47 granted_to: "group:googlers"
48 }
49 acls {
50 role: OWNER
51 granted_to: "group:project-chromeos-admins"
52 }
Jason D. Clintona9e374a2018-10-18 18:41:00 -060053 acls {
54 role: TRIGGERER
55 granted_to: "group:mdb/chromeos-build-access"
56 }
Don Garrettbe3608b2018-06-05 17:10:09 -070057}
58"""
59
Don Garrett9a0d90c2018-10-30 12:47:14 -070060def buildJobName(build_config):
61 if 'schedule_branch' in build_config:
62 return '%s-%s' % (build_config.schedule_branch, build_config.name)
63 else:
64 return build_config.name
65
Don Garrettbe3608b2018-06-05 17:10:09 -070066
67def genSchedulerJob(build_config):
68 """Generate the luci scheduler job for a given build config.
69
70 Args:
71 build_config: config_lib.BuildConfig.
72
73 Returns:
74 Multiline string to include in the luci scheduler configuration.
75 """
Don Garrett9a0d90c2018-10-30 12:47:14 -070076 job_name = buildJobName(build_config)
Don Garrett73148e52018-08-17 16:54:46 -070077 if 'schedule_branch' in build_config:
78 branch = build_config.schedule_branch
Don Garrett73148e52018-08-17 16:54:46 -070079 else:
80 branch = 'master'
Don Garrett73148e52018-08-17 16:54:46 -070081
82 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,
Yoshisato Yanagisawa16285b42018-09-19 14:00:58 +090087 'cbb_goma_client_type': build_config.goma_client_type,
Don Garrett73148e52018-08-17 16:54:46 -070088 }
89
90 # Filter out tags with no value set.
91 tags = {k: v for k, v in tags.iteritems() if v}
92
93
94 tag_lines = [' tags: "%s:%s"' % (k, tags[k])
95 for k in sorted(tags.keys())]
96 prop_lines = [' properties: "%s:%s"' % (k, tags[k])
97 for k in sorted(tags.keys())]
98
Don Garrettbe3608b2018-06-05 17:10:09 -070099 # TODO: Move --buildbot arg into recipe, and remove from here.
100 template = """
101job {
Don Garrett8dace272018-07-19 14:07:42 -0700102 id: "%(job_name)s"
Don Garrettbe3608b2018-06-05 17:10:09 -0700103 acl_sets: "default"
104 schedule: "%(schedule)s"
105 buildbucket: {
106 server: "cr-buildbucket.appspot.com"
107 bucket: "luci.chromeos.general"
108 builder: "%(builder)s"
Don Garrett73148e52018-08-17 16:54:46 -0700109%(tag_lines)s
110%(prop_lines)s
Don Garrettbe3608b2018-06-05 17:10:09 -0700111 properties: "cbb_extra_args:[\\"--buildbot\\"]"
112 }
113}
114"""
Don Garrett8dace272018-07-19 14:07:42 -0700115
Don Garrettbe3608b2018-06-05 17:10:09 -0700116 return template % {
Don Garrett8dace272018-07-19 14:07:42 -0700117 'job_name': job_name,
Don Garrettbe3608b2018-06-05 17:10:09 -0700118 'builder': build_config.luci_builder,
Don Garrettbe3608b2018-06-05 17:10:09 -0700119 'schedule': build_config.schedule,
Don Garrett73148e52018-08-17 16:54:46 -0700120 'tag_lines': '\n'.join(tag_lines),
121 'prop_lines': '\n'.join(prop_lines),
Don Garrettbe3608b2018-06-05 17:10:09 -0700122 }
123
124
125def genSchedulerTrigger(trigger_name, repo, refs, builds):
126 """Generate the luci scheduler job for a given build config.
127
128 Args:
129 trigger_name: Name of the trigger as a string.
130 repo: Gitiles URL git git repository.
131 refs: Iterable of git refs to check. May use regular expressions.
132 builds: Iterable of build config names to trigger.
133
134 Returns:
135 Multiline string to include in the luci scheduler configuration.
136 """
137 template = """
138trigger {
139 id: "%(trigger_name)s"
140 acl_sets: "default"
141 schedule: "with 5m interval"
142 gitiles: {
143 repo: "%(repo)s"
144%(refs)s
145 }
146%(triggers)s
147}
148"""
149
150 return template % {
151 'trigger_name': trigger_name,
152 'repo': repo,
153 'refs': '\n'.join(' refs: "%s"' % r for r in refs),
154 'triggers': '\n'.join(' triggers: "%s"' % b for b in builds),
155 }
156
157
Don Garrett8dace272018-07-19 14:07:42 -0700158def genLuciSchedulerConfig(site_config, branch_config):
Don Garrettbe3608b2018-06-05 17:10:09 -0700159 """Generate a luciSchedulerConfig as a string.
160
161 Args:
162 site_config: A config_lib.SiteConfig instance.
Don Garrett8dace272018-07-19 14:07:42 -0700163 branch_config: A list of BuildConfig instances to schedule.
Don Garrettbe3608b2018-06-05 17:10:09 -0700164
165 Returns:
166 The complete scheduler configuration contents as a string.
167 """
168 # Trigger collection is used to collect together trigger information, so
169 # we can reuse the same trigger for multiple builds as needed.
170 # It maps gitiles_key to a set of build_names.
171 # A gitiles_key = (gitiles_url, tuple(ref_list))
172 trigger_collection = {}
173
174 jobs = []
Don Garrettbe3608b2018-06-05 17:10:09 -0700175
Don Garrett8dace272018-07-19 14:07:42 -0700176 # Order the configs consistently.
177 configs = [site_config[name] for name in sorted(site_config)] + branch_config
178
179 for config in configs:
Don Garrettbe3608b2018-06-05 17:10:09 -0700180 # Populate jobs.
181 if config.schedule:
182 jobs.append(genSchedulerJob(config))
183
184 # Populate trigger_collection.
185 if config.triggered_gitiles:
186 for gitiles_url, ref_list in config.triggered_gitiles:
187 gitiles_key = (gitiles_url, tuple(ref_list))
188 trigger_collection.setdefault(gitiles_key, set())
Don Garrett9a0d90c2018-10-30 12:47:14 -0700189 trigger_collection[gitiles_key].add(buildJobName(config))
Don Garrettbe3608b2018-06-05 17:10:09 -0700190
191 # Populate triggers.
192 triggers = []
193 trigger_counter = 0
194 for gitiles_key in sorted(trigger_collection):
195 builds = sorted(trigger_collection[gitiles_key])
196
197 trigger_name = 'trigger_%s' % trigger_counter
198 gitiles_url, refs = gitiles_key
199 triggers.append(genSchedulerTrigger(
200 trigger_name, gitiles_url, refs, builds))
201 trigger_counter += 1
202
203 return ''.join([_CONFIG_HEADER] + triggers + jobs)
204
205
206def GetParser():
207 """Creates the argparse parser."""
208 parser = commandline.ArgumentParser(description=__doc__)
209
210 parser.add_argument('-o', '--file_out', type='path',
211 help='Write output to specified file.')
212
213 return parser
214
215
216def main(argv):
217 parser = GetParser()
218 options = parser.parse_args(argv)
219 options.Freeze()
220
221 site_config = config_lib.GetConfig()
Don Garrett8dace272018-07-19 14:07:42 -0700222 branch_config = chromeos_config.BranchScheduleConfig()
Don Garrettbe3608b2018-06-05 17:10:09 -0700223
224 with (open(options.file_out, 'w') if options.file_out else sys.stdout) as fh:
Don Garrett8dace272018-07-19 14:07:42 -0700225 fh.write(genLuciSchedulerConfig(site_config, branch_config))