Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: masters/master.chromiumos/master.cfg

Issue 1068263003: CrOS: Update public waterfall to auto-configure. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Added experimental/documentation annotations to web UI. Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # -*- python -*- 1 # -*- python -*-
2 # ex: set syntax=python: 2 # ex: set syntax=python:
3 3
4 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 4 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
5 # Use of this source code is governed by a BSD-style license that can be 5 # Use of this source code is governed by a BSD-style license that can be
6 # found in the LICENSE file. 6 # found in the LICENSE file.
7 7
8 # This is the buildmaster config file for the 'chromeos' bot. It must 8 # This is the buildmaster config file for the 'chromeos' bot. It must
9 # be installed as 'master.cfg' in your buildmaster's base directory 9 # be installed as 'master.cfg' in your buildmaster's base directory
10 # (although the filename can be changed with the --basedir option to 10 # (although the filename can be changed with the --basedir option to
11 # 'mktap buildbot master'). 11 # 'mktap buildbot master').
12 12
13 # It has one job: define a dictionary named BuildmasterConfig. This 13 # It has one job: define a dictionary named BuildmasterConfig. This
14 # dictionary has a variety of keys to control different aspects of the 14 # dictionary has a variety of keys to control different aspects of the
15 # buildmaster. They are documented in docs/config.xhtml . 15 # buildmaster. They are documented in docs/config.xhtml .
16 16
17 import json
18 import os
17 import re 19 import re
18 20
19 from buildbot.changes.filter import ChangeFilter 21 from buildbot.changes.filter import ChangeFilter
20 from buildbot.changes.pb import PBChangeSource 22 from buildbot.changes.pb import PBChangeSource
21 from buildbot.scheduler import Periodic 23 from buildbot.scheduler import Periodic
22 24
23 # These modules come from scripts/master, which must be in the PYTHONPATH. 25 # These modules come from scripts/master, which must be in the PYTHONPATH.
24 from master import master_utils 26 from master import master_utils
25 from master import slaves_list 27 from master import slaves_list
26 from master.chromeos_manifest_scheduler import \ 28 from master.chromeos_manifest_scheduler import \
27 ChromeOSManifestSingleBranchScheduler, ChromeOSManifestAnyBranchScheduler, \ 29 ChromeOSManifestSingleBranchScheduler, ChromeOSManifestAnyBranchScheduler, \
28 FilterNewSpec, CommentRespectingGitPoller 30 FilterNewSpec, CommentRespectingGitPoller
29 from master.cros import builder_config 31 from master.cros import builder_config
30 from master.factory import chromeos_factory 32 from master.factory import chromeos_factory
31 33
32 # These modules come from scripts/common, which must be in the PYTHONPATH. 34 # These modules come from scripts/common, which must be in the PYTHONPATH.
35 import chromiumos_board_config
33 import config 36 import config
34 import master_site_config 37 import master_site_config
38 from master.cros import builder_config
39 from common.cros_chromite import ChromiteTarget
35 40
36 ActiveMaster = master_site_config.ChromiumOS 41 ActiveMaster = master_site_config.ChromiumOS
37 42 DRY_RUN = not ActiveMaster.is_production_host
38 TREE_GATE_KEEPER = ActiveMaster.is_production_host
39
40 # Never enable auto_reboot for folks testing locally.
41 DISABLE_AUTO_REBOOT = not ActiveMaster.is_production_host
42 43
43 # This is the dictionary that the buildmaster pays attention to. We also use 44 # This is the dictionary that the buildmaster pays attention to. We also use
44 # a shorter alias to save typing. 45 # a shorter alias to save typing.
45 c = BuildmasterConfig = {} 46 c = BuildmasterConfig = {}
46 47
47 BUILDERS = [] 48 config.DatabaseSetup(c, require_dbconfig=ActiveMaster.is_production_host)
49
48 50
49 # ---------------------------------------------------------------------------- 51 # ----------------------------------------------------------------------------
50 # BUILDER DEFINITIONS 52 # BUILDER DEFINITIONS
51 53
52 # The 'builders' list defines the Builders. Each one is configured with a 54 # The 'builders' list defines the Builders. Each one is configured with a
53 # dictionary, using the following keys: 55 # dictionary, using the following keys:
54 # name (required): the name used to describe this bilder 56 # name (required): the name used to describe this bilder
55 # slavename (required): which slave to use, must appear in c['slaves'] 57 # slavename (required): which slave to use, must appear in c['slaves']
56 # builddir (required): which subdirectory to run the builder in 58 # builddir (required): which subdirectory to run the builder in
57 # factory (required): a BuildFactory to define how the build is run 59 # factory (required): a BuildFactory to define how the build is run
58 # category (optional): it is not used in the normal 'buildbot' meaning. It is 60 # category (optional): it is not used in the normal 'buildbot' meaning. It is
59 # used by JS generation to determine which steps it should 61 # used by JS generation to determine which steps it should
60 # look for to close the tree. 62 # look for to close the tree.
61 # 63 #
62 64
63 # Cros helper functions to build builders and factories. 65 # General source to add in cbuildbot types:
66 def GenCBuild(bc, root_dir=None, auto_reboot=False, branch='master',
67 slave_root='/b', extra_categories=None):
68 """Generate a cbuild buildbot configuration
64 69
65 def GetCBuildbotFactory(config, **kwargs): 70 Create a buildbot builder configuration and return a builder
66 """Returns cros buildbot factories.""" 71 dictionary associated with it.
67 return chromeos_factory.CbuildbotFactory(
68 params=config, dry_run=not ActiveMaster.is_production_host,
69 buildroot='/b/cbuild/external_master', show_gclient_output=False,
70 **kwargs).get_factory()
71 72
73 Arguments:
74 bc: (builder_config.BuilderConfig) The config.
75 root_dir: Root of the directory where all work will take place.
76 name: Name as displayed in the waterfall, if None generate automatically.
77 auto_reboot: bool whether or not the target should reboot between builds
78 branch: The branch to set the builder up for, defaults to 'master'
79 slave_root: The root dir where the buildbot slave is installed.
80 Returns:
81 A builder dictionary assocaited with a factory
82 """
83 categories = ['1release full']
84 if bc.closer:
85 categories.append('closer')
86 else:
87 categories.append('info')
72 88
73 TAGS = {} 89 build_dir_parts = [str(bc.config.name)]
90 if branch:
91 build_dir_parts.append(branch)
74 92
75 class BuilderDefinition(object): 93 # All builders on the internal waterfall should use the same directory names
76 def __init__(self, name): 94 # as the trybot waterfall and any other internal waterfalls. The "_master"
77 self.name = name 95 # suffix is for historical reasons -- we use that suffix regardless of what
96 # branch we're building for.
97 if root_dir is None:
98 root_dir = 'external_master'
78 99
79 def tag(self, *tags): 100 cbuild_root = os.path.join(slave_root, 'cbuild', root_dir)
80 for tag in tags:
81 TAGS.setdefault(tag, []).append(self.name)
82 return self
83 101
102 kwargs = {}
103 # Give the SDK builder more time.
104 if bc.timeout:
105 kwargs['max_time'] = bc.timeout
84 106
85 def AddBuilderDefinition(display_name, cbb_name, closer=True, auto_reboot=False, 107 factory = chromeos_factory.CbuildbotFactory(
86 superTime=None, collapse=False): 108 params=str(bc.config.name), branch=branch, buildroot=cbuild_root,
87 """Adds a builder definition given by the args. 109 show_gclient_output=False, dry_run=DRY_RUN, **kwargs
88 110 ).get_factory()
89 Args:
90 display_name: Name displayed on buildbot waterfall.
91 closer: Do we close the tree based on this build's failure.
92 auto_reboot: Whether to reboot the bot after each run.
93 """
94 category = '1release full|info'
95 builder_definition = BuilderDefinition(display_name)
96 if closer:
97 category = '1release full|closer'
98 builder_definition.tag('closer')
99
100 # Discard suffixes such as " (chromium:12345)".
101 build_dir = re.sub(r'\s\(.*\)$', '', display_name)
102 build_dir = build_dir.replace(' ', '-')
103 if superTime:
104 factory = GetCBuildbotFactory(cbb_name, max_time=superTime)
105 else:
106 factory = GetCBuildbotFactory(cbb_name)
107
108 if DISABLE_AUTO_REBOOT:
109 auto_reboot = False
110 111
111 builder = { 112 builder = {
112 'name': display_name, 113 'name': str(bc.builder_name),
113 'builddir': build_dir, 114 'builddir': '-'.join(build_dir_parts),
114 'factory': factory, 115 'factory': factory,
115 'category': category, 116 'category': '|'.join(categories),
116 'auto_reboot': auto_reboot, 117 'auto_reboot': auto_reboot,
117 } 118 }
118 if collapse: 119 if bc.collapse:
119 builder['collapseRequests'] = builder_config.AlwaysCollapseFunc 120 builder['collapseRequests'] = builder_config.AlwaysCollapseFunc
120 BUILDERS.append(builder) 121 return builder
121 return builder_definition
122 122
123 # Associate the slaves to the builders.
124 c['builders'] = []
123 125
124 def _AddBoardTarget(board, target_type, **kw): 126 for bc in chromiumos_board_config.builder_configs.itervalues():
125 return AddBuilderDefinition('%s %s' % (board, target_type), 127 c['builders'].append(GenCBuild(bc))
126 '%s-%s' % (board, target_type), **kw)
127
128 def AddPaladin(board, **kw):
129 kw['closer'] = False
130 return _AddBoardTarget(board, 'paladin', **kw).tag('paladin')
131
132 def AddIncremental(board, **kw):
133 kw.setdefault('collapse', True)
134 return _AddBoardTarget(board, 'incremental', **kw).tag('default')
135
136 def AddFull(board, **kw):
137 kw.setdefault('collapse', True)
138 return _AddBoardTarget(board, 'full', **kw).tag('default')
139
140 def AddASAN(board, **kw):
141 kw.setdefault('collapse', True)
142 return AddBuilderDefinition(
143 '%s ASAN' % (board,),
144 '%s-asan' % (board,), **kw).tag('default')
145
146 # Paladin Builders -- exception to closer rule below as they are very important
147 # to watch.
148 AddPaladin('x86-generic')
149 AddPaladin('amd64-generic')
150 AddPaladin('amd64-generic_freon')
151 AddPaladin('gizmo')
152 AddPaladin('mipsel-o32-generic')
153 AddPaladin('arm-generic')
154 AddPaladin('panther_embedded-minimal')
155
156 AddIncremental('x86-generic').tag('x86')
157 AddIncremental('amd64-generic').tag('x86')
158 AddIncremental('daisy').tag('arm')
159
160 # Full Builders
161 AddFull('x86-generic').tag('x86')
162 AddFull('amd64-generic').tag('x86')
163 AddFull('daisy').tag('arm')
164 AddFull('arm-generic').tag('arm')
165 AddFull('mipsel-o32-generic')
166
167 AddBuilderDefinition('chromiumos sdk', 'chromiumos-sdk',
168 superTime=22*3600, collapse=True).tag('default')
169
170 ####### Non Closer build defs.
171
172 # Miscellaneous builders.
173 AddBuilderDefinition('refresh packages (chromium:412795)', 'refresh-packages',
174 closer=False).tag('refresh')
175 AddASAN('x86-generic')
176 AddASAN('amd64-generic', closer=False)
177
178
179 c['builders'] = BUILDERS
180
181
182 config.DatabaseSetup(c, require_dbconfig=ActiveMaster.is_production_host)
183 128
184 129
185 ####### CHANGESOURCES 130 ####### CHANGESOURCES
186 131
187 MANIFEST_VERSIONS_REPO = ( 132 MANIFEST_VERSIONS_REPO = (
188 'https://chromium.googlesource.com/chromiumos/manifest-versions') 133 'https://chromium.googlesource.com/chromiumos/manifest-versions')
189 c['change_source'] = [PBChangeSource()] 134 c['change_source'] = [PBChangeSource()]
190 c['change_source'].append(CommentRespectingGitPoller( 135 c['change_source'].append(CommentRespectingGitPoller(
191 repourl=MANIFEST_VERSIONS_REPO, 136 repourl=MANIFEST_VERSIONS_REPO,
192 branch='master', 137 branch='master',
193 workdir='/tmp/chromiumos-manifest-versions', 138 workdir='/tmp/chromiumos-manifest-versions',
194 pollinterval=10)) 139 pollinterval=10))
195 140
196 141
197 ####### SCHEDULERS 142 ####### SCHEDULERS
198 143
144 def GetBuilders(func):
145 return [b for b in chromiumos_board_config.builder_configs.itervalues()
146 if func(b)]
147
148
149 def GetBuilderNames(func):
150 return [str(builder_config.builder_name)
151 for builder_config in GetBuilders(func)]
152
153
154 def GetBuilderNamesForCategory(category):
155 return GetBuilderNames(lambda b: b.config.category == category)
156
157
199 ## configure the Schedulers 158 ## configure the Schedulers
200 # XXX: Changes to builderNames must also be made in:# - slaves.cfg 159 # XXX: Changes to builderNames must also be made in:
160 # - slaves.cfg
201 # - templates/announce.html 161 # - templates/announce.html
202 # - And down below in the builder definitions as well 162 # - And down below in the builder definitions as well
203 # - and you probably need to restart any changed slaves as well as the master 163 # - and you probably need to restart any changed slaves as well as the master
204 164
205 s_paladin = ChromeOSManifestSingleBranchScheduler( 165 s_paladin = ChromeOSManifestSingleBranchScheduler(
206 name='paladin', 166 name='paladin',
207 change_filter=FilterNewSpec(MANIFEST_VERSIONS_REPO, 'master-paladin'), 167 change_filter=FilterNewSpec(MANIFEST_VERSIONS_REPO, 'master-paladin'),
208 builderNames=TAGS['paladin'], 168 builderNames=GetBuilderNamesForCategory(ChromiteTarget.PALADIN),
209 ) 169 )
210 170
211 s_refresh_packages = Periodic( 171 s_refresh_packages = Periodic(
212 name='refresh_pkgs_scheduler', 172 name='refresh_pkgs_scheduler',
213 periodicBuildTimer=24 * 60 * 60, # 1 day 173 periodicBuildTimer=24 * 60 * 60, # 1 day
214 builderNames=TAGS['refresh'], 174 builderNames=GetBuilderNamesForCategory(ChromiteTarget.REFRESH_PACKAGES),
215 ) 175 )
216 176
217 # Default scheduler triggers when we see changes. 177 # Default scheduler triggers when we see changes.
218 repository_fn = lambda x: x != MANIFEST_VERSIONS_REPO 178 repository_fn = lambda x: x != MANIFEST_VERSIONS_REPO
219 s_chromeos_default = ChromeOSManifestAnyBranchScheduler( 179 s_chromeos_default = ChromeOSManifestAnyBranchScheduler(
220 name='chromeos', 180 name='chromeos',
221 change_filter=ChangeFilter(repository_fn=repository_fn, branch='master'), 181 change_filter=ChangeFilter(repository_fn=repository_fn, branch='master'),
222 builderNames=TAGS['default'], 182 builderNames=(
183 GetBuilderNamesForCategory(ChromiteTarget.INCREMENTAL) +
184 GetBuilderNamesForCategory(ChromiteTarget.FULL))
223 ) 185 )
224 186
225 c['schedulers'] = [ 187 c['schedulers'] = [
226 s_paladin, s_chromeos_default, s_refresh_packages, 188 s_paladin, s_chromeos_default, s_refresh_packages,
227 ] 189 ]
228 190
229 ####### BUILDSLAVES 191 ####### BUILDSLAVES
230 192
231 # the 'slaves' list defines the set of allowable buildslaves. Each element is a 193 # the 'slaves' list defines the set of allowable buildslaves. Each element is a
232 # tuple of bot-name and bot-password. These correspond to values given to the 194 # tuple of bot-name and bot-password. These correspond to values given to the
233 # buildslave's mktap invocation. 195 # buildslave's mktap invocation.
234 196
235 # First, load the list from slaves.cfg. 197 # First, load the list from slaves.cfg.
236 slaves = slaves_list.SlavesList('slaves.cfg', 'ChromiumOS') 198 slaves = slaves_list.SlavesList('slaves.cfg', 'ChromiumOS')
237 199 if not slaves.GetSlaves():
238 # Associate the slaves to the builders. 200 raise ValueError("Failed to load slaves.")
239 for builder in c['builders']: 201 for builder in c['builders']:
240 builder['slavenames'] = slaves.GetSlavesName(builder=builder['name']) 202 builder['slavenames'] = slaves.GetSlavesName(builder=builder['name'])
241 203
242 # The 'slaves' list defines the set of allowable buildslaves. List all the 204 # The 'slaves' list defines the set of allowable buildslaves. List all the
243 # slaves registered to a builder. Remove dupes. 205 # slaves registered to a builder. Remove dupes.
244 c['slaves'] = master_utils.AutoSetupSlaves(c['builders'], 206 c['slaves'] = master_utils.AutoSetupSlaves(c['builders'],
245 config.Master.GetBotPassword()) 207 config.Master.GetBotPassword())
246 208
247 209
248 ####### STATUS TARGETS 210 ####### STATUS TARGETS
249 211
250 # Buildbot master url: 212 # Buildbot master url:
251 # Must come before AutoSetupMaster(). 213 # Must come before AutoSetupMaster().
252 c['buildbotURL'] = ActiveMaster.buildbot_url 214 c['buildbotURL'] = ActiveMaster.buildbot_url
253 215
216 # Returns 'True' if a builder is experimental.
217 def cros_builder_experimental(name):
218 config = chromiumos_board_config.builder_name_map.get(name)
219 return config and config.is_experimental
220
221 # Adds common status and tools to this master.
222 def cros_builder_doc(name):
223 config = chromiumos_board_config.builder_name_map.get(name)
224 if config:
225 doc = config.config.get('doc')
226 if doc:
227 return {'url': doc}
228 return None
229
230 web_template_globals = {
231 'cros_builder_experimental': cros_builder_experimental,
232 'cros_builder_doc': cros_builder_doc,
233 }
234
254 # Adds common status and tools to this master. 235 # Adds common status and tools to this master.
255 master_utils.AutoSetupMaster(c, ActiveMaster, 236 master_utils.AutoSetupMaster(c, ActiveMaster,
256 templates=['./templates', '../master.chromium/templates'], 237 templates=['./templates', '../master.chromium/templates'],
257 order_console_by_time=True) 238 order_console_by_time=True,
239 web_template_globals=web_template_globals)
258 240
259 ####### BUILDER LIST OUTPUT 241 ####### BUILDER LIST OUTPUT
260 def write_js_reference(builder_groups):
261 """Generate a js file for the waterfall to include."""
262 242
243 def write_js_json(varname, d):
244 """Generate a js file for the waterfall to include.
245
246 We do this by creating a Javascript fragment defining the variable, 'varname',
247 to be the result of parsing emitted JSON.
248 """
249 json_dump = json.dumps(d, indent=2, sort_keys=True)
250 data = 'var %s = %s;' % (varname, json_dump)
263 with open('public_html/auto-builder.js', 'w') as f: 251 with open('public_html/auto-builder.js', 'w') as f:
264 for name, builders in builder_groups: 252 f.write(data)
265 f.write('var %s = [\n' % name)
266 f.write(',\n'.join([' "builder=%s"' % b for b in builders]))
267 f.write(' ].join("&");\n')
268 253
269 # This gets called by the shim when we need to write the JS file(s). 254 # This gets called by the shim when we need to write the JS file(s).
270 def WriteHTMLFragments(): 255 def WriteHTMLFragments():
271 write_js_reference([ 256 write_js_json('buildercfg', {
272 ('closer', TAGS['closer']), 257 'closers': GetBuilderNames(lambda b: b.closer),
273 ('x86', TAGS['x86']), 258 'paladin': GetBuilderNamesForCategory(ChromiteTarget.PALADIN),
274 ('arm', TAGS['arm']), 259 'incremental': GetBuilderNamesForCategory(ChromiteTarget.INCREMENTAL),
275 ('commit_queue', TAGS['paladin']), 260 'asan': GetBuilderNamesForCategory(ChromiteTarget.ASAN),
276 ]) 261 'full': GetBuilderNamesForCategory(ChromiteTarget.FULL),
262 })
277 263
278 ####### TROOPER NAGGING 264 ####### TROOPER NAGGING
279 if ActiveMaster.is_production_host: 265 if ActiveMaster.is_production_host:
280 from master import chromium_notifier 266 from master import chromium_notifier
281 categories_steps = { 267 categories_steps = {
282 'closer': [ 268 'closer': [
283 'update_scripts', 269 'update_scripts',
284 'Clear and Clone chromite', 270 'Clear and Clone chromite',
285 ] 271 ]
286 } 272 }
287 273
288 c['status'].append(chromium_notifier.ChromiumNotifier( 274 c['status'].append(chromium_notifier.ChromiumNotifier(
289 fromaddr=ActiveMaster.from_address, 275 fromaddr=ActiveMaster.from_address,
290 categories_steps=categories_steps, 276 categories_steps=categories_steps,
291 relayhost=config.Master.smtp, 277 relayhost=config.Master.smtp,
292 status_header='%(steps)s failed on "%(builder)s"', 278 status_header='%(steps)s failed on "%(builder)s"',
293 subject='buildbot trooper alert on %(builder)s (%(projectName)s)', 279 subject='buildbot trooper alert on %(builder)s (%(projectName)s)',
294 extraRecipients=['chrome-troopers@google.com'], 280 extraRecipients=['chrome-troopers@google.com'],
295 sheriffs=['sheriff'], 281 sheriffs=['sheriff'],
296 lookup=master_utils.FilterDomain(), 282 lookup=master_utils.FilterDomain(),
297 use_getname=True)) 283 use_getname=True))
298 284
299 if not ActiveMaster.is_production_host: 285 if not ActiveMaster.is_production_host:
286 # Save our slave pool state. This is populated when our 'slaves' variable
287 # gets generated.
288 chromiumos_board_config.slave_allocator.SaveState(list_unallocated=True)
289 slave_map = chromiumos_board_config.slave_allocator.GetSlaveMap()
290 if slave_map.unallocated:
291 log.msg("The following slaves were not allocated: %s" % (
292 sorted(slave_map.unallocated),))
293
294 # Dump the current configuration.
300 master_utils.DumpSetup(c) 295 master_utils.DumpSetup(c)
296
297 # Disable 'auto_reboot' on slaves for local testing.
298 for builder in c['builders']:
299 builder['auto_reboot'] = False
OLDNEW
« no previous file with comments | « masters/master.chromiumos/config.current.txt ('k') | masters/master.chromiumos/public_html/document-icon.png » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698