2 # ex: set syntax=python:
4 from buildbot.plugins import *
5 from buildbot.plugins import buildslave, util
7 # This is a sample buildmaster config file. It must be installed as
8 # 'master.cfg' in your buildmaster's base directory.
10 # This is the dictionary that the buildmaster pays attention to. We also use
11 # a shorter alias to save typing.
12 c = BuildmasterConfig = {}
14 quaggagit = 'git://git.sv.gnu.org/quagga.git'
19 # filter a given 'workers' entry into a property list
20 # suitable for public display
21 def workers2publicprops (worker):
22 publicprops = [ "os", "version", "vm", "pkg", "texi", "cc",
24 return { k:worker[k] for k in worker if k in publicprops }
26 # vm: non-VM are assumed faster and used for initial build
27 # pkg: rpm, sysv, dpkg - only do test rpm builds at moment
28 # texi: True or "true" if we can use for doc building
29 # cc: List of tuples of installed compilers, with:
30 # (<tag>, <version>, <command>)
31 # tag: gcc, clang, sunpro
32 # latent: VM spun up on demand via LatentSlave, uses "session" for
34 # session: libvirt URI to use for latent workers. Default will be set on
35 # latent VMs if not specified.
36 # hd_image: libvirt image to use
44 "cc": [ ("gcc", "6.3.1"),
46 ("gcc", "3.4.6", "gcc34"),
54 "cc": [ ("gcc", "7.0.1"),
56 ("gcc", "3.4.6", "gcc34"),
64 "cc": [ ("gcc", "4.8.5") ],
72 "cc": [ ("gcc", "4.9.2") ],
73 "hd_image": "/var/lib/libvirt/images/debian8.qcow2",
80 "cc": [ ("gcc", "6.3.0") ],
82 "hd_image": "/var/lib/libvirt/images/debian9.qcow2",
90 "cc": [ ("clang", "3.4.1") ],
91 "hd_image": "/var/lib/libvirt/images/freebsd103.qcow2",
98 "cc": [ ("gcc", "4.9.4"), ("clang", "3.8.0"), ],
100 "hd_image": "/var/lib/libvirt/images/freebsd110.qcow2",
104 "version": "hipster",
108 "cc": [ ("gcc", "6.3.0"), ("sunpro", "12.0"),
111 "hd_image": "/var/lib/libvirt/images/buildbot-oi-hipster.qcow2",
115 # ensure "latent" is set to false, where not set.
116 # add in the passwords
119 w["bot"] = "buildbot-" + kw
120 if "latent" not in w:
122 w["pass"] = workers_pass[kw]
124 analyses_builders = [ "clang-analyzer" ]
126 # default Libvirt session
127 for w in (w for w in workers.values () if ("latent" in w and w["latent"])
128 and ("session" not in w)):
129 w["session"] = 'qemu+ssh://buildbot@sagan.jakma.org/system'
131 osbuilders = ["build-" + kw for kw in workers]
132 osfastbuilders = ["build-" + kw for kw in workers if workers[kw]["vm"] == False]
133 osslowbuilders = ["build-" + kw for kw in workers if workers[kw]["vm"] == True]
135 rpmbuilders = ["rpm-" + kw for kw in workers if workers[kw]["pkg"] == "rpm"]
139 # [kw for kw in workers if len([v for (c,v) in workers[kw]["cc"] if c == "gcc"]) > 0 ]
142 allbuilders += osbuilders
143 allbuilders += rpmbuilders
144 allbuilders += analyses_builders
145 allbuilders += ["commit-builder"]
146 allbuilders += ["build-distcheck"]
147 allbuilders += ["build-docs" ]
149 # Force merging of requests.
150 # c['mergeRequests'] = lambda *args, **kwargs: True
155 # The 'slaves' list defines the set of recognized buildslaves. Each element is
156 # a BuildSlave object, specifying a unique slave name and password. The same
157 # slave name and password must be configured on the slave.
159 for w in (w for w in workers.values() if ("latent" not in w)
160 or (w["latent"] == False)):
161 c['slaves'].append(buildslave.BuildSlave(w["bot"], w["pass"],
162 properties=workers2publicprops (w),
165 for w in (w for w in workers.values()
168 and "hd_image" in w):
169 c['slaves'].append(buildslave.LibVirtSlave(
172 util.Connection(w["session"]),
174 properties=workers2publicprops (w),
177 # 'protocols' contains information about protocols which master will use for
178 # communicating with slaves.
179 # You must define at least 'port' option that slaves could connect to your master
180 # with this protocol.
181 # 'port' must match the value configured into the buildslaves (with their
183 c['protocols'] = {'pb': {'port': 9989}}
185 ####### CHANGESOURCES
187 # the 'change_source' setting tells the buildmaster how it should find out
188 # about source code changes. Here we point to the buildbot clone of pyflakes.
190 c['change_source'] = []
191 c['change_source'].append(changes.GitPoller(
193 workdir='gitpoller-workdir',
194 branches=['master','volatile/next'],
197 ####### REVISION LINKS
198 # associate changesouce repositories to URI templates for code view
200 c['revlink'] = util.RevlinkMatch([quaggagit + r"(.*)"],
201 r"http://git.savannah.gnu.org/cgit/quagga.git/commit/?id=%s")
205 # Configure the Schedulers, which decide how to react to incoming changes.
207 # We want a first line of 'quick' builds, which then trigger further builds.
209 # A control-flow builder, "commit-builder", used to sequence the 'real'
210 # sets of builders, via Triggers.
213 c['schedulers'].append(schedulers.SingleBranchScheduler(
214 name="master-change",
215 change_filter=util.ChangeFilter(branch='master'),
217 builderNames=[ "commit-builder" ]))
219 c['schedulers'].append(schedulers.SingleBranchScheduler(
221 change_filter=util.ChangeFilter(
222 branch='volatile/next'),
224 builderNames=[ "commit-builder" ] ))
226 # Initial build checks on faster, non-VM
227 c['schedulers'].append(schedulers.Triggerable(
228 name="trigger-build-first",
229 builderNames=osfastbuilders))
231 # Build using remaining builders, after firstbuilders.
232 c['schedulers'].append(schedulers.Triggerable(
233 name="trigger-build-rest",
234 builderNames=osslowbuilders))
236 # Analyses tools, e.g. CLang Analyzer scan-build
237 c['schedulers'].append(schedulers.Triggerable(
238 name="trigger-build-analyses",
239 builderNames=analyses_builders))
241 c['schedulers'].append(schedulers.Triggerable(
242 name="trigger-distcheck",
243 builderNames=["build-distcheck"]))
244 # RPM check and build
245 c['schedulers'].append(schedulers.Triggerable(
247 builderNames=rpmbuilders))
249 # Doc build check (non-nightly, so no upload)
250 c['schedulers'].append(schedulers.Triggerable(
251 name="trigger-build-docs",
252 builderNames=["build-docs"]))
254 # Try and force schedulers
255 c['schedulers'].append(schedulers.ForceScheduler(
257 builderNames=allbuilders))
259 c['schedulers'].append(schedulers.Try_Userpass(
261 builderNames=osbuilders
263 + ["build-distcheck",
269 ## nightly docs build
270 c['schedulers'].append(schedulers.Nightly(
273 builderNames=[ "build-docs" ],
277 properties = { "nightly": True },
284 # The 'builders' list defines the Builders, which tell Buildbot how to perform a build:
285 # what steps, and which slaves can execute them. Note that any particular build will
286 # only take place on one slave.
289 steps.Git(repourl=quaggagit, mode='incremental'),
290 steps.ShellCommand(command=["./update-autotools"],
291 description="generating autoconf",
292 descriptionDone="autoconf"),
293 steps.Configure(command="../build/configure"),
294 steps.ShellCommand(command=["make", "clean"],
295 description="cleaning",
296 descriptionDone="make clean"),
299 ### Default 'check' build, builder instantiated for each OS
301 factory = util.BuildFactory()
302 # check out the source
303 factory.addStep(steps.Git(repourl=quaggagit, mode='incremental'))
304 factory.addStep(steps.ShellCommand(command=["./update-autotools"],
305 description="generating autoconf",
306 descriptionDone="autoconf"))
307 factory.addStep(steps.Configure())
308 factory.addStep(steps.ShellCommand(command=["make", "clean"],
309 description="cleaning",
310 descriptionDone="clean"))
312 #factory.addSteps(common_setup)
313 factory.addStep(steps.Compile(command=["make", "-j", "2", "all"]))
314 factory.addStep(steps.ShellCommand(command=["make", "check"],
315 description="checking",
316 descriptionDone="make check"))
318 # create builder for every OS, for every buildbot
319 # XXX: at moment this assumes 1:1 OS<->bot
321 c['builders'].append(util.BuilderConfig(
323 slavenames=workers[kw]["bot"],
326 ### distcheck Builder, executed on any available bot
327 factory = util.BuildFactory()
328 # check out the source
329 factory.addStep(steps.Git(repourl=quaggagit, mode='incremental'))
330 factory.addStep(steps.ShellCommand(command=["./update-autotools"],
331 description="generating autoconf",
332 descriptionDone="autoconf"))
333 factory.addStep(steps.Configure())
334 factory.addStep(steps.ShellCommand(command=["make", "clean"],
335 description="cleaning",
336 descriptionDone="make clean"))
337 factory.addStep(steps.ShellCommand(command=["make", "distcheck"],
338 description="run make distcheck",
339 descriptionDone="make distcheck"))
340 c['builders'].append(
341 util.BuilderConfig(name="build-distcheck",
342 slavenames=list(w["bot"] for w in workers.values()),
346 ### LLVM clang-analyzer build, executed on any available non-VM bot
348 f = util.BuildFactory()
349 # check out the source
350 f.addStep(steps.Git(repourl=quaggagit, mode='incremental',
351 getDescription=True))
352 f.addStep(steps.ShellCommand(command=["./update-autotools"],
353 description="run autotools",
354 descriptionDone="autoconf"))
355 f.addStep(steps.Configure())
356 f.addStep(steps.ShellCommand(command=["make", "clean"],
357 description="cleaning",
358 descriptionDone="make clean"))
360 f.addStep(steps.SetProperty(property="clang-id",
361 value=util.Interpolate("%(prop:commit-description)s-%(prop:buildnumber)s")))
363 f.addStep(steps.SetProperty(property="clang-output-dir",
364 value=util.Interpolate("../CLANG-%(prop:clang-id)s")))
365 f.addStep(steps.SetProperty(property="clang-uri",
366 value=util.Interpolate("/clang-analyzer/%(prop:clang-id)s")))
367 # relative to buildbot master working directory
368 f.addStep(steps.SetProperty(property="clang-upload-dir",
369 value=util.Interpolate("public_html/clang-analyzer/%(prop:clang-id)s")))
371 f.addStep(steps.Compile(command=["scan-build",
374 util.Interpolate("%(prop:clang-output-dir)s"),
375 "make", "-j", "all"]))
376 f.addStep(steps.DirectoryUpload(
377 slavesrc=util.Interpolate("%(prop:clang-output-dir)s"),
378 masterdest = util.Interpolate("%(prop:clang-upload-dir)s"),
380 name = "clang report",
381 url = util.Interpolate("%(prop:clang-uri)s"),
383 f.addStep(steps.RemoveDirectory(
384 dir=util.Interpolate("%(prop:clang-output-dir)s")
388 c['builders'].append(
389 util.BuilderConfig(name="clang-analyzer",
390 slavenames=list(w["bot"] for w in workers.values() if not w["vm"]),
394 ### RPM: check and build
395 f = util.BuildFactory ()
397 # check out the source
398 f.addStep(steps.Git(repourl=quaggagit, mode='full'))
399 f.addStep(steps.ShellCommand(command=["./update-autotools"],
400 description="run autotools",
401 descriptionDone="autotools"))
402 f.addStep(steps.Configure())
403 f.addStep(steps.ShellCommand(command=["make", "dist"],
404 description="run make dist",
405 descriptionDone="make dist"))
406 # not imported somehow
407 #f.addStep(steps.RpmLint(fileloc="redhat/quagga.spec"))
408 f.addStep(steps.ShellCommand(command=["rpmlint", "-i", "redhat/quagga.spec"],
409 description="run rpmlint",
410 descriptionDone="rpmlint"))
411 f.addStep(steps.RpmBuild(specfile="redhat/quagga.spec"))
412 # rpmdir=util.Interpolate("%(prop:builddir)s/rpm")))
414 # XXX: assuming 1:1 OS:buildbot mapping
415 for kw in (kw for kw in workers if workers[kw]["pkg"] == "rpm"):
416 c['builders'].append(
417 util.BuilderConfig(name="rpm-" + kw,
418 slavenames="buildbot-" + kw,
423 ### Build documentation
425 def build_is_nightly (step):
426 n = step.getProperty("nightly")
427 if n == True or n == "True" or n == "true":
431 f = util.BuildFactory ()
432 f.addStep(steps.Git(repourl=quaggagit, mode='full'))
433 f.addStep(steps.ShellCommand(command=["./update-autotools"],
434 description="run autotools",
435 descriptionDone="autotools"))
436 f.addStep(steps.Configure(command=["../build/configure"],
438 f.addStep(steps.ShellCommand(command=["make", "V=99", "quagga.html"],
439 description="making split HTML doc",
440 descriptionDone="docs: split HTML",
444 #f.addStep(steps.FileUpload(
445 # slavesrc="build/doc/fig-normal-processing.png",
446 # masterdest = "public_html/docs/nightly/quagga/",
447 # name = "Upload Fig 1",
448 # doStepIf=build_is_nightly,
450 #f.addStep(steps.FileUpload(
451 # slavesrc="build/doc/fig-rs-processing.png",
452 # masterdest = "public_html/docs/nightly/quagga/",
453 # name = "Upload Fig 2",
454 # doStepIf=build_is_nightly,
456 f.addStep(steps.MultipleFileUpload(
457 slavesrcs=[ "doc/fig-rs-processing.png",
458 "doc/fig-normal-processing.png" ],
459 masterdest = "public_html/docs/nightly/quagga/",
460 name = "Upload Figures",
461 doStepIf=build_is_nightly,
463 f.addStep(steps.DirectoryUpload(
464 slavesrc="quagga.html",
465 masterdest = "public_html/docs/nightly/quagga",
467 name = "Upload split HTML",
468 url = "/docs/nightly/quagga/index.html",
470 doStepIf=build_is_nightly,
472 f.addStep(steps.RemoveDirectory(
473 dir="docs/doc/quagga.html",
475 f.addStep(steps.ShellCommand(command=["make", "V=99",
476 "MAKEINFOFLAGS=--no-split",
478 description="making one-page HTML doc",
479 descriptionDone="docs: one-page HTML",
483 f.addStep(steps.FileUpload(
484 slavesrc="quagga.html",
485 masterdest = "public_html/docs/nightly/quagga/quagga.html",
486 name = "Upload single HTML",
487 url = "/docs/nightly/quagga/quagga.html",
489 doStepIf=build_is_nightly,
491 f.addStep(steps.ShellCommand(command=["make", "V=99", "quagga.pdf"],
492 description="making PDF docs",
493 descriptionDone="docs: PDF",
496 f.addStep(steps.FileUpload(
497 slavesrc="quagga.pdf",
498 masterdest = "public_html/docs/nightly/quagga/quagga.pdf",
500 url = "/docs/nightly/quagga/quagga.pdf",
502 doStepIf=build_is_nightly,
505 c['builders'].append(
506 util.BuilderConfig(name="build-docs",
507 slavenames=[w["bot"] for w in workers.values()
508 if "texi" in w and w["texi"] == True ],
512 ### Co-ordination builds used to sequence parallel builds via Triggerable
514 # to understand this you have to read this list and the Triggered schedulers
515 # to see what sets of builds are being sequenced. Bit clunky, but Buildbot
516 # doesn't have a way to just specify a pipeline of groups of builders more
519 f = util.BuildFactory()
520 f.addStep(steps.Trigger (
521 schedulerNames = [ "trigger-build-first" ],
523 updateSourceStamp=True
525 f.addStep(steps.Trigger (
526 schedulerNames = [ "trigger-build-rest" ],
528 updateSourceStamp=True
530 f.addStep(steps.Trigger (
531 schedulerNames = [ "trigger-build-analyses", "trigger-distcheck",
532 "trigger-build-docs" ],
534 updateSourceStamp=True
536 f.addStep(steps.Trigger (
537 schedulerNames = [ "trigger-rpm" ],
539 updateSourceStamp=True
542 c['builders'].append(
543 util.BuilderConfig(name="commit-builder",
544 slavenames=[w["bot"] for w in workers.values() if not w["vm"]],
548 ####### STATUS TARGETS
550 # 'status' is a list of Status Targets. The results of each build will be
551 # pushed to these targets. buildbot/status/*.py has a variety to choose from,
552 # including web pages, email senders, and IRC bots.
556 from buildbot.status import html
557 from buildbot.status.web import authz, auth
559 authz_cfg=authz.Authz(
560 # change any of these to True to enable; see the manual for more
562 #auth=auth.BasicAuth([("pyflakes","pyflakes")]),
563 auth=util.BasicAuth(users),
564 gracefulShutdown = False,
565 forceBuild = 'auth', # use this to test your slave once it is set up
566 forceAllBuilds = 'auth', # ..or this
567 pingBuilder = 'auth',
569 stopAllBuilds = 'auth',
570 cancelPendingBuild = 'auth',
571 cancelAllPendingBuilds = 'auth',
574 c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
576 c['status'].append(status.MailNotifier(
577 fromaddr="buildbot@quagga.net",
578 extraRecipients=["paul@jakma.org"],
579 sendToInterestedUsers=False,
582 c['status'].append (status.IRC(
583 "irc.freenode.net", "bb-quagga",
585 channels=[{"channel": "#quagga"}],
588 'successToFailure': 1,
589 'failureToSuccess': 1,
593 ####### PROJECT IDENTITY
595 # the 'title' string will appear at the top of this buildbot
596 # installation's html.WebStatus home page (linked to the
597 # 'titleURL') and is embedded in the title of the waterfall HTML page.
599 c['title'] = "Quagga"
600 c['titleURL'] = "https://www.quagga.net/"
602 # the 'buildbotURL' string should point to the location where the buildbot's
603 # internal web server (usually the html.WebStatus page) is visible. This
604 # typically uses the port number set in the Waterfall 'status' entry, but
605 # with an externally-visible host name which the buildbot cannot figure out
608 c['buildbotURL'] = "http://buildbot.quagga.net/"
613 # This specifies what database buildbot uses to store its state. You can leave
614 # this at its default for all but the largest installations.
615 'db_url' : "sqlite:///state.sqlite",
619 c['debugPassword'] = debugPassword