Buildbot
Buildbot is an open-source framework for automating software build, test, and release processes. At its core, Buildbot is a job scheduling system: it queues jobs, executes the jobs when the required resources are available, and reports the results. It can be easily installed and serve as a continuous integration platform to be used together with a variety of version control solutions, including gitea.
In this tutorial, we will first follow along with the official installation manual and set up a hello world
-system and will extend the standard installation of Buildbot with a gitea-Plugin.
Note
For this guide you should be familiar with the basic concepts of
ssh port forwarding
Folder/File Permissions
Note
Recommended reading to follow along and go beyond this guide:
Buildbot in 5 Minutes User Tutorial (warning: based on an older version of buildbot! Code examples should be taken with a grain of salt. It explains the mechanics quite nicely, though)
License
Buildbot is released under the GNU General Public License v2.0.
Installation
You can install the BuildBot bundle using pip3.8
:
[isabell@stardust ~]$ pip3.8 install buildbot[bundle] --user
If you want e-mail notifications from BuildBot to work later on, you will also need to install pyopenssl
and service-identity
:
[isabell@stardust ~]$ pip3.8 install pyopenssl service-identity --user
Configuration of the master
Prepare folder
Prepare the BuildBot folders. We are going to use one folder for all of our masters and another for all the workers:
[isabell@stardust ~]$ mkdir ~/bb-master
Initialize
Create the first master:
[isabell@stardust ~]$ cd ~/bb-master
[isabell@stardust bb-master]$ buildbot create-master master
This will create the directory bb-master/master
, set up a sqlite database and deposit a sample configuration.
Add default configuration
Move the sample configuration:
[isabell@stardust bb-master]$ mv master/master.cfg.sample master/master.cfg
You should read through the rest of the options, but leave things to their default values for now.
Note
This step will leave the hello world
demo that Buildbot automatically enters into the configuration file intact. In combination with a worker, the example builder will clone the buildbot/hello-world
github repository and run the test_hello.py
script from that repository. More information on how to configure builders is available in the official Buildbot manual.
Test the setup
That’s it! Our master should be able to start now:
Note
We are starting buildbot with the --nodaemon
option, forcing it to start in the foreground. In order to continue with the guide, you’ll need to terminate it using Ctrl+C after it starts successfully.
[isabell@stardust bb-master] buildbot start --nodaemon master
Following twistd.log until startup finished..
The buildmaster appears to have (re)started correctly.
If you don’t get the same output, check the log at master/twistd.log
for errors.
Service
In this step, we will set up supervisord to take control of our Buildbot master.
Create the file ~/etc/services.d/buildbot-master.ini
with the following content:
[program:buildbot-master]
command=buildbot start --nodaemon %(ENV_HOME)s/bb-master/master
After creating the configuration, tell supervisord to refresh its configuration and start the service:
[isabell@stardust ~]$ supervisorctl reread
SERVICE: available
[isabell@stardust ~]$ supervisorctl update
SERVICE: added process group
[isabell@stardust ~]$ supervisorctl status
SERVICE RUNNING pid 26020, uptime 0:03:14
[isabell@stardust ~]$
If it does not show RUNNING
as a status, check the twistd.log
for errors again.
Configuration of the worker
Now that the master is done, let’s create the first worker!
Prepare folder
Prepare the BuildBot folders. We are going to use one folder for all of our masters and another for all the workers:
[isabell@stardust ~]$ mkdir ~/bb-workers
Initialize
Change directories and create the worker:
[isabell@stardust bb-master] cd ~/bb-workers
[isabell@stardust bb-workers] buildbot-worker create-worker example-worker localhost:8010 example-worker pass
This will create the directory example-worker
and deposit the worker configuration file (example-worker/buildbot.tac
) as well as some additional files with meta information about this worker. The creation tool will give you some output and instructions on what to edit afterwards - you should definitely take a look at the mentioned files and enter your information.
Service
The worker also requires its own process for which we will use supervisord again.
Create the file ~/etc/services.d/buildbot-worker.ini
with the following content:
[program:buildbot-worker]
command=buildbot-worker start --nodaemon %(ENV_HOME)s/bb-workers/example-worker
After creating the configuration, tell supervisord to refresh its configuration and start the service:
[isabell@stardust ~]$ supervisorctl reread
SERVICE: available
[isabell@stardust ~]$ supervisorctl update
SERVICE: added process group
[isabell@stardust ~]$ supervisorctl status
SERVICE RUNNING pid 26020, uptime 0:03:14
[isabell@stardust ~]$
If it’s not in state RUNNING
, check the twistd.log
for errors again.
Securing the BuildBot Installation
Now that we have a working BuildBot master and worker, it’s time to take a look at securing the webinterface. BuildBot was developed under the assumption that access to the webinterface would only be allowed from a private network and not the world wide web - so, by default, there is no permission or authentication management configured. Even if you don’t plan on exposing the webinterface to the world, you should probably take a look at the www authentication section in the official manual and use one of the available modules as otherwise all users on the same Uberspace host as you would be able to access your Buildbot freely.
Using SSH Tunnel to keep BuildBot private
A better way to keep the webinterface secure is to never expose it to the public in the first place and use an SSH tunnel instead. This limits access to users who can connect to your Uberspace account via SSH.
You can either do this via the ssh
command like so:
[isabell@desktop ~] ssh -L 9989:localhost:9989 isabell@stardust.uberspace.de
Or you can adjust your local ~/.ssh/config
file by adding the LocalForward
option to the Uberspace host. The host entry would look something like this:
Host stardust
HostName stardust.uberspace.de
User isabell
LocalForward 9989 localhost:9989
You can then connect via
[isabell@desktop ~] ssh stardust
Now that the connection is established with port forwarding, you can call up http://localhost:9989/
in your browser to access the Buildbot webinterface! We have now basically completed the ‘First Run’ tutorial of the official manual and you should be able to force an execution of the runtests
builder.
Restricting SSH access to port forwarding only
If you don’t want to give everyone who needs access to the BuildBot webinterface full shell access to your Uberspace account, there is support for that as well! You can simply prepend their public key in the ~/.ssh/authorized_keys
file with the following:
command="echo 'This account can only be used for port forwarding to buildbot'",no-agent-forwarding,no-X11-forwarding,permitopen="localhost:9989" ssh-rsa ...
This will allow the respective users to connect to the tunnel like this (the -N
prevents execution of remote commands):
[isabell@desktop ~] ssh -N -L 9989:localhost:9989 isabell@stardust.uberspace.de
After which they will also be able to open http://localhost:9989/
, but won’t have an open shell to which they could issue other commands or forward to any other port than 9989
. You can also verify that it’s working by connecting without the -N
parameter - that should show you the error message configured in command
beforehand.
Integration with gitea
One useful thing to do with BuildBot is to use it as a continuous integration runner. Since gitea also works on Uberspace but doesn’t support ‘direct’ CI/CD integration like github and gitlab, we can use gitea’s web hooks to trigger our BuildBot installation to do something.
Install
For this, we will need to install the buildbot_gitea
plugin for BuildBot, developed by Marvin Pohl of lab132. We will install directly from their git repository using pip:
[isabell@stardust ~] pip3.8 install git+https://github.com/lab132/buildbot-gitea.git --user
Configure
Now that we installed the buildbot_gitea
plugin, we can use gitea
as a dialect for accepting incoming webhook messages via http://localhost:9989/change_hook/gitea
. For this, return to editing the master.cfg
from earlier. There, add the following to enable incoming webhook messages from gitea:
c['www']['change_hook_dialects'] = {
'gitea': {
'secret': 'SomeSecretPassPhraseToAuthenticateGitea',
}}
That’s it! Restart your BuildBot master via supervisorctl restart buildbot-master
and continue by adding the webhook to the desired gitea repository!
Link to gitea
Adding the webhook to a repository works pretty much as expected. Go to the desired repository, click on Settings > Webhooks > Add Webhook > Gitea
and enter http://localhost:9989/change_hook/gitea
as the URL and whatever you entered as a secret as secret. This of course assumes that you installed gitea on the same Uberspace host as BuildBot.
Note
If gitea and Buildbot are installed on different hosts, you will either need to set up an SSH tunnel between them or expose the Buildbot webinterface to the public. You may refer to the section on securing the Buildbot installation as a starting point. autossh might also be interesting to you.
And that’s it! Now, push-events in your gitea repository will trigger the runtests-builder from the example setup.
Finishing Installation
Congratulations! You now have an operational BuildBot installation on your Uberspace! Continue with the recommended reading from the beginning to learn more about the architecture of BuildBot and how to set up your own repositories and builders.
Written by: Thomas Hoffmann <uberlab@emptyweb.de>