The
BuildBot is a system to automate the compile/test cycle required
to validate code changes. Here we are going setup buildbot master and slaves
with the following requirements:
- We have serveral projects: project1, project2, project3
- These projects live
under Mercurial (e.g. hosted at bitbucket.org) with base url
https://scm.dev.local/hg/ followed by project name
(e.g. https://scm.dev.local/hg/project1)
- We should be able run at least 2 builds in parallel (this is where we
can use buildbot slaves: linux-slave1 and linux-slave2)
- The build should trigger automatically if the changes detected every 30
minutes during working day.
- The builder should execute make all that ultimatelly does
everything we need to verify integrity.
- The builder should be checked agains certain python versions: 2.4, 2.5,
2.6, 2.7 and 3.2
Install Buildbot Packages
Installation in debian is pretty straight forward:
apt-get -y install buildbot subversion mercurial git make
This installs both master and slave. By default debian installer places buildbot working
directories to
/var/lib/buildbot. This directory includes 2 others:
masters, slaves. So basic installation supports multiple masters and slaves.
Create Master
Let call our master buildbot instance
master1 so in future in case we need more
(that happens) we can easily add seconds, etc.
cd /var/lib/buildbot/masters
buildbot create-master --relocatable --log-size=512000 \
--log-count=3 master1
cp master1/master.cfg.sample master1/master.cfg
chown -R buildbot:buildbot master1/
This command creates a buildmaster working directory and
buildbot.tac file. The
master will live in
master1. At runtime, the
master will read a configuration file (named
master.cfg by default) in its basedir.
Configure Buildbot Daemon
The Debian installer for buildbot comes with configuration file (
/etc/default/buildmaster) that let you auto start build masters.
MASTER_RUNNER=/usr/bin/buildbot
MASTER_ENABLED[1]=1
MASTER_NAME[1]="buildmaster1"
MASTER_USER[1]="buildbot"
MASTER_BASEDIR[1]="/var/lib/buildbot/masters/master1"
MASTER_OPTIONS[1]=""
MASTER_PREFIXCMD[1]=""
By this point we should be able to start buildbot with default configuration.
/etc/init.d/buildmaster start
Look at
master1/twisted.log for errors:
tail -f master1/twisted.log
Let verify it is up and running (web front end listen on port 8010, slaves enter point is 9989):
netstat -tunlp
tcp 0 0 0.0.0.0:9989 0.0.0.0:* LISTEN 3557/python
tcp 0 0 0.0.0.0:8010 0.0.0.0:* LISTEN 3557/python
Open browser to http://localhost:8010/ (change localhost to the buildbot server name)
to see buildbot welcome page.
Master Configuration
Open
master.cfg (located at /var/lib/buildbot/masters/master1) and define
our pre-requirements:
c = BuildmasterConfig = {}
source_root = 'https://scm.dev.local/hg/'
source_user = ''
projects = ['project1', 'project2', 'project3']
python_versions = ['2.4', '2.5', '2.6', '2.7', '3.2']
passwd = {
'source': '',
'linux-slave1': '',
'linux-slave2': ''
}
from buildbot.locks import MasterLock
from buildbot.locks import SlaveLock
source_lock = MasterLock('source')
build_lock = SlaveLock('build',
maxCount = 1,
maxCountForSlave = {
'linux-slave1': 2,
'linux-slave2': 2
})
Consider read
strong password generator.
Build Slaves
Build slaves represent a standard, manually started machine that will try to connect to the buildbot master as a slave (file
master.cfg):
from buildbot.buildslave import BuildSlave
c['slaves'] = [
BuildSlave('linux-slave1', passwd['linux-slave1']),
BuildSlave('linux-slave2', passwd['linux-slave2'])
]
c['slavePortnum'] = 9989
Change Sources
The sources are checked every 30 mins, with 1 minute shift. This let lower source control
workload in case you have many projects. Here is an example for svn:
from buildbot.changes.svnpoller import SVNPoller
from buildbot.changes.svnpoller import split_file_alwaystrunk
c['change_source'] = []
c['change_source'].extend(SVNPoller(
svnurl=source_root + name,
split_file=split_file_alwaystrunk,
svnuser=source_user,
svnpasswd=passwd['source'],
project=name,
pollinterval=1800 + i*60
) for i, name in enumerate(projects))
Schedulers
Schedulers are responsible for initiating builds on builders. Several schedulers perform filtering on an incoming set of changes, here we are filtering on project name.
from buildbot.changes.filter import ChangeFilter
from buildbot.schedulers.basic import SingleBranchScheduler
c['schedulers'] = []
c['schedulers'].extend([
SingleBranchScheduler(
name=name,
change_filter=ChangeFilter(
branch=None,
project=name,
),
treeStableTimer=5 * 60,
builderNames=["%s-%s" % (name, v) for v in python_versions]
) for name in projects
])
from buildbot.schedulers.forcesched import ForceScheduler
c['schedulers'].extend([
ForceScheduler(
name=name + '-forced',
builderNames=[name])
for name in projects
])
Builders
A BuildFactory defines the steps that every build will follow (sort of script).
from buildbot.config import BuilderConfig
from buildbot.process.factory import BuildFactory
from buildbot.steps.shell import ShellCommand
from buildbot.steps.source.mercurial import Mercurial
c['builders'] = []
c['builders'].extend([
BuilderConfig(
name="%s-%s" % (name, v),
slavenames=["linux-slave1", "linux-slave2"],
factory=BuildFactory([
Mercurial(
repourl=source_root + name,
branchType='inrepo',
mode='full',
method='fresh',
haltOnFailure=True,
locks=[source_lock.access('exclusive')]
),
ShellCommand(
command=["make", "all"],
haltOnFailure=True,
locks=[build_lock.access('counting')]
),
ShellCommand(
command=["make", "clean"],
alwaysRun=True
)
]))
for name in projects
for v in python_versions
])
Status Targets
The Buildmaster has a variety of ways to present build status to various users. Each such delivery method is a status target. Here we define web status and notification via email.
c['status'] = []
from buildbot.status import html
from buildbot.status.web import authz
authz_cfg=authz.Authz(
gracefulShutdown = False,
forceBuild = True,
forceAllBuilds = False,
pingBuilder = False,
stopBuild = False,
stopAllBuilds = False,
cancelPendingBuild = False,
)
c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
from buildbot.status.mail import MailNotifier
c['status'].append(MailNotifier(
fromaddr="bb1@dev.local",
extraRecipients=["buildbot@dev.local"],
sendToInterestedUsers=False,
mode='problem'
))
Create Slave
The buildslaves are typically run on a variety of separate machines, at least one per platform of interest. These machines connect to the buildmaster over a TCP connection to a publically-visible port. As a result, the buildslaves can live behind a NAT box or similar firewalls, as long as they can get to buildmaster. Here the build master is located at localhost.
buildslave create-slave --umask=027 --relocatable \
--keepalive=120 --maxdelay=30 --log-size=512000 \
--log-count=3 linux-slave1 localhost linux-slave1 \
<password>
chown -R buildbot:buildbot linux-slave1/
Repeat above but for linux-slave2.
Configure Buildbot Daemon
The Debian installer for buildbot comes with configuration file (
/etc/default/buildslave) that let you auto start build slaves.
SLAVE_RUNNER=/usr/bin/buildslave
SLAVE_ENABLED[1]=1
SLAVE_NAME[1]="linux-slave1"
SLAVE_USER[1]="buildbot"
SLAVE_BASEDIR[1]="/var/lib/buildbot/slaves/linux-slave1"
SLAVE_OPTIONS[1]=""
SLAVE_PREFIXCMD[1]=""
SLAVE_ENABLED[2]=1
SLAVE_NAME[2]="linux-slave2"
SLAVE_USER[2]="buildbot"
SLAVE_BASEDIR[2]="/var/lib/buildbot/slaves/linux-slave2"
SLAVE_OPTIONS[2]=""
SLAVE_PREFIXCMD[2]=""
You should be able to start buildbot slaves.
# /etc/init.d/buildslave start
Restarting buildslave "linux-slave1".
Restarting buildslave "linux-slave2".
Look at linux-slave1/twisted.log for errors:
tail -f linux-slave1/twisted.log
Open browser to http://localhost:8010/ (change localhost to the buildbot server name) to trigger your build.
I have few questions:
ReplyDelete1. Are these slaves(linux-slave1, linux-slave2) setup in one machine or two machines.
2. Are these slaves(linux-slave1, linux-slave2) run in parallal, if parallael but i want to run one by one ,wait for completed 1st slave and send mail and then start 2nd one slave(like queue concept) is it possible ?.
3. what about 3 projects(project1, project2, project3), which machine will run these projects.
please can you tell me working procedure clearly , i am confusing,
my mail id : rathnamachary@gmail.com
1. yes
Delete2. yes
3. any available
Thank you Andriy. but still confusing.
ReplyDeletePlease explain detail working procedure.
I would suggest try instead... please note that blog post starts from several points we are trying to achieve... which should give you an idea.
DeleteThe buildbot online documentation has quite a lot of details indeed.
Actually I have setup many machine for each slave by doing like this more machines are getting for each slave, to overcome i want to do queue concept, in that whichever machine are free. we will run on that machine.
ReplyDeleteso here my question is how to give this command for every different salve "buildslave create-slave buildslave localhost:9989 slave1 password_slave1".
basically buildbot attempts to run in parallel as much as possible unless you synchronize critical parts and/or serialize execution with locks.
DeleteFor above buildbot pls help me how to do two slaves serialize by lock, if you don't mind pls send code with lock,for running one slave after one slave
DeleteHi andriy,
ReplyDeletefor 1st comment both slave1,slave2 setup in one machine or two machine?and are both running in parallal or one by one?
Pls suggest me.
If two slaves are running on a single machine they still run in parallel.
Delete