1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
#! /usr/bin/env python
"""
This script can be used to generate an Ubuntu VM that is suitable for use by the libvirt backend of buildbot.
It creates a buildbot slave and then changes the buildbot.tac to get its username from the hostname. The hostname is set by
changing the DHCP script.
See network.xml for how to map a MAC address to an IP address and a hostname. You can load that configuration on to your master by running::
virsh net-define network.xml
Note that the VM's also need their MAC address set, and configuring to use the new network, or this won't work..
"""
import os, platform, tempfile
if platform.machine() == "x86_64":
arch = "amd64"
else:
arch = "i386"
postboot = """\
#!/bin/sh
chroot $1 update-rc.d -f buildbot remove
chroot $1 addgroup --system minion
chroot $1 adduser --system --home /var/local/buildbot --shell /bin/bash --ingroup zope --disabled-password --disabled-login minion
mkdir -p $1/var/local/buildbot
chroot $1 chown minion: /var/local/buildbot
chroot $1 sudo -u minion /usr/bin/buildbot create-slave /var/local/buildbot %(master_host)s:%(master_port)s %(slave)s %(slave_password)s
cat > $1/etc/default/buildbot << HERE
BB_NUMBER[0]=0
BB_NAME[0]="minion"
BB_USER[0]="minion"
BB_BASEDIR[0]="/var/local/buildbot"
BB_OPTIONS[0]=""
BB_PREFIXCMD[0]=""
HERE
cat > $1/var/local/buildbot/buildbot.tac << HERE
from twisted.application import service
from buildbot.slave.bot import BuildSlave
import socket
basedir = r'/var/local/buildbot'
buildmaster_host = '%(master_host)s'
port = %(master_port)s
slavename = socket.gethostname()
passwd = "%(slave_password)s"
keepalive = 600
usepty = 0
umask = None
maxdelay = 300
rotateLength = 1000000
maxRotatedFiles = None
application = service.Application('buildslave')
s = BuildSlave(buildmaster_host, port, slavename, passwd, basedir,
keepalive, usepty, umask=umask, maxdelay=maxdelay)
s.setServiceParent(application)
HERE
cat > $1/etc/dhcp3/dhclient-exit-hooks.d/update-hostname << HERE
if [ x\$reason != xBOUND ] && [ x\$reason != xREBIND ] && [ x\$reason != xREBOOT ]; then exit; fi
echo Updating hostname: \$new_host_name
hostname \$new_host_name
echo Starting buildbot
/etc/init.d/buildbot stop || true
/etc/init.d/buildbot start
HERE
cat > $1/etc/udev/rules.d/virtio.rules << HERE
KERNEL=="vda*", SYMLINK+="sda%%n"
HERE
"""
class VMBuilder:
""" Class that executes ubuntu-vm-builder with appropriate options """
postboot = postboot
defaults = {
"rootsize": 8192,
"mem": 1024,
"domain": 'yourdomain.com',
"hostname": "ubuntu",
"arch": arch,
"variant": "minbase",
"components": "main,universe,multiverse,restricted",
"lang": "en_GB.UTF-8",
"timezone": "Europe/London",
"execscript": os.path.realpath(os.path.join(os.curdir, "postboot.sh")),
"addpkg": [
"standard^", "server^", "gpgv", "openssh-server", "buildbot", "subversion",
],
}
def __init__(self, hypervisor="kvm", suite="karmic", destdir="ubuntu", **kw):
self.hypervisor = hypervisor
self.suite = suite
self.destdir = destdir
self.options = self.defaults.copy()
self.options.update(**kw)
f = tempfile.NamedTemporaryFile(delete=False, prefix="/var/tmp/")
print >>f, self.postboot % {
'master_host': '192.168.201.1',
'master_port': '8081',
'slave': 'slave',
'slave_password': 'password',
}
f.close()
os.chmod(f.name, 0755)
self.options['execscript'] = f.name
def build(self):
optstring = []
for k, v in self.options.items():
if type(v) == type([]):
for i in v:
if i:
optstring.append("--%s=%s" % (k, i))
else:
if v:
optstring.append("--%s=%s" % (k, v))
execute=("ubuntu-vm-builder %s %s -d%s %s" % (
self.hypervisor,
self.suite,
self.destdir,
" ".join(optstring)))
print execute
os.system(execute)
if __name__ == "__main__":
import sys, socket, optparse
parser = optparse.OptionParser(usage="%prog [options] project")
parser.add_option("-p", "--proxy", help="http proxy URL")
(options, args) = parser.parse_args()
builder = VMBuilder(proxy=options.proxy)
builder.build()
|