chiark / gitweb /
buildserver: auto-detect and use libvirt's QEMU+KVM
authorHans-Christoph Steiner <hans@eds.org>
Thu, 15 Sep 2016 09:12:18 +0000 (11:12 +0200)
committerHans-Christoph Steiner <hans@eds.org>
Mon, 19 Sep 2016 14:33:12 +0000 (16:33 +0200)
For running in QEMU/KVM guests like on jenkins.debian.net, this sets up the
whole process automatically.  This only really covers the case where this
is running in a KVM guest, and the original case of running VirtualBox on
bare metal.  It could be extended to cover more cases if someone wanted to.

examples/makebuildserver.config.py
makebuildserver

index 4ee73fbce01308c2aeebaf5abdb277431c9ae033..b6c0183d013893689f4b79658626247d1c537ab2 100644 (file)
 # about the timeout, extend the timeout here. (default: 600 seconds)
 #
 # boot_timeout = 1200
+
+# By default, this whole process uses VirtualBox as the provider, but
+# QEMU+KVM is also supported via the libvirt plugin to vagrant. If
+# this is run within a KVM guest, then libvirt's QEMU+KVM will be used
+# automatically.  It can also be manually enabled by uncommenting
+# below:
+#
+# vm_provider = 'libvirt'
index 3a26bf512f1c5ee014c11ae3cd7e1e4506cf694a..1901013782378eb0ef050ffabdc1333a4798e978 100755 (executable)
@@ -64,8 +64,20 @@ config = {
     'cpus': 1,
     'memory': 1024,
     'hwvirtex': 'off',
+    'vm_provider': 'virtualbox',
 }
 
+if os.path.isfile('/usr/bin/systemd-detect-virt'):
+    try:
+        virt = subprocess.check_output('/usr/bin/systemd-detect-virt').strip().decode('utf-8')
+    except subprocess.CalledProcessError as e:
+        virt = 'none'
+    if virt == 'qemu' or virt == 'kvm':
+        print('Running in a VM guest, defaulting to QEMU/KVM via libvirt')
+        config['vm_provider'] = 'libvirt'
+    elif virt != 'none':
+        print('Running in an unsupported VM guest (' + virt + ')!')
+
 # load config file, if present
 if os.path.exists('makebuildserver.config.py'):
     exec(compile(open('makebuildserver.config.py').read(), 'makebuildserver.config.py', 'exec'), config)
@@ -346,6 +358,7 @@ elif os.path.exists('/proc/cpuinfo'):
 vf = os.path.join(serverdir, 'Vagrantfile.yaml')
 writevf = True
 if os.path.exists(vf):
+    print('Halting', serverdir)
     vagrant(['halt'], serverdir)
     with open(vf, 'r', encoding='utf-8') as f:
         oldconfig = yaml.load(f)
@@ -361,6 +374,33 @@ if writevf:
     with open(vf, 'w', encoding='utf-8') as f:
         yaml.dump(config, f)
 
+if config['vm_provider'] == 'libvirt':
+    returncode, out = vagrant(['box', 'list'], serverdir, printout=options.verbose)
+    found_basebox = False
+    needs_mutate = False
+    for line in out.splitlines():
+        if line.startswith(config['basebox']):
+            found_basebox = True
+            if line.split('(')[1].split(',')[0] != 'libvirt':
+                needs_mutate = True
+            continue
+    if not found_basebox:
+        if isinstance(config['baseboxurl'], str):
+            baseboxurl = config['baseboxurl']
+        else:
+            baseboxurl = config['baseboxurl'][0]
+        print('Adding', config['basebox'], 'from', baseboxurl)
+        vagrant(['box', 'add', '--name', config['basebox'], baseboxurl],
+                serverdir, printout=options.verbose)
+        needs_mutate = True
+    if needs_mutate:
+        print('Converting', config['basebox'], 'to libvirt format')
+        vagrant(['mutate', config['basebox'], 'libvirt'],
+                serverdir, printout=options.verbose)
+        print('Removing virtualbox format copy of', config['basebox'])
+        vagrant(['box', 'remove', '--provider', 'virtualbox', config['basebox']],
+                serverdir, printout=options.verbose)
+
 print("Configuring build server VM")
 returncode, out = vagrant(['up', '--provision'], serverdir, printout=True)
 with open(os.path.join(serverdir, 'up.log'), 'w') as log: