123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661 |
- # -*- python -*-
- # ex: set syntax=python:
- import json
- from buildbot.plugins import *
- from buildbot.plugins import buildslave, util
- # This is a sample buildmaster config file. It must be installed as
- # 'master.cfg' in your buildmaster's base directory.
- # This is the dictionary that the buildmaster pays attention to. We also use
- # a shorter alias to save typing.
- c = BuildmasterConfig = {}
- quaggagit = 'git://git.sv.gnu.org/quagga.git'
- # password defs
- execfile("pass.cfg")
- # filter a given 'workers' entry into a property list
- # suitable for public display
- def workers2publicprops (worker):
- publicprops = [ "os", "version", "vm", "pkg", "texi", "cc",
- "latent", "env" ]
- return { k:worker[k] for k in worker if k in publicprops }
- # get compiler names
- def compilers(workers):
- names = set ()
- for l in [ w["cc"] for w in workers.values ()]:
- for e in l:
- names |= { e["n"] }
- return names
- # bots with given compiler tag
- def ccbots (cc):
- return [ workers[kw]["bot"] for kw in workers
- if len([c["n"] for c in workers[kw]["cc"]
- if c["n"] is cc]) > 0]
- # vm: non-VM are assumed faster and used for initial build
- # pkg: rpm, sysv, dpkg - only do test rpm builds at moment
- # texi: True or "true" if we can use for doc building
- # cc: List of dicts of installed compilers, with:
- # { "n": <tag>, "v": <version>, "bin": <command>) }
- # tags: gcc, clang, sunpro, tcc
- # env: JSON dictionary of environment variables to be passed to shell
- # commands as a dictionary via json.load.
- # latent: VM spun up on demand via LatentSlave, uses "session" for
- # the libvirt URI.
- #
- # When latent is true:
- # session: libvirt URI to use for latent workers. Default will be set on
- # latent VMs if not specified.
- # hd_image: libvirt image to use
- workers = {
- "fedora-24": {
- "os": "Fedora",
- "version": "24",
- "vm": False,
- "pkg": "rpm",
- "texi": True,
- "cc": [ { "n": "gcc", "v": "6.3.1"},
- { "n": "clang", "v": "3.8.1"},
- { "n": "gcc", "v": "3.4.6", "bin": "gcc34"},
- ],
- },
- "fedora-26": {
- "os": "Fedora",
- "version": "26",
- "vm": False,
- "pkg": "rpm",
- "cc": [ { "n": "gcc", "v": "7.0.1" },
- { "n": "clang", "v": "3.9.0" },
- { "n": "gcc", "v": "3.4.6", "bin": "gcc34" },
- ],
- },
- "centos-7": {
- "os": "CentOS",
- "version": "7",
- "vm": False,
- "pkg": "rpm",
- "cc": [ { "n": "gcc", "v": "4.8.5"} ],
- },
- "ubuntu-16.10": {
- "os": "Ubuntu",
- "version": "16.10",
- "vm": False,
- "pkg": "dpkg",
- "cc": [
- { "n": "gcc", "v": "6.2.0"},
- { "n": "tcc", "v": "0.9.26"},
- ],
- },
- "debian-8": {
- "os": "Debian",
- "version": "8",
- "vm": True,
- "pkg": "dpkg",
- "latent": True,
- "cc": [ { "n": "gcc", "v": "4.9.2"} ],
- "hd_image": "/var/lib/libvirt/images/debian8.qcow2",
- },
- "debian-9": {
- "os": "Debian",
- "version": "9",
- "vm": True,
- "pkg": "dpkg",
- "cc": [ { "n": "gcc", "v": "6.3.0"} ],
- "latent": True,
- "hd_image": "/var/lib/libvirt/images/debian9.qcow2",
- },
- "freebsd-10": {
- "os": "FreeBSD",
- "version": "10",
- "vm": True,
- "pkg": "",
- "latent": True,
- "cc": [ { "n": "clang", "v": "3.4.1"} ],
- "hd_image": "/var/lib/libvirt/images/freebsd103.qcow2",
- },
- "freebsd-11": {
- "os": "FreeBSD",
- "version": "11",
- "vm": True,
- "pkg": "",
- "cc": [ {"n": "gcc", "v": "4.9.4"},
- { "n": "clang", "v": "3.8.0"},
- ],
- "latent": True,
- "hd_image": "/var/lib/libvirt/images/freebsd110.qcow2",
- },
- "openbsd-6": {
- "os": "OpenBSD",
- "version": "6.0",
- "vm": True,
- "pkg": "",
- "cc": [ { "n": "gcc", "v": "4.2.1"} ],
- "latent": True,
- "hd_image": "/var/lib/libvirt/images/openbsd-6.qcow2",
- "env": ' { "AUTOMAKE_VERSION": "1.15", "AUTOCONF_VERSION": "2.69" } ',
- },
- "oi-hipster": {
- "os": "OpenIndiana",
- "version": "hipster",
- "vm": True,
- "pkg": "sysv",
- "latent": True,
- "cc": [ { "n": "gcc", "v": "6.3.0"},
- { "n": "sunpro", "v": "12.0" },
- { "n": "gcc", "v": "4.4.4"}
- ],
- "hd_image": "/var/lib/libvirt/images/buildbot-oi-hipster.qcow2",
- },
- }
- # workers config preparation:
- # - add defaults for important fields not set
- # - add passwords
- def workers_prep (workers):
- for kw in workers:
- w = workers[kw]
- w["bot"] = "buildbot-" + kw
- # 'latent' must be set.
- if "latent" not in w:
- w["latent"] = False
- # set default libvirt session for latent bots
- if w["latent"] and ("session" not in w):
- w["session"] = 'qemu+ssh://buildbot@sagan.jakma.org/system'
- w["pass"] = workers_pass[kw]
- workers_prep (workers)
- analyses_builders = [ "clang-analyzer" ]
- osbuilders = ["build-" + kw for kw in workers]
- osfastbuilders = ["build-" + kw for kw in workers if workers[kw]["vm"] == False]
- osslowbuilders = ["build-" + kw for kw in workers if workers[kw]["vm"] == True]
- rpmbuilders = ["rpm-" + kw for kw in workers if workers[kw]["pkg"] == "rpm"]
- allbuilders = []
- allbuilders += osbuilders
- allbuilders += rpmbuilders
- allbuilders += analyses_builders
- allbuilders += ["commit-builder"]
- allbuilders += ["build-distcheck"]
- allbuilders += ["build-docs" ]
- # Force merging of requests.
- # c['mergeRequests'] = lambda *args, **kwargs: True
- ####### BUILDSLAVES
- c['slaves'] = []
- # The 'slaves' list defines the set of recognized buildslaves. Each element is
- # a BuildSlave object, specifying a unique slave name and password. The same
- # slave name and password must be configured on the slave.
- for w in (w for w in workers.values() if ("latent" not in w)
- or (w["latent"] == False)):
- c['slaves'].append(buildslave.BuildSlave(w["bot"], w["pass"],
- properties=workers2publicprops (w),
- ))
- for w in (w for w in workers.values()
- if ("latent" in w)
- and w["latent"]
- and "hd_image" in w):
- c['slaves'].append(buildslave.LibVirtSlave(
- w["bot"],
- w["pass"],
- util.Connection(w["session"]),
- w["hd_image"],
- properties=workers2publicprops (w),
- ))
- # 'protocols' contains information about protocols which master will use for
- # communicating with slaves.
- # You must define at least 'port' option that slaves could connect to your master
- # with this protocol.
- # 'port' must match the value configured into the buildslaves (with their
- # --master option)
- c['protocols'] = {'pb': {'port': 9989}}
- ####### CHANGESOURCES
- # the 'change_source' setting tells the buildmaster how it should find out
- # about source code changes. Here we point to the buildbot clone of pyflakes.
- c['change_source'] = []
- c['change_source'].append(changes.GitPoller(
- quaggagit,
- workdir='gitpoller-workdir',
- branches=True,
- # branches=['master','volatile/next'],
- pollinterval=300))
- ####### REVISION LINKS
- # associate changesouce repositories to URI templates for code view
- #
- c['revlink'] = util.RevlinkMatch([quaggagit + r"(.*)"],
- r"http://git.savannah.gnu.org/cgit/quagga.git/commit/?id=%s")
- ####### SCHEDULERS
- # Configure the Schedulers, which decide how to react to incoming changes.
- # We want a first line of 'quick' builds, which then trigger further builds.
- #
- # A control-flow builder, "commit-builder", used to sequence the 'real'
- # sets of builders, via Triggers.
- c['schedulers'] = []
- c['schedulers'].append(schedulers.SingleBranchScheduler(
- name="master-change",
- change_filter=util.ChangeFilter(branch='master'),
- treeStableTimer=10,
- builderNames=[ "commit-builder" ]))
- c['schedulers'].append(schedulers.SingleBranchScheduler(
- name="next-change",
- change_filter=util.ChangeFilter(
- branch='volatile/next'),
- treeStableTimer=10,
- builderNames=[ "commit-builder" ] ))
- # Initial build checks on faster, non-VM
- c['schedulers'].append(schedulers.Triggerable(
- name="trigger-build-first",
- builderNames=osfastbuilders))
- # Build using remaining builders, after firstbuilders.
- c['schedulers'].append(schedulers.Triggerable(
- name="trigger-build-rest",
- builderNames=osslowbuilders))
- # Analyses tools, e.g. CLang Analyzer scan-build
- c['schedulers'].append(schedulers.Triggerable(
- name="trigger-build-analyses",
- builderNames=analyses_builders))
- # Dist check
- c['schedulers'].append(schedulers.Triggerable(
- name="trigger-distcheck",
- builderNames=["build-distcheck"]))
- # RPM check and build
- c['schedulers'].append(schedulers.Triggerable(
- name="trigger-rpm",
- builderNames=rpmbuilders))
- # Doc build check (non-nightly, so no upload)
- c['schedulers'].append(schedulers.Triggerable(
- name="trigger-build-docs",
- builderNames=["build-docs"]))
- # Try and force schedulers
- c['schedulers'].append(schedulers.ForceScheduler(
- name="force",
- builderNames=allbuilders))
- c['schedulers'].append(schedulers.Try_Userpass(
- name="try",
- builderNames=osbuilders
- + rpmbuilders
- + ["build-distcheck",
- "clang-analyzer",
- "build-docs" ],
- userpass=users,
- port=8031))
- ## nightly docs build
- c['schedulers'].append(schedulers.Nightly(
- name="nightly-docs",
- branch="master",
- builderNames=[ "build-docs" ],
- hour=3,
- minute=0,
- onlyIfChanged=True,
- properties = { "nightly": True },
- ))
- ####### BUILDERS
- c['builders'] = []
- # The 'builders' list defines the Builders, which tell Buildbot how to perform a build:
- # what steps, and which slaves can execute them. Note that any particular build will
- # only take place on one slave.
- # Renderer to extract simple JSON dictionary object from the configuration
- # via the 'env' property, and return as a python dictionary, so it can
- # be passed to the 'env=' argument that some Steps allow.
- @util.renderer
- def get_config_env (props):
- jsonenv = props.getProperty('env')
- env = None
- if jsonenv:
- env = json.loads (jsonenv)
- return env
- def makecmd (target):
- if isinstance(target,basestring):
- return [ "make", "-j", "2", target ]
- return [ "make", "-j", "2" ] + target
- step_git = steps.Git(repourl=quaggagit, mode='incremental')
- step_autoconf = steps.ShellCommand(command=["./update-autotools"],
- description="generating autoconf",
- descriptionDone="autoconf",
- haltOnFailure=True,
- env=get_config_env)
- git_and_autoconf = [
- step_git, step_autoconf,
- ]
- step_configure = steps.Configure(command="../build/configure")
- step_clean = steps.ShellCommand(command=makecmd("clean"),
- description="cleaning",
- descriptionDone="make clean")
- configure_and_clean = [ step_configure, step_clean ]
- common_setup = git_and_autoconf + configure_and_clean
- ### Default 'check' build, builder instantiated for each OS
- factory = util.BuildFactory()
- factory.addSteps(common_setup)
- factory.addStep(steps.Compile(command=makecmd("all")))
- factory.addStep(steps.ShellCommand(command=makecmd("check"),
- description="checking",
- descriptionDone="make check"))
- # create builder for every OS, for every buildbot
- # XXX: at moment this assumes 1:1 OS<->bot
- for kw in workers:
- c['builders'].append(util.BuilderConfig(
- name="build-" + kw,
- slavenames=workers[kw]["bot"],
- factory=factory))
- ### distcheck Builder, executed on any available bot
- factory = util.BuildFactory()
- factory.addSteps(common_setup)
- factory.addStep(steps.ShellCommand(command=makecmd("distcheck"),
- description="run make distcheck",
- descriptionDone="make distcheck"))
- c['builders'].append(
- util.BuilderConfig(name="build-distcheck",
- slavenames=list(w["bot"] for w in workers.values()),
- factory=factory,
- ))
- ### LLVM clang-analyzer build, executed on any available non-VM bot
- f = util.BuildFactory()
- f.addSteps(common_setup)
- f.addStep(steps.SetProperty(property="clang-id",
- value=util.Interpolate("%(prop:commit-description)s-%(prop:buildnumber)s")))
- f.addStep(steps.SetProperty(property="clang-output-dir",
- value=util.Interpolate("../CLANG-%(prop:clang-id)s")))
- f.addStep(steps.SetProperty(property="clang-uri",
- value=util.Interpolate("/clang-analyzer/%(prop:clang-id)s")))
- # relative to buildbot master working directory
- f.addStep(steps.SetProperty(property="clang-upload-dir",
- value=util.Interpolate("public_html/clang-analyzer/%(prop:clang-id)s")))
- f.addStep(steps.Compile(command=["scan-build",
- "-analyze-headers",
- "-o",
- util.Interpolate("%(prop:clang-output-dir)s"),
- "make", "all"]))
- f.addStep(steps.DirectoryUpload(
- slavesrc=util.Interpolate("%(prop:clang-output-dir)s"),
- masterdest = util.Interpolate("%(prop:clang-upload-dir)s"),
- compress = 'bz2',
- name = "clang report",
- url = util.Interpolate("%(prop:clang-uri)s"),
- ))
- f.addStep(steps.RemoveDirectory(
- dir=util.Interpolate("%(prop:clang-output-dir)s")
- ))
- c['builders'].append(
- util.BuilderConfig(name="clang-analyzer",
- slavenames=ccbots ("clang"),
- factory=f))
- ### RPM: check and build
- f = util.BuildFactory ()
- # check out the source
- f.addStep(steps.Git(repourl=quaggagit, mode='full'))
- f.addStep(step_autoconf)
- f.addStep(step_configure)
- f.addStep(steps.ShellCommand(command=makecmd("dist"),
- description="run make dist",
- descriptionDone="make dist"))
- # not imported somehow
- #f.addStep(steps.RpmLint(fileloc="redhat/quagga.spec"))
- f.addStep(steps.ShellCommand(command=["rpmlint", "-i", "redhat/quagga.spec"],
- description="run rpmlint",
- descriptionDone="rpmlint"))
- f.addStep(steps.RpmBuild(specfile="redhat/quagga.spec"))
- # rpmdir=util.Interpolate("%(prop:builddir)s/rpm")))
- # XXX: assuming 1:1 OS:buildbot mapping
- for kw in (kw for kw in workers if workers[kw]["pkg"] == "rpm"):
- c['builders'].append(
- util.BuilderConfig(name="rpm-" + kw,
- slavenames="buildbot-" + kw,
- factory=f
- )
- )
- ### Build documentation
- def build_is_nightly (step):
- n = step.getProperty("nightly")
- if n == True or n == "True" or n == "true":
- return True
- return False
- f = util.BuildFactory ()
- f.addStep(steps.Git(repourl=quaggagit, mode='full'))
- f.addStep(step_autoconf)
- f.addStep(steps.Configure(command=["../build/configure"],
- workdir="docs"))
- f.addStep(steps.ShellCommand(command=["make", "V=99", "quagga.html"],
- description="making split HTML doc",
- descriptionDone="docs: split HTML",
- workdir="docs/doc",
- haltOnFailure=True,
- ))
- #f.addStep(steps.FileUpload(
- # slavesrc="build/doc/fig-normal-processing.png",
- # masterdest = "public_html/docs/nightly/quagga/",
- # name = "Upload Fig 1",
- # doStepIf=build_is_nightly,
- #))
- #f.addStep(steps.FileUpload(
- # slavesrc="build/doc/fig-rs-processing.png",
- # masterdest = "public_html/docs/nightly/quagga/",
- # name = "Upload Fig 2",
- # doStepIf=build_is_nightly,
- #))
- f.addStep(steps.MultipleFileUpload(
- slavesrcs=[ "doc/fig-rs-processing.png",
- "doc/fig-normal-processing.png" ],
- masterdest = "public_html/docs/nightly/quagga/",
- name = "Upload Figures",
- doStepIf=build_is_nightly,
- ))
- f.addStep(steps.DirectoryUpload(
- slavesrc="quagga.html",
- masterdest = "public_html/docs/nightly/quagga",
- compress = 'bz2',
- name = "Upload split HTML",
- url = "/docs/nightly/quagga/index.html",
- workdir="docs/doc",
- doStepIf=build_is_nightly,
- ))
- f.addStep(steps.RemoveDirectory(
- dir="docs/doc/quagga.html",
- ))
- f.addStep(steps.ShellCommand(command=["make", "V=99",
- "MAKEINFOFLAGS=--no-split",
- "quagga.html"],
- description="making one-page HTML doc",
- descriptionDone="docs: one-page HTML",
- workdir="docs/doc",
- haltOnFailure=True
- ))
- f.addStep(steps.FileUpload(
- slavesrc="quagga.html",
- masterdest = "public_html/docs/nightly/quagga/quagga.html",
- name = "Upload single HTML",
- url = "/docs/nightly/quagga/quagga.html",
- workdir="docs/doc",
- doStepIf=build_is_nightly,
- ))
- f.addStep(steps.ShellCommand(command=["make", "V=99", "quagga.pdf"],
- description="making PDF docs",
- descriptionDone="docs: PDF",
- workdir="docs/doc"
- ))
- f.addStep(steps.FileUpload(
- slavesrc="quagga.pdf",
- masterdest = "public_html/docs/nightly/quagga/quagga.pdf",
- name = "Upload PDF",
- url = "/docs/nightly/quagga/quagga.pdf",
- workdir="docs/doc",
- doStepIf=build_is_nightly,
- ))
- c['builders'].append(
- util.BuilderConfig(name="build-docs",
- slavenames=[w["bot"] for w in workers.values()
- if "texi" in w and w["texi"] == True ],
- factory=f
- ))
- ### Co-ordination builds used to sequence parallel builds via Triggerable
- # to understand this you have to read this list and the Triggered schedulers
- # to see what sets of builds are being sequenced. Bit clunky, but Buildbot
- # doesn't have a way to just specify a pipeline of groups of builders more
- # cleanly.
- f = util.BuildFactory()
- f.addStep(steps.Trigger (
- schedulerNames = [ "trigger-build-first" ],
- waitForFinish=True,
- updateSourceStamp=True
- ))
- f.addStep(steps.Trigger (
- schedulerNames = [ "trigger-build-rest" ],
- waitForFinish=True,
- updateSourceStamp=True
- ))
- f.addStep(steps.Trigger (
- schedulerNames = [ "trigger-build-analyses", "trigger-distcheck",
- "trigger-build-docs" ],
- waitForFinish=True,
- updateSourceStamp=True
- ))
- f.addStep(steps.Trigger (
- schedulerNames = [ "trigger-rpm" ],
- waitForFinish=True,
- updateSourceStamp=True
- ))
- c['builders'].append(
- util.BuilderConfig(name="commit-builder",
- slavenames=[w["bot"] for w in workers.values() if not w["vm"]],
- factory=f)
- )
- ####### STATUS TARGETS
- # 'status' is a list of Status Targets. The results of each build will be
- # pushed to these targets. buildbot/status/*.py has a variety to choose from,
- # including web pages, email senders, and IRC bots.
- c['status'] = []
- from buildbot.status import html
- from buildbot.status.web import authz, auth
- authz_cfg=authz.Authz(
- # change any of these to True to enable; see the manual for more
- # options
- #auth=auth.BasicAuth([("pyflakes","pyflakes")]),
- auth=util.BasicAuth(users),
- gracefulShutdown = False,
- forceBuild = 'auth', # use this to test your slave once it is set up
- forceAllBuilds = 'auth', # ..or this
- pingBuilder = 'auth',
- stopBuild = 'auth',
- stopAllBuilds = 'auth',
- cancelPendingBuild = 'auth',
- cancelAllPendingBuilds = 'auth',
- pauseSlave = 'auth',
- )
- c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
- c['status'].append(status.MailNotifier(
- fromaddr="buildbot@quagga.net",
- extraRecipients=["paul@jakma.org"],
- sendToInterestedUsers=False,
- ))
- c['status'].append (status.IRC(
- "irc.freenode.net", "bb-quagga",
- useColors=True,
- channels=[{"channel": "#quagga"}],
- notify_events={
- 'exception': 1,
- 'successToFailure': 1,
- 'failureToSuccess': 1,
- },
- ))
- ####### PROJECT IDENTITY
- # the 'title' string will appear at the top of this buildbot
- # installation's html.WebStatus home page (linked to the
- # 'titleURL') and is embedded in the title of the waterfall HTML page.
- c['title'] = "Quagga"
- c['titleURL'] = "https://www.quagga.net/"
- # the 'buildbotURL' string should point to the location where the buildbot's
- # internal web server (usually the html.WebStatus page) is visible. This
- # typically uses the port number set in the Waterfall 'status' entry, but
- # with an externally-visible host name which the buildbot cannot figure out
- # without some help.
- c['buildbotURL'] = "http://buildbot.quagga.net/"
- ####### DB URL
- c['db'] = {
- # This specifies what database buildbot uses to store its state. You can leave
- # this at its default for all but the largest installations.
- 'db_url' : "sqlite:///state.sqlite",
- }
- #### debug
- c['debugPassword'] = debugPassword
|