blob: 35a0bcd4e6c94a3769064120f0feb196845e0659 [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
6"""Generate LUCI Scheduler config file.
7
8This generates the LUCI Scheduler configuration file for ChromeOS builds based
9on the chromeos_config contents.
10
11To update the production config:
12 cd $REPO/manifest-internal
13 git checkout infra/config
14 $REPO/chromite/scripts/gen_luci_scheduler > luci-scheduler.cfg
15 git commit -a
16 git cl upload (yes, really) (Say Yes to removing commit-msg hook)
17 repo abandon infra/config
18
19Limitations:
20 This script can only handle builds on the "master" branch.
21"""
22
23from __future__ import print_function
24
25import sys
26
Don Garrett8dace272018-07-19 14:07:42 -070027from chromite.config import chromeos_config
Don Garrettbe3608b2018-06-05 17:10:09 -070028from chromite.lib import commandline
29from chromite.lib import config_lib
30
31
32_CONFIG_HEADER = """# Defines buckets on luci-scheduler.appspot.com.
33#
34# For schema of this file and documentation see ProjectConfig message in
35# https://github.com/luci/luci-go/blob/master/scheduler/appengine/messages/config.proto
36
37# Generated with chromite/scripts/gen_luci_scheduler
38
39acl_sets {
40 name: "default"
41 acls {
42 role: READER
43 granted_to: "group:googlers"
44 }
45 acls {
46 role: OWNER
47 granted_to: "group:project-chromeos-admins"
48 }
49}
50"""
51
52
53def genSchedulerJob(build_config):
54 """Generate the luci scheduler job for a given build config.
55
56 Args:
57 build_config: config_lib.BuildConfig.
58
59 Returns:
60 Multiline string to include in the luci scheduler configuration.
61 """
62 # TODO: Move --buildbot arg into recipe, and remove from here.
63 template = """
64job {
Don Garrett8dace272018-07-19 14:07:42 -070065 id: "%(job_name)s"
Don Garrettbe3608b2018-06-05 17:10:09 -070066 acl_sets: "default"
67 schedule: "%(schedule)s"
68 buildbucket: {
69 server: "cr-buildbucket.appspot.com"
70 bucket: "luci.chromeos.general"
71 builder: "%(builder)s"
72 tags: "cbb_branch:%(branch)s"
73 tags: "cbb_display_label:%(display_label)s"
74 tags: "cbb_config:%(name)s"
75 properties: "cbb_branch:%(branch)s"
76 properties: "cbb_display_label:%(display_label)s"
77 properties: "cbb_config:%(name)s"
78 properties: "cbb_extra_args:[\\"--buildbot\\"]"
79 }
80}
81"""
Don Garrett8dace272018-07-19 14:07:42 -070082 if 'schedule_branch' in build_config:
83 branch = build_config.schedule_branch
84 job_name = '%s-%s' % (branch, build_config.name)
85 else:
86 branch = 'master'
87 job_name = build_config.name
88
Don Garrettbe3608b2018-06-05 17:10:09 -070089 return template % {
Don Garrett8dace272018-07-19 14:07:42 -070090 'job_name': job_name,
Don Garrettbe3608b2018-06-05 17:10:09 -070091 'name': build_config.name,
92 'builder': build_config.luci_builder,
Don Garrett8dace272018-07-19 14:07:42 -070093 'branch': branch,
Don Garrettbe3608b2018-06-05 17:10:09 -070094 'display_label': build_config.display_label,
95 'schedule': build_config.schedule,
96 }
97
98
99def genSchedulerTrigger(trigger_name, repo, refs, builds):
100 """Generate the luci scheduler job for a given build config.
101
102 Args:
103 trigger_name: Name of the trigger as a string.
104 repo: Gitiles URL git git repository.
105 refs: Iterable of git refs to check. May use regular expressions.
106 builds: Iterable of build config names to trigger.
107
108 Returns:
109 Multiline string to include in the luci scheduler configuration.
110 """
111 template = """
112trigger {
113 id: "%(trigger_name)s"
114 acl_sets: "default"
115 schedule: "with 5m interval"
116 gitiles: {
117 repo: "%(repo)s"
118%(refs)s
119 }
120%(triggers)s
121}
122"""
123
124 return template % {
125 'trigger_name': trigger_name,
126 'repo': repo,
127 'refs': '\n'.join(' refs: "%s"' % r for r in refs),
128 'triggers': '\n'.join(' triggers: "%s"' % b for b in builds),
129 }
130
131
Don Garrett8dace272018-07-19 14:07:42 -0700132def genLuciSchedulerConfig(site_config, branch_config):
Don Garrettbe3608b2018-06-05 17:10:09 -0700133 """Generate a luciSchedulerConfig as a string.
134
135 Args:
136 site_config: A config_lib.SiteConfig instance.
Don Garrett8dace272018-07-19 14:07:42 -0700137 branch_config: A list of BuildConfig instances to schedule.
Don Garrettbe3608b2018-06-05 17:10:09 -0700138
139 Returns:
140 The complete scheduler configuration contents as a string.
141 """
142 # Trigger collection is used to collect together trigger information, so
143 # we can reuse the same trigger for multiple builds as needed.
144 # It maps gitiles_key to a set of build_names.
145 # A gitiles_key = (gitiles_url, tuple(ref_list))
146 trigger_collection = {}
147
148 jobs = []
Don Garrettbe3608b2018-06-05 17:10:09 -0700149
Don Garrett8dace272018-07-19 14:07:42 -0700150 # Order the configs consistently.
151 configs = [site_config[name] for name in sorted(site_config)] + branch_config
152
153 for config in configs:
Don Garrettbe3608b2018-06-05 17:10:09 -0700154 # Populate jobs.
155 if config.schedule:
156 jobs.append(genSchedulerJob(config))
157
158 # Populate trigger_collection.
159 if config.triggered_gitiles:
160 for gitiles_url, ref_list in config.triggered_gitiles:
161 gitiles_key = (gitiles_url, tuple(ref_list))
162 trigger_collection.setdefault(gitiles_key, set())
163 trigger_collection[gitiles_key].add(config.name)
164
165 # Populate triggers.
166 triggers = []
167 trigger_counter = 0
168 for gitiles_key in sorted(trigger_collection):
169 builds = sorted(trigger_collection[gitiles_key])
170
171 trigger_name = 'trigger_%s' % trigger_counter
172 gitiles_url, refs = gitiles_key
173 triggers.append(genSchedulerTrigger(
174 trigger_name, gitiles_url, refs, builds))
175 trigger_counter += 1
176
177 return ''.join([_CONFIG_HEADER] + triggers + jobs)
178
179
180def GetParser():
181 """Creates the argparse parser."""
182 parser = commandline.ArgumentParser(description=__doc__)
183
184 parser.add_argument('-o', '--file_out', type='path',
185 help='Write output to specified file.')
186
187 return parser
188
189
190def main(argv):
191 parser = GetParser()
192 options = parser.parse_args(argv)
193 options.Freeze()
194
195 site_config = config_lib.GetConfig()
Don Garrett8dace272018-07-19 14:07:42 -0700196 branch_config = chromeos_config.BranchScheduleConfig()
Don Garrettbe3608b2018-06-05 17:10:09 -0700197
198 with (open(options.file_out, 'w') if options.file_out else sys.stdout) as fh:
Don Garrett8dace272018-07-19 14:07:42 -0700199 fh.write(genLuciSchedulerConfig(site_config, branch_config))