Buildbot runvm

One type of build we do in BuildBot is to build and test MariaDB binary packages for the platforms we release on. We build and test packages for Debian (4 and 5), Ubuntu (8.04 to 10.04), Centos 5, and generic Linux; amd64 and i386 architectures. This testing is done with virtual machines run in KVM.

To better control the startup and shutdown of the virtual machines we use a small wrapper around KVM we developed called runvm. The purpose of this tool is to make it easy to boot up a virtual machine, run some build commands inside it, and shut it down cleanly.

This wrapper encapsulates the steps needed to boot up a virtual machine, run a series of commands inside it, and shut it down gracefully afterwards. Some special care is taken in the script to ensure that the virtual machine is always shut down after use (gracefully if possible), even in case of various failures or the loss of the parent process or controlling TTY. And if a conflicting virtual machine somehow manages to escape shutdown, runvm automatically attempts to terminate it before starting a new one. This extra robustness is important for fully automated testing as in our Buildbot setup, to ensure that the system can run unattended for longer periods of time.

Essentially, instead of a normal Buildbot session which would do something like this on the slave:

./configure && make

We instead use runvm to do the same inside a virtual machine running as a KVM guest with the build slave as host:

runvm image.qcow2 "./configure" "make"

See the runvm Usage Examples or runvm --help sections below for more detailed examples, but this is the basic idea.

runvm Usage Examples

Usage Example One

Here is an example command you could use to run a build inside a virtual machine using runvm:

runvm --port=2222 ubuntu-hardy-i386.qcow2 \
  "= scp -P 2222 mariadb-5.1.41-rc.tar.gz localhost:" \
  "tar zxf mariadb-5.1.41-rc.tar.gz" \
  "cd mariadb-5.1.41-rc && ./configure" \
  "cd mariadb-5.1.41-rc && make"

In this example, ubuntu-hardy-amd64.qcow2 is a KVM image already installed with compilers and set up for password-less ssh access (using public key authentication). Port 2222 on the host side is forwarded to the ssh service (port 22) on the guest side (so by specifying different --port options it is easy to run multiple runvm invocations in parallel; in our Buildbot setup we run 3 builds in parallel this way).

Note the use of the scp command, prefixed with an equals sign "=" Commands prefixed in this way are run on the host side rather than the guest side; this is a convenient way to copy data in or results out of the virtual machine while the runvm session is running.

Using runvm in this way we are able to easily and flexibly manage a large number of virtual machines for automated builds with very little overhead and complexity. In fact we have around 70 distinct virtual machines! The only resource they take is a little disk space (around 37 GByte). And the virtual machines images are also simple to set up, requiring only a minimal install; no need to set up networking bridges or IP addresses, or to install a Buildbot client. All the complex logic runs on the host system, which only needs to be installed once.

By keeping the virtual images simple, builds and tests run in a minimal environment, which is useful to detect any missing dependencies or other problems that do not show themselves on normal developer machines with a full desktop install (we even do install testing on a separate virtual machine from the one used to build, with compilers etc. not installed on the one used to test installation).

Usage Example Two

A further refinement of example one (above) is to create a new temporary virtual machine image before each step as a copy of a reference image, run the build, and throw away the temporary image after the build. This avoids any possibility of a previous build influencing a following build in any way (and thus also simplifies the build setup, as we can install stuff freely without any need to do cleanup). It also avoids having to fix a broken image, like needing to manually run fsck after a crash or similar issue. We use this technique for most of our binary package builds in Buildbot.

To use this copy-and-discard technique with runvm, the --base-image option is useful:

This will run the build in a temporary copy tmp.qcow2 of the reference image ubuntu-hardy-i386.qcow2, without modifying the reference image in any way. This uses the copy-on-write feature of the qcow2 image format (see qemu-img(1)), so it even takes only very little time (fraction of a second) and minimal space (only changed blocks are written to the new image).

Additional Usage Examples

The above two examples show basically how the package testing in our Buildbot setup is done. There are some further details of course, like more options for the build commmands and extra care to get logfiles out to debug problems; the full details are available in our Buildbot configuration file. But the basic principle is just a number of runvm commands like the examples above.

Getting runvm

The runvm tool is available under GPL on Lauchpad in the project Tools for MariaDB. In the bzr repository it is found as buildbot/runvm. If someone finds it useful or has suggestions for improvements, please drop us a line on the maria-developers mailing list.

runvm --help

Since it might be useful, here is the output from runvm --help (check the latest version of the tool for up-to-date output):

This page is based on a blog post by Kristian Nielsen, the primary developer of runvm.

This page is licensed: CC BY-SA / Gnu FDL

Last updated

Was this helpful?