OLD | NEW |
1 # This file is part of Buildbot. Buildbot is free software: you can | 1 # This file is part of Buildbot. Buildbot is free software: you can |
2 # redistribute it and/or modify it under the terms of the GNU General Public | 2 # redistribute it and/or modify it under the terms of the GNU General Public |
3 # License as published by the Free Software Foundation, version 2. | 3 # License as published by the Free Software Foundation, version 2. |
4 # | 4 # |
5 # This program is distributed in the hope that it will be useful, but WITHOUT | 5 # This program is distributed in the hope that it will be useful, but WITHOUT |
6 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 6 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
7 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | 7 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
8 # details. | 8 # details. |
9 # | 9 # |
10 # You should have received a copy of the GNU General Public License along with | 10 # You should have received a copy of the GNU General Public License along with |
11 # this program; if not, write to the Free Software Foundation, Inc., 51 | 11 # this program; if not, write to the Free Software Foundation, Inc., 51 |
12 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 12 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
13 # | 13 # |
14 # Copyright Buildbot Team Members | 14 # Copyright Buildbot Team Members |
15 | 15 |
16 | 16 |
| 17 import re |
17 import os | 18 import os |
18 import signal | 19 import signal |
19 import time | 20 import time |
20 import textwrap | 21 import textwrap |
21 import twisted.internet.error | 22 import twisted.internet.error |
22 | 23 |
23 try: | 24 try: |
24 import pyximport | 25 import pyximport |
25 pyximport.install() | 26 pyximport.install() |
26 from twisted.internet import epollreactor | 27 from twisted.internet import epollreactor |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 changeHorizon = config.get("changeHorizon") | 349 changeHorizon = config.get("changeHorizon") |
349 if changeHorizon is not None and not isinstance(changeHorizon, i
nt): | 350 if changeHorizon is not None and not isinstance(changeHorizon, i
nt): |
350 raise ValueError("changeHorizon needs to be an int") | 351 raise ValueError("changeHorizon needs to be an int") |
351 | 352 |
352 multiMaster = config.get("multiMaster", False) | 353 multiMaster = config.get("multiMaster", False) |
353 | 354 |
354 metrics_config = config.get("metrics") | 355 metrics_config = config.get("metrics") |
355 caches_config = config.get("caches", {}) | 356 caches_config = config.get("caches", {}) |
356 autoBuildCacheRatio = config.get("autoBuildCacheRatio", None) | 357 autoBuildCacheRatio = config.get("autoBuildCacheRatio", None) |
357 | 358 |
| 359 # load validation, with defaults, and verify no unrecognized |
| 360 # keys are included. |
| 361 validation_defaults = { |
| 362 'branch': re.compile(r'^[\w.+/~-]*$'), |
| 363 'revision': re.compile(r'^[\w.+/~-]*$'), |
| 364 'property_name': re.compile(r'^[\w\.\-\/\~:]*$'), |
| 365 'property_value': re.compile(r'^[\w\.\-\/\~:]*$'), |
| 366 } |
| 367 validation_config = validation_defaults.copy() |
| 368 validation_config.update(config.get("validation", {})) |
| 369 v_config_keys = set(validation_config.keys()) |
| 370 v_default_keys = set(validation_defaults.keys()) |
| 371 if v_config_keys > v_default_keys: |
| 372 raise ValueError("unrecognized validation key(s): %s" % |
| 373 (", ".join(v_config_keys - v_default_keys,))) |
| 374 |
358 except KeyError: | 375 except KeyError: |
359 log.msg("config dictionary is missing a required parameter") | 376 log.msg("config dictionary is missing a required parameter") |
360 log.msg("leaving old configuration in place") | 377 log.msg("leaving old configuration in place") |
361 raise | 378 raise |
362 | 379 |
363 if "sources" in config: | 380 if "sources" in config: |
364 m = ("c['sources'] is deprecated as of 0.7.6 and is no longer " | 381 m = ("c['sources'] is deprecated as of 0.7.6 and is no longer " |
365 "accepted in >= 0.8.0 . Please use c['change_source'] inste
ad.") | 382 "accepted in >= 0.8.0 . Please use c['change_source'] inste
ad.") |
366 raise KeyError(m) | 383 raise KeyError(m) |
367 | 384 |
368 if "bots" in config: | 385 if "bots" in config: |
369 m = ("c['bots'] is deprecated as of 0.7.6 and is no longer " | 386 m = ("c['bots'] is deprecated as of 0.7.6 and is no longer " |
370 "accepted in >= 0.8.0 . Please use c['slaves'] instead.") | 387 "accepted in >= 0.8.0 . Please use c['slaves'] instead.") |
371 raise KeyError(m) | 388 raise KeyError(m) |
372 | 389 |
373 # Set up metrics and caches | 390 # Set up metrics and caches |
374 self.loadConfig_Metrics(metrics_config) | 391 self.loadConfig_Metrics(metrics_config) |
375 self.loadConfig_Caches(caches_config, buildCacheSize, | 392 self.loadConfig_Caches(caches_config, buildCacheSize, |
376 changeCacheSize) | 393 changeCacheSize) |
377 | 394 |
378 slaves = config.get('slaves', []) | 395 slaves = config.get('slaves', []) |
379 if "slaves" not in config: | 396 if "slaves" not in config: |
380 log.msg("config dictionary must have a 'slaves' key") | 397 log.msg("config dictionary must have a 'slaves' key") |
381 log.msg("leaving old configuration in place") | 398 log.msg("leaving old configuration in place") |
382 raise KeyError("must have a 'slaves' key") | 399 raise KeyError("must have a 'slaves' key") |
383 | 400 |
384 self.config.changeHorizon = changeHorizon | 401 self.config.changeHorizon = changeHorizon |
| 402 self.config.validation = validation_config |
385 | 403 |
386 change_source = config.get('change_source', []) | 404 change_source = config.get('change_source', []) |
387 if isinstance(change_source, (list, tuple)): | 405 if isinstance(change_source, (list, tuple)): |
388 change_sources = change_source | 406 change_sources = change_source |
389 else: | 407 else: |
390 change_sources = [change_source] | 408 change_sources = [change_source] |
391 | 409 |
392 # do some validation first | 410 # do some validation first |
393 for s in slaves: | 411 for s in slaves: |
394 assert interfaces.IBuildSlave.providedBy(s) | 412 assert interfaces.IBuildSlave.providedBy(s) |
(...skipping 898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1293 self.master.addChange(change) | 1311 self.master.addChange(change) |
1294 | 1312 |
1295 def addBuildset(self, **kwargs): | 1313 def addBuildset(self, **kwargs): |
1296 return self.master.addBuildset(**kwargs) | 1314 return self.master.addBuildset(**kwargs) |
1297 | 1315 |
1298 def getBuilder(self, name): | 1316 def getBuilder(self, name): |
1299 b = self.master.botmaster.builders[name] | 1317 b = self.master.botmaster.builders[name] |
1300 return BuilderControl(b, self) | 1318 return BuilderControl(b, self) |
1301 | 1319 |
1302 components.registerAdapter(Control, BuildMaster, interfaces.IControl) | 1320 components.registerAdapter(Control, BuildMaster, interfaces.IControl) |
OLD | NEW |