OLD | NEW |
---|---|
(Empty) | |
1 # -*- python -*- | |
2 # ex: set syntax=python: | |
3 | |
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 | |
6 # found in the LICENSE file. | |
7 | |
8 # It has one job: define a dictionary named BuildmasterConfig. This | |
9 # dictionary has a variety of keys to control different aspects of the | |
10 # buildmaster. They are documented in docs/config.xhtml . | |
11 | |
12 from buildbot import locks | |
13 from buildbot.changes import svnpoller | |
14 from buildbot.scheduler import Dependent | |
15 from buildbot.scheduler import Scheduler | |
16 from buildbot.scheduler import Periodic | |
17 | |
18 from common import chromium_utils | |
19 from master import build_utils | |
20 from master import chromium_step | |
21 from master import master_utils | |
22 from master import slaves_list | |
23 from master.factory import chromium_factory | |
24 from master.factory import gclient_factory | |
25 from master.factory import dart_factory | |
26 from buildbot.process.buildstep import RemoteShellCommand | |
27 | |
28 import config | |
29 ActiveMaster = config.Master.DartFYI | |
30 | |
31 # Hack to increase timeout for steps, dart2js debug checked mode takes more than | |
32 # 8 hours. | |
33 RemoteShellCommand.__init__.im_func.func_defaults = (None, | |
nsylvain
2012/04/12 00:38:17
Someone modified AddTestStep in the last week or 2
| |
34 1, | |
35 1, | |
36 1200, | |
37 48*60*60, {}, | |
38 'slave-config', | |
39 True) | |
40 | |
41 MASTER_HOST = ActiveMaster.master_host | |
42 WEB_STATUS = True | |
43 MAIL_NOTIFIER = False | |
44 TREE_GATE_KEEPER = False | |
45 GOOD_REVISIONS = False | |
46 MASTER_PORT = ActiveMaster.master_port | |
47 | |
48 | |
49 # This is the dictionary that the buildmaster pays attention to. We also use | |
50 # a shorter alias to save typing. | |
51 c = BuildmasterConfig = {} | |
52 | |
53 config.DatabaseSetup(c, require_dbconfig=ActiveMaster.is_production_host) | |
54 | |
55 # 'slavePortnum' defines the TCP port to listen on. This must match the value | |
56 # configured into the buildslaves (with their --master option) | |
57 c['slavePortnum'] = ActiveMaster.slave_port | |
58 | |
59 # Setup a per slave lock to prevent more than one thing running at once on | |
60 # a single slave. | |
61 slave_lock = locks.SlaveLock('overload_lock', maxCount=1) | |
62 | |
63 | |
64 # Slave allocation | |
65 # build-base-name, category, platform, builder, tester | |
66 variants = [] | |
67 | |
68 | |
69 slaves = slaves_list.SlavesList('slaves.cfg', 'Dart') | |
70 | |
71 | |
72 ####### CHANGESOURCES | |
73 | |
74 def DartTreeFileSplitter(path): | |
75 pieces = path.split('/') | |
76 if pieces[0] == 'trunk': | |
77 return ('trunk', '/'.join(pieces[1:])) | |
78 elif pieces[0] == 'branches': | |
79 return ('/'.join(pieces[0:2]), | |
80 '/'.join(pieces[2:])) | |
81 else: | |
82 return None | |
83 | |
84 dart_revision_url = "http://code.google.com/p/dart/source/detail?r=%s" | |
85 | |
86 # Polls config.Master.dart_url for changes | |
87 poller = svnpoller.SVNPoller(svnurl=config.Master.dart_url, | |
88 split_file=DartTreeFileSplitter, | |
89 pollinterval=10, | |
90 revlinktmpl=dart_revision_url) | |
91 | |
92 c['change_source'] = [poller] | |
93 | |
94 ####### SCHEDULERS | |
95 | |
96 ## configure the Schedulers | |
97 | |
98 builder_names = [] | |
99 for v in variants: | |
100 builder_names.append(v['name']) | |
101 | |
102 s = Scheduler( | |
103 name='main', | |
104 branch="branches/bleeding_edge", | |
105 treeStableTimer=0, | |
106 builderNames=builder_names | |
107 ) | |
108 | |
109 c['schedulers'] = [s] | |
110 | |
111 | |
112 ####### BUILDERS | |
113 | |
114 # buildbot/process/factory.py provides several BuildFactory classes you can | |
115 # start with, which implement build processes for common targets (GNU | |
116 # autoconf projects, CPAN perl modules, etc). The factory.BuildFactory is the | |
117 # base class, and is configured with a series of BuildSteps. When the build | |
118 # is run, the appropriate buildslave is told to execute each Step in turn. | |
119 | |
120 # the first BuildStep is typically responsible for obtaining a copy of the | |
121 # sources. There are source-obtaining Steps in buildbot/process/step.py for | |
122 # CVS, SVN, and others. | |
123 | |
124 builders = [] | |
125 | |
126 # ---------------------------------------------------------------------------- | |
127 # FACTORIES | |
128 | |
129 factory_base = { | |
130 'vm-mac': dart_factory.DartFactory('dart', 'vm-mac'), | |
131 'vm-linux': dart_factory.DartFactory('dart', 'vm-linux'), | |
132 'vm-win32': dart_factory.DartFactory('dart', 'vm-win32'), | |
133 'dartc-linux': dart_factory.DartFactory('dart', 'dartc-linux'), | |
134 'dart_client': dart_factory.DartFactory('dart', 'dart_client'), | |
135 'dart-editor': dart_factory.DartFactory('dart', 'dart-editor'), | |
136 'frog': dart_factory.DartFactory('dart', 'frog'), | |
137 'frogsh': dart_factory.DartFactory('dart', 'frogsh'), | |
138 } | |
139 | |
140 for v in variants: | |
141 platform = v['platform'] | |
142 base = factory_base[platform] | |
143 if platform in ['dart_client', 'dart-editor']: | |
144 v['factory_builder'] = base.DartAnnotatedFactory( | |
145 python_script='dart/client/tools/buildbot_annotated_steps.py', | |
146 ) | |
147 else: | |
148 v['factory_builder'] = base.DartFactory( | |
149 slave_type='BuilderTester', | |
150 clobber=False, | |
151 options={ | |
152 'mode': v['mode'], | |
153 'arch': v['arch'], | |
154 'name': v['name'], | |
155 }, | |
156 ) | |
157 | |
158 | |
159 factories = [] | |
160 | |
161 | |
162 primary_builders = [] | |
163 for f in factories: | |
164 primary_builders.append(f[0]) | |
165 | |
166 s_dartium = Scheduler( | |
167 name='dartium', | |
168 branch='branches/bleeding_edge', | |
169 treeStableTimer=0, | |
170 builderNames=primary_builders) | |
171 c['schedulers'].append(s_dartium) | |
172 | |
173 # ---------------------------------------------------------------------------- | |
174 # BUILDER DEFINITIONS | |
175 | |
176 # The 'builders' list defines the Builders. Each one is configured with a | |
177 # dictionary, using the following keys: | |
178 # name (required): the name used to describe this builder | |
179 # slavename (required): which slave to use, must appear in c['slaves'] | |
180 # builddir (required): which subdirectory to run the builder in | |
181 # factory (required): a BuildFactory to define how the build is run | |
182 # periodicBuildTime (optional): if set, force a build every N seconds | |
183 # category (optional): it is not used in the normal 'buildbot' meaning. It is | |
184 # used by gatekeeper to determine which steps it should | |
185 # look for to close the tree. | |
186 # | |
187 | |
188 c['builders'] = [] | |
189 for v in variants: | |
190 c['builders'].append({ | |
191 'name': v['name'], | |
192 'builddir': v['name'], | |
193 'factory': v['factory_builder'], | |
194 'slavenames': slaves.GetSlavesName(builder=v['name']), | |
195 'category': v['category'], | |
196 'locks': [slave_lock], | |
197 }) | |
198 | |
199 | |
200 for f in factories: | |
201 c['builders'].append({ | |
202 'name': f[0], | |
203 'slavenames': slaves.GetSlavesName(builder=f[0]), | |
204 'builddir': f[0], | |
205 'factory': f[2], | |
206 'category': '%s' % f[1], | |
207 # Don't enable auto_reboot for people testing locally. | |
208 'auto_reboot': ActiveMaster.is_production_host, | |
209 }) | |
210 | |
211 ####### BUILDSLAVES | |
212 | |
213 # The 'slaves' list defines the set of allowable buildslaves. List all the | |
214 # slaves registered to a builder. Remove dupes. | |
215 c['slaves'] = master_utils.AutoSetupSlaves(c['builders'], | |
216 config.Master.GetBotPassword()) | |
217 | |
218 # Make sure everything works together. | |
219 master_utils.VerifySetup(c, slaves) | |
220 | |
221 | |
222 ####### STATUS TARGETS | |
223 | |
224 # 'status' is a list of Status Targets. The results of each build will be | |
225 # pushed to these targets. buildbot/status/*.py has a variety to choose from, | |
226 # including web pages, email senders, and IRC bots. | |
227 | |
228 c['status'] = [] | |
229 | |
230 if WEB_STATUS: | |
231 c['status'].append( | |
232 master_utils.CreateWebStatus(MASTER_PORT, allowForce=True, | |
233 public_html='./public_html', | |
234 templates=['./templates'])) | |
235 c['status'].append( | |
236 master_utils.CreateWebStatus(ActiveMaster.master_port_alt, | |
237 allowForce=False)) | |
238 | |
239 if MAIL_NOTIFIER: | |
240 from buildbot.status.mail import MailNotifier | |
241 c['status'].append(MailNotifier(fromaddr=ActiveMaster.from_address, | |
242 mode='problem', | |
243 sendToInterestedUsers=True, | |
244 extraRecipients=['ricow@google.com'], | |
245 lookup=master_utils.FilterDomain())) | |
246 | |
247 if TREE_GATE_KEEPER: | |
248 from master import gatekeeper | |
249 # This is the list of the builder categories and the corresponding critical | |
250 # steps. If one critical step fails, gatekeeper will close the tree | |
251 # automatically. | |
252 categories_steps = { | |
253 '': ['update scripts', 'update', 'clobber', 'clobber_packages'], | |
254 'closer': ['update scripts', 'update', 'compile', 'unit_tests'], | |
255 'info': [], | |
256 'inprogress': [], | |
257 'plugin': ['clobber', 'compile', | |
258 'small_tests', 'medium_tests', 'large_tests'], | |
259 'qa': ['unit_tests'], | |
260 } | |
261 exclusions = {} | |
262 forgiving_steps = ['update scripts', 'update', 'svnkill', 'taskkill', | |
263 'archived build'] | |
264 c['status'].append(gatekeeper.GateKeeper( | |
265 fromaddr=ActiveMaster.from_address, | |
266 categories_steps=categories_steps, | |
267 exclusions=exclusions, | |
268 relayhost=config.Master.smtp, | |
269 subject='buildbot %(result)s in %(projectName)s on %(builder)s, ' | |
270 'revision %(revision)s', | |
271 extraRecipients=ActiveMaster.tree_closing_notification_recipients, | |
272 lookup='google.com', | |
273 forgiving_steps=forgiving_steps)) | |
274 | |
275 if GOOD_REVISIONS: | |
276 from master import goodrevisions | |
277 # This is the list of builders with their respective list of critical steps | |
278 # that all need to succeed to mark a revision as successful. A single failure | |
279 # in any of the steps of any of the builders will mark the revision as failed. | |
280 good_revision_steps = { | |
281 '': ['update', 'compile'], | |
282 } | |
283 c['status'].append(goodrevisions.GoodRevisions( | |
284 good_revision_steps=good_revision_steps, | |
285 store_revisions_url=ActiveMaster.store_revisions_url)) | |
286 | |
287 | |
288 # Keep last build logs, the default is too low. | |
289 c['buildHorizon'] = 1000 | |
290 c['logHorizon'] = 500 | |
291 # Must be at least 2x the number of slaves. | |
292 c['eventHorizon'] = 200 | |
293 # Must be at least 1x the number of builds listed in console. | |
294 c['buildCacheSize'] = 60 | |
295 | |
296 | |
297 ####### DEBUGGING OPTIONS | |
298 | |
299 # if you set 'debugPassword', then you can connect to the buildmaster with | |
300 # the diagnostic tool in contrib/debugclient.py . From this tool, you can | |
301 # manually force builds and inject changes, which may be useful for testing | |
302 # your buildmaster without actually commiting changes to your repository (or | |
303 # before you have a functioning 'sources' set up). The debug tool uses the | |
304 # same port number as the slaves do: 'slavePortnum'. | |
305 | |
306 #c['debugPassword'] = 'debugpassword' | |
307 | |
308 # if you set 'manhole', you can ssh into the buildmaster and get an | |
309 # interactive python shell, which may be useful for debugging buildbot | |
310 # internals. It is probably only useful for buildbot developers. You can also | |
311 # use an authorized_keys file, or plain telnet. | |
312 #from buildbot import manhole | |
313 #c['manhole'] = manhole.PasswordManhole('tcp:9999:interface=127.0.0.1', | |
314 # 'admin', 'password') | |
315 | |
316 | |
317 ####### PROJECT IDENTITY | |
318 | |
319 # the 'projectName' string will be used to describe the project that this | |
320 # buildbot is working on. For example, it is used as the title of the | |
321 # waterfall HTML page. The 'projectURL' string will be used to provide a link | |
322 # from buildbot HTML pages to your project's home page. | |
323 | |
324 c['projectName'] = ActiveMaster.project_name | |
325 c['projectURL'] = config.Master.project_url | |
326 | |
327 # the 'buildbotURL' string should point to the location where the buildbot's | |
328 # internal web server (usually the html.Waterfall page) is visible. This | |
329 # typically uses the port number set in the Waterfall 'status' entry, but | |
330 # with an externally-visible host name which the buildbot cannot figure out | |
331 # without some help. | |
332 | |
333 c['buildbotURL'] = 'http://build.chromium.org/p/client.dart/' | |
OLD | NEW |