master.cfg 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. # -*- python -*-
  2. # ex: set syntax=python:
  3. import json
  4. from buildbot.plugins import *
  5. from buildbot.plugins import buildslave, util
  6. # This is a sample buildmaster config file. It must be installed as
  7. # 'master.cfg' in your buildmaster's base directory.
  8. # This is the dictionary that the buildmaster pays attention to. We also use
  9. # a shorter alias to save typing.
  10. c = BuildmasterConfig = {}
  11. quaggagit = 'git://git.sv.gnu.org/quagga.git'
  12. # password defs
  13. execfile("pass.cfg")
  14. # filter a given 'workers' entry into a property list
  15. # suitable for public display
  16. def workers2publicprops (worker):
  17. publicprops = [ "os", "version", "vm", "pkg", "texi", "cc",
  18. "latent", "env" ]
  19. return { k:worker[k] for k in worker if k in publicprops }
  20. # get compiler names
  21. def compilers(workers):
  22. names = set ()
  23. for l in [ w["cc"] for w in workers.values ()]:
  24. for e in l:
  25. names |= { e["n"] }
  26. return names
  27. # bots with given compiler tag
  28. def ccbots (cc):
  29. return [ workers[kw]["bot"] for kw in workers
  30. if len([c["n"] for c in workers[kw]["cc"]
  31. if c["n"] is cc]) > 0]
  32. # vm: non-VM are assumed faster and used for initial build
  33. # pkg: rpm, sysv, dpkg - only do test rpm builds at moment
  34. # texi: True or "true" if we can use for doc building
  35. # cc: List of dicts of installed compilers, with:
  36. # { "n": <tag>, "v": <version>, "bin": <command>) }
  37. # tags: gcc, clang, sunpro, tcc
  38. # env: JSON dictionary of environment variables to be passed to shell
  39. # commands as a dictionary via json.load.
  40. # latent: VM spun up on demand via LatentSlave, uses "session" for
  41. # the libvirt URI.
  42. #
  43. # When latent is true:
  44. # session: libvirt URI to use for latent workers. Default will be set on
  45. # latent VMs if not specified.
  46. # hd_image: libvirt image to use
  47. workers = {
  48. "fedora-24": {
  49. "os": "Fedora",
  50. "version": "24",
  51. "vm": False,
  52. "pkg": "rpm",
  53. "texi": True,
  54. "cc": [ { "n": "gcc", "v": "6.3.1"},
  55. { "n": "clang", "v": "3.8.1"},
  56. { "n": "gcc", "v": "3.4.6", "bin": "gcc34"},
  57. ],
  58. },
  59. "fedora-26": {
  60. "os": "Fedora",
  61. "version": "26",
  62. "vm": False,
  63. "pkg": "rpm",
  64. "cc": [ { "n": "gcc", "v": "7.0.1" },
  65. { "n": "clang", "v": "3.9.0" },
  66. { "n": "gcc", "v": "3.4.6", "bin": "gcc34" },
  67. ],
  68. },
  69. "centos-7": {
  70. "os": "CentOS",
  71. "version": "7",
  72. "vm": False,
  73. "pkg": "rpm",
  74. "cc": [ { "n": "gcc", "v": "4.8.5"} ],
  75. },
  76. "ubuntu-16.10": {
  77. "os": "Ubuntu",
  78. "version": "16.10",
  79. "vm": False,
  80. "pkg": "dpkg",
  81. "cc": [
  82. { "n": "gcc", "v": "6.2.0"},
  83. { "n": "tcc", "v": "0.9.26"},
  84. ],
  85. },
  86. "debian-8": {
  87. "os": "Debian",
  88. "version": "8",
  89. "vm": True,
  90. "pkg": "dpkg",
  91. "latent": True,
  92. "cc": [ { "n": "gcc", "v": "4.9.2"} ],
  93. "hd_image": "/var/lib/libvirt/images/debian8.qcow2",
  94. },
  95. "debian-9": {
  96. "os": "Debian",
  97. "version": "9",
  98. "vm": True,
  99. "pkg": "dpkg",
  100. "cc": [ { "n": "gcc", "v": "6.3.0"} ],
  101. "latent": True,
  102. "hd_image": "/var/lib/libvirt/images/debian9.qcow2",
  103. },
  104. "freebsd-10": {
  105. "os": "FreeBSD",
  106. "version": "10",
  107. "vm": True,
  108. "pkg": "",
  109. "latent": True,
  110. "cc": [ { "n": "clang", "v": "3.4.1"} ],
  111. "hd_image": "/var/lib/libvirt/images/freebsd103.qcow2",
  112. },
  113. "freebsd-11": {
  114. "os": "FreeBSD",
  115. "version": "11",
  116. "vm": True,
  117. "pkg": "",
  118. "cc": [ {"n": "gcc", "v": "4.9.4"},
  119. { "n": "clang", "v": "3.8.0"},
  120. ],
  121. "latent": True,
  122. "hd_image": "/var/lib/libvirt/images/freebsd110.qcow2",
  123. },
  124. "openbsd-6": {
  125. "os": "OpenBSD",
  126. "version": "6.0",
  127. "vm": True,
  128. "pkg": "",
  129. "cc": [ { "n": "gcc", "v": "4.2.1"} ],
  130. "latent": True,
  131. "hd_image": "/var/lib/libvirt/images/openbsd-6.qcow2",
  132. "env": ' { "AUTOMAKE_VERSION": "1.15", "AUTOCONF_VERSION": "2.69" } ',
  133. },
  134. "oi-hipster": {
  135. "os": "OpenIndiana",
  136. "version": "hipster",
  137. "vm": True,
  138. "pkg": "sysv",
  139. "latent": True,
  140. "cc": [ { "n": "gcc", "v": "6.3.0"},
  141. { "n": "sunpro", "v": "12.0" },
  142. { "n": "gcc", "v": "4.4.4"}
  143. ],
  144. "hd_image": "/var/lib/libvirt/images/buildbot-oi-hipster.qcow2",
  145. },
  146. }
  147. # workers config preparation:
  148. # - add defaults for important fields not set
  149. # - add passwords
  150. def workers_prep (workers):
  151. for kw in workers:
  152. w = workers[kw]
  153. w["bot"] = "buildbot-" + kw
  154. # 'latent' must be set.
  155. if "latent" not in w:
  156. w["latent"] = False
  157. # set default libvirt session for latent bots
  158. if w["latent"] and ("session" not in w):
  159. w["session"] = 'qemu+ssh://buildbot@sagan.jakma.org/system'
  160. w["pass"] = workers_pass[kw]
  161. workers_prep (workers)
  162. analyses_builders = [ "clang-analyzer" ]
  163. osbuilders = ["build-" + kw for kw in workers]
  164. osfastbuilders = ["build-" + kw for kw in workers if workers[kw]["vm"] == False]
  165. osslowbuilders = ["build-" + kw for kw in workers if workers[kw]["vm"] == True]
  166. rpmbuilders = ["rpm-" + kw for kw in workers if workers[kw]["pkg"] == "rpm"]
  167. allbuilders = []
  168. allbuilders += osbuilders
  169. allbuilders += rpmbuilders
  170. allbuilders += analyses_builders
  171. allbuilders += ["commit-builder"]
  172. allbuilders += ["build-distcheck"]
  173. allbuilders += ["build-docs" ]
  174. # Force merging of requests.
  175. # c['mergeRequests'] = lambda *args, **kwargs: True
  176. ####### BUILDSLAVES
  177. c['slaves'] = []
  178. # The 'slaves' list defines the set of recognized buildslaves. Each element is
  179. # a BuildSlave object, specifying a unique slave name and password. The same
  180. # slave name and password must be configured on the slave.
  181. for w in (w for w in workers.values() if ("latent" not in w)
  182. or (w["latent"] == False)):
  183. c['slaves'].append(buildslave.BuildSlave(w["bot"], w["pass"],
  184. properties=workers2publicprops (w),
  185. ))
  186. for w in (w for w in workers.values()
  187. if ("latent" in w)
  188. and w["latent"]
  189. and "hd_image" in w):
  190. c['slaves'].append(buildslave.LibVirtSlave(
  191. w["bot"],
  192. w["pass"],
  193. util.Connection(w["session"]),
  194. w["hd_image"],
  195. properties=workers2publicprops (w),
  196. ))
  197. # 'protocols' contains information about protocols which master will use for
  198. # communicating with slaves.
  199. # You must define at least 'port' option that slaves could connect to your master
  200. # with this protocol.
  201. # 'port' must match the value configured into the buildslaves (with their
  202. # --master option)
  203. c['protocols'] = {'pb': {'port': 9989}}
  204. ####### CHANGESOURCES
  205. # the 'change_source' setting tells the buildmaster how it should find out
  206. # about source code changes. Here we point to the buildbot clone of pyflakes.
  207. c['change_source'] = []
  208. c['change_source'].append(changes.GitPoller(
  209. quaggagit,
  210. workdir='gitpoller-workdir',
  211. branches=True,
  212. # branches=['master','volatile/next'],
  213. pollinterval=300))
  214. ####### REVISION LINKS
  215. # associate changesouce repositories to URI templates for code view
  216. #
  217. c['revlink'] = util.RevlinkMatch([quaggagit + r"(.*)"],
  218. r"http://git.savannah.gnu.org/cgit/quagga.git/commit/?id=%s")
  219. ####### SCHEDULERS
  220. # Configure the Schedulers, which decide how to react to incoming changes.
  221. # We want a first line of 'quick' builds, which then trigger further builds.
  222. #
  223. # A control-flow builder, "commit-builder", used to sequence the 'real'
  224. # sets of builders, via Triggers.
  225. c['schedulers'] = []
  226. c['schedulers'].append(schedulers.SingleBranchScheduler(
  227. name="master-change",
  228. change_filter=util.ChangeFilter(branch='master'),
  229. treeStableTimer=10,
  230. builderNames=[ "commit-builder" ]))
  231. c['schedulers'].append(schedulers.SingleBranchScheduler(
  232. name="next-change",
  233. change_filter=util.ChangeFilter(
  234. branch='volatile/next'),
  235. treeStableTimer=10,
  236. builderNames=[ "commit-builder" ] ))
  237. # Initial build checks on faster, non-VM
  238. c['schedulers'].append(schedulers.Triggerable(
  239. name="trigger-build-first",
  240. builderNames=osfastbuilders))
  241. # Build using remaining builders, after firstbuilders.
  242. c['schedulers'].append(schedulers.Triggerable(
  243. name="trigger-build-rest",
  244. builderNames=osslowbuilders))
  245. # Analyses tools, e.g. CLang Analyzer scan-build
  246. c['schedulers'].append(schedulers.Triggerable(
  247. name="trigger-build-analyses",
  248. builderNames=analyses_builders))
  249. # Dist check
  250. c['schedulers'].append(schedulers.Triggerable(
  251. name="trigger-distcheck",
  252. builderNames=["build-distcheck"]))
  253. # RPM check and build
  254. c['schedulers'].append(schedulers.Triggerable(
  255. name="trigger-rpm",
  256. builderNames=rpmbuilders))
  257. # Doc build check (non-nightly, so no upload)
  258. c['schedulers'].append(schedulers.Triggerable(
  259. name="trigger-build-docs",
  260. builderNames=["build-docs"]))
  261. # Try and force schedulers
  262. c['schedulers'].append(schedulers.ForceScheduler(
  263. name="force",
  264. builderNames=allbuilders))
  265. c['schedulers'].append(schedulers.Try_Userpass(
  266. name="try",
  267. builderNames=osbuilders
  268. + rpmbuilders
  269. + ["build-distcheck",
  270. "clang-analyzer",
  271. "build-docs" ],
  272. userpass=users,
  273. port=8031))
  274. ## nightly docs build
  275. c['schedulers'].append(schedulers.Nightly(
  276. name="nightly-docs",
  277. branch="master",
  278. builderNames=[ "build-docs" ],
  279. hour=3,
  280. minute=0,
  281. onlyIfChanged=True,
  282. properties = { "nightly": True },
  283. ))
  284. ####### BUILDERS
  285. c['builders'] = []
  286. # The 'builders' list defines the Builders, which tell Buildbot how to perform a build:
  287. # what steps, and which slaves can execute them. Note that any particular build will
  288. # only take place on one slave.
  289. # Renderer to extract simple JSON dictionary object from the configuration
  290. # via the 'env' property, and return as a python dictionary, so it can
  291. # be passed to the 'env=' argument that some Steps allow.
  292. @util.renderer
  293. def get_config_env (props):
  294. jsonenv = props.getProperty('env')
  295. env = None
  296. if jsonenv:
  297. env = json.loads (jsonenv)
  298. return env
  299. def makecmd (target):
  300. if isinstance(target,basestring):
  301. return [ "make", "-j", "2", target ]
  302. return [ "make", "-j", "2" ] + target
  303. step_git = steps.Git(repourl=quaggagit, mode='incremental')
  304. step_autoconf = steps.ShellCommand(command=["./update-autotools"],
  305. description="generating autoconf",
  306. descriptionDone="autoconf",
  307. haltOnFailure=True,
  308. env=get_config_env)
  309. git_and_autoconf = [
  310. step_git, step_autoconf,
  311. ]
  312. step_configure = steps.Configure(command="../build/configure")
  313. step_clean = steps.ShellCommand(command=makecmd("clean"),
  314. description="cleaning",
  315. descriptionDone="make clean")
  316. configure_and_clean = [ step_configure, step_clean ]
  317. common_setup = git_and_autoconf + configure_and_clean
  318. ### Default 'check' build, builder instantiated for each OS
  319. factory = util.BuildFactory()
  320. factory.addSteps(common_setup)
  321. factory.addStep(steps.Compile(command=makecmd("all")))
  322. factory.addStep(steps.ShellCommand(command=makecmd("check"),
  323. description="checking",
  324. descriptionDone="make check"))
  325. # create builder for every OS, for every buildbot
  326. # XXX: at moment this assumes 1:1 OS<->bot
  327. for kw in workers:
  328. c['builders'].append(util.BuilderConfig(
  329. name="build-" + kw,
  330. slavenames=workers[kw]["bot"],
  331. factory=factory))
  332. ### distcheck Builder, executed on any available bot
  333. factory = util.BuildFactory()
  334. factory.addSteps(common_setup)
  335. factory.addStep(steps.ShellCommand(command=makecmd("distcheck"),
  336. description="run make distcheck",
  337. descriptionDone="make distcheck"))
  338. c['builders'].append(
  339. util.BuilderConfig(name="build-distcheck",
  340. slavenames=list(w["bot"] for w in workers.values()),
  341. factory=factory,
  342. ))
  343. ### LLVM clang-analyzer build, executed on any available non-VM bot
  344. f = util.BuildFactory()
  345. f.addSteps(common_setup)
  346. f.addStep(steps.SetProperty(property="clang-id",
  347. value=util.Interpolate("%(prop:commit-description)s-%(prop:buildnumber)s")))
  348. f.addStep(steps.SetProperty(property="clang-output-dir",
  349. value=util.Interpolate("../CLANG-%(prop:clang-id)s")))
  350. f.addStep(steps.SetProperty(property="clang-uri",
  351. value=util.Interpolate("/clang-analyzer/%(prop:clang-id)s")))
  352. # relative to buildbot master working directory
  353. f.addStep(steps.SetProperty(property="clang-upload-dir",
  354. value=util.Interpolate("public_html/clang-analyzer/%(prop:clang-id)s")))
  355. f.addStep(steps.Compile(command=["scan-build",
  356. "-analyze-headers",
  357. "-o",
  358. util.Interpolate("%(prop:clang-output-dir)s"),
  359. "make", "all"]))
  360. f.addStep(steps.DirectoryUpload(
  361. slavesrc=util.Interpolate("%(prop:clang-output-dir)s"),
  362. masterdest = util.Interpolate("%(prop:clang-upload-dir)s"),
  363. compress = 'bz2',
  364. name = "clang report",
  365. url = util.Interpolate("%(prop:clang-uri)s"),
  366. ))
  367. f.addStep(steps.RemoveDirectory(
  368. dir=util.Interpolate("%(prop:clang-output-dir)s")
  369. ))
  370. c['builders'].append(
  371. util.BuilderConfig(name="clang-analyzer",
  372. slavenames=ccbots ("clang"),
  373. factory=f))
  374. ### RPM: check and build
  375. f = util.BuildFactory ()
  376. # check out the source
  377. f.addStep(steps.Git(repourl=quaggagit, mode='full'))
  378. f.addStep(step_autoconf)
  379. f.addStep(step_configure)
  380. f.addStep(steps.ShellCommand(command=makecmd("dist"),
  381. description="run make dist",
  382. descriptionDone="make dist"))
  383. # not imported somehow
  384. #f.addStep(steps.RpmLint(fileloc="redhat/quagga.spec"))
  385. f.addStep(steps.ShellCommand(command=["rpmlint", "-i", "redhat/quagga.spec"],
  386. description="run rpmlint",
  387. descriptionDone="rpmlint"))
  388. f.addStep(steps.RpmBuild(specfile="redhat/quagga.spec"))
  389. # rpmdir=util.Interpolate("%(prop:builddir)s/rpm")))
  390. # XXX: assuming 1:1 OS:buildbot mapping
  391. for kw in (kw for kw in workers if workers[kw]["pkg"] == "rpm"):
  392. c['builders'].append(
  393. util.BuilderConfig(name="rpm-" + kw,
  394. slavenames="buildbot-" + kw,
  395. factory=f
  396. )
  397. )
  398. ### Build documentation
  399. def build_is_nightly (step):
  400. n = step.getProperty("nightly")
  401. if n == True or n == "True" or n == "true":
  402. return True
  403. return False
  404. f = util.BuildFactory ()
  405. f.addStep(steps.Git(repourl=quaggagit, mode='full'))
  406. f.addStep(step_autoconf)
  407. f.addStep(steps.Configure(command=["../build/configure"],
  408. workdir="docs"))
  409. f.addStep(steps.ShellCommand(command=["make", "V=99", "quagga.html"],
  410. description="making split HTML doc",
  411. descriptionDone="docs: split HTML",
  412. workdir="docs/doc",
  413. haltOnFailure=True,
  414. ))
  415. #f.addStep(steps.FileUpload(
  416. # slavesrc="build/doc/fig-normal-processing.png",
  417. # masterdest = "public_html/docs/nightly/quagga/",
  418. # name = "Upload Fig 1",
  419. # doStepIf=build_is_nightly,
  420. #))
  421. #f.addStep(steps.FileUpload(
  422. # slavesrc="build/doc/fig-rs-processing.png",
  423. # masterdest = "public_html/docs/nightly/quagga/",
  424. # name = "Upload Fig 2",
  425. # doStepIf=build_is_nightly,
  426. #))
  427. f.addStep(steps.MultipleFileUpload(
  428. slavesrcs=[ "doc/fig-rs-processing.png",
  429. "doc/fig-normal-processing.png" ],
  430. masterdest = "public_html/docs/nightly/quagga/",
  431. name = "Upload Figures",
  432. doStepIf=build_is_nightly,
  433. ))
  434. f.addStep(steps.DirectoryUpload(
  435. slavesrc="quagga.html",
  436. masterdest = "public_html/docs/nightly/quagga",
  437. compress = 'bz2',
  438. name = "Upload split HTML",
  439. url = "/docs/nightly/quagga/index.html",
  440. workdir="docs/doc",
  441. doStepIf=build_is_nightly,
  442. ))
  443. f.addStep(steps.RemoveDirectory(
  444. dir="docs/doc/quagga.html",
  445. ))
  446. f.addStep(steps.ShellCommand(command=["make", "V=99",
  447. "MAKEINFOFLAGS=--no-split",
  448. "quagga.html"],
  449. description="making one-page HTML doc",
  450. descriptionDone="docs: one-page HTML",
  451. workdir="docs/doc",
  452. haltOnFailure=True
  453. ))
  454. f.addStep(steps.FileUpload(
  455. slavesrc="quagga.html",
  456. masterdest = "public_html/docs/nightly/quagga/quagga.html",
  457. name = "Upload single HTML",
  458. url = "/docs/nightly/quagga/quagga.html",
  459. workdir="docs/doc",
  460. doStepIf=build_is_nightly,
  461. ))
  462. f.addStep(steps.ShellCommand(command=["make", "V=99", "quagga.pdf"],
  463. description="making PDF docs",
  464. descriptionDone="docs: PDF",
  465. workdir="docs/doc"
  466. ))
  467. f.addStep(steps.FileUpload(
  468. slavesrc="quagga.pdf",
  469. masterdest = "public_html/docs/nightly/quagga/quagga.pdf",
  470. name = "Upload PDF",
  471. url = "/docs/nightly/quagga/quagga.pdf",
  472. workdir="docs/doc",
  473. doStepIf=build_is_nightly,
  474. ))
  475. c['builders'].append(
  476. util.BuilderConfig(name="build-docs",
  477. slavenames=[w["bot"] for w in workers.values()
  478. if "texi" in w and w["texi"] == True ],
  479. factory=f
  480. ))
  481. ### Co-ordination builds used to sequence parallel builds via Triggerable
  482. # to understand this you have to read this list and the Triggered schedulers
  483. # to see what sets of builds are being sequenced. Bit clunky, but Buildbot
  484. # doesn't have a way to just specify a pipeline of groups of builders more
  485. # cleanly.
  486. f = util.BuildFactory()
  487. f.addStep(steps.Trigger (
  488. schedulerNames = [ "trigger-build-first" ],
  489. waitForFinish=True,
  490. updateSourceStamp=True
  491. ))
  492. f.addStep(steps.Trigger (
  493. schedulerNames = [ "trigger-build-rest" ],
  494. waitForFinish=True,
  495. updateSourceStamp=True
  496. ))
  497. f.addStep(steps.Trigger (
  498. schedulerNames = [ "trigger-build-analyses", "trigger-distcheck",
  499. "trigger-build-docs" ],
  500. waitForFinish=True,
  501. updateSourceStamp=True
  502. ))
  503. f.addStep(steps.Trigger (
  504. schedulerNames = [ "trigger-rpm" ],
  505. waitForFinish=True,
  506. updateSourceStamp=True
  507. ))
  508. c['builders'].append(
  509. util.BuilderConfig(name="commit-builder",
  510. slavenames=[w["bot"] for w in workers.values() if not w["vm"]],
  511. factory=f)
  512. )
  513. ####### STATUS TARGETS
  514. # 'status' is a list of Status Targets. The results of each build will be
  515. # pushed to these targets. buildbot/status/*.py has a variety to choose from,
  516. # including web pages, email senders, and IRC bots.
  517. c['status'] = []
  518. from buildbot.status import html
  519. from buildbot.status.web import authz, auth
  520. authz_cfg=authz.Authz(
  521. # change any of these to True to enable; see the manual for more
  522. # options
  523. #auth=auth.BasicAuth([("pyflakes","pyflakes")]),
  524. auth=util.BasicAuth(users),
  525. gracefulShutdown = False,
  526. forceBuild = 'auth', # use this to test your slave once it is set up
  527. forceAllBuilds = 'auth', # ..or this
  528. pingBuilder = 'auth',
  529. stopBuild = 'auth',
  530. stopAllBuilds = 'auth',
  531. cancelPendingBuild = 'auth',
  532. cancelAllPendingBuilds = 'auth',
  533. pauseSlave = 'auth',
  534. )
  535. c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
  536. c['status'].append(status.MailNotifier(
  537. fromaddr="buildbot@quagga.net",
  538. extraRecipients=["paul@jakma.org"],
  539. sendToInterestedUsers=False,
  540. ))
  541. c['status'].append (status.IRC(
  542. "irc.freenode.net", "bb-quagga",
  543. useColors=True,
  544. channels=[{"channel": "#quagga"}],
  545. notify_events={
  546. 'exception': 1,
  547. 'successToFailure': 1,
  548. 'failureToSuccess': 1,
  549. },
  550. ))
  551. ####### PROJECT IDENTITY
  552. # the 'title' string will appear at the top of this buildbot
  553. # installation's html.WebStatus home page (linked to the
  554. # 'titleURL') and is embedded in the title of the waterfall HTML page.
  555. c['title'] = "Quagga"
  556. c['titleURL'] = "https://www.quagga.net/"
  557. # the 'buildbotURL' string should point to the location where the buildbot's
  558. # internal web server (usually the html.WebStatus page) is visible. This
  559. # typically uses the port number set in the Waterfall 'status' entry, but
  560. # with an externally-visible host name which the buildbot cannot figure out
  561. # without some help.
  562. c['buildbotURL'] = "http://buildbot.quagga.net/"
  563. ####### DB URL
  564. c['db'] = {
  565. # This specifies what database buildbot uses to store its state. You can leave
  566. # this at its default for all but the largest installations.
  567. 'db_url' : "sqlite:///state.sqlite",
  568. }
  569. #### debug
  570. c['debugPassword'] = debugPassword