added box handling to vmtools

This commit is contained in:
Hans-Christoph Steiner 2017-05-22 17:14:48 +02:00
parent 01b6473823
commit 5dbcd0e9bd
2 changed files with 60 additions and 23 deletions

View file

@ -105,6 +105,9 @@ class FDroidBuildVm():
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
logger.info('could not bring vm up: %s', e) logger.info('could not bring vm up: %s', e)
def halt(self):
self.vgrnt.halt(force=True)
def destroy(self): def destroy(self):
"""Remove every trace of this VM from the system. """Remove every trace of this VM from the system.
@ -125,13 +128,37 @@ class FDroidBuildVm():
except Exception as e: except Exception as e:
logger.debug("could not delete vagrant dir: %s, %s", vgrntdir, e) logger.debug("could not delete vagrant dir: %s, %s", vgrntdir, e)
try: try:
subprocess.check_call(['vagrant', 'global-status', '--prune']) self._check_call(['vagrant', 'global-status', '--prune'])
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
logger.debug('pruning global vagrant status failed: %s', e) logger.debug('pruning global vagrant status failed: %s', e)
def package(self, output=None, keep_box_file=None): def package(self, output=None, keep_box_file=None):
self.vgrnt.package(output=output) self.vgrnt.package(output=output)
def box_add(self, boxname, boxfile, force=True):
"""Add vagrant box to vagrant.
:param boxname: name assigned to local deployment of box
:param boxfile: path to box file
:param force: overwrite existing box image (default: True)
"""
boxfile = abspath(boxfile)
if not isfile(boxfile):
raise FDroidBuildVmException('supplied boxfile \'%s\' does not exist', boxfile)
self.vgrnt.box_add(boxname, abspath(boxfile), force=force)
def box_remove(self, boxname):
try:
self._check_call(['vagrant', 'box', 'remove', '--all', '--force', boxname])
except subprocess.CalledProcessError as e:
logger.debug('tried removing box %s, but is did not exist: %s', boxname, e)
# TODO: remove box files manually
# nesessary when Vagrantfile in ~/.vagrant.d/... is broken.
def _check_call(self, cmd):
logger.debug(' '.join(cmd))
return subprocess.check_call(cmd)
class LibvirtBuildVm(FDroidBuildVm): class LibvirtBuildVm(FDroidBuildVm):
def __init__(self, srvdir): def __init__(self, srvdir):
@ -141,7 +168,7 @@ class LibvirtBuildVm(FDroidBuildVm):
try: try:
self.conn = libvirt.open('qemu:///system') self.conn = libvirt.open('qemu:///system')
except libvirt.libvirtError as e: except libvirt.libvirtError as e:
logger.critical('could not connect to libvirtd: %s', e) raise FDroidBuildVmException('could not connect to libvirtd: %s' % (e))
def destroy(self): def destroy(self):
@ -151,8 +178,7 @@ class LibvirtBuildVm(FDroidBuildVm):
# this is way more easy and therefore fault tolerant. # this is way more easy and therefore fault tolerant.
# (eg. lookupByName only works on running VMs) # (eg. lookupByName only works on running VMs)
try: try:
logger.debug('virsh -c qemu:///system destroy %s', self.srvname) self._check_call(('virsh', '-c', 'qemu:///system', 'destroy', self.srvname))
subprocess.check_call(('virsh', '-c', 'qemu:///system', 'destroy', self.srvname))
logger.info("...waiting a sec...") logger.info("...waiting a sec...")
time.sleep(10) time.sleep(10)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
@ -160,14 +186,13 @@ class LibvirtBuildVm(FDroidBuildVm):
try: try:
# libvirt python bindings do not support all flags required # libvirt python bindings do not support all flags required
# for undefining domains correctly. # for undefining domains correctly.
logger.debug('virsh -c qemu:///system undefine %s --nvram --managed-save --remove-all-storage --snapshots-metadata', self.srvname) self._check_call(('virsh', '-c', 'qemu:///system', 'undefine', self.srvname, '--nvram', '--managed-save', '--remove-all-storage', '--snapshots-metadata'))
subprocess.check_call(('virsh', '-c', 'qemu:///system', 'undefine', self.srvname, '--nvram', '--managed-save', '--remove-all-storage', '--snapshots-metadata'))
logger.info("...waiting a sec...") logger.info("...waiting a sec...")
time.sleep(10) time.sleep(10)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
logger.info("could not undefine libvirt domain '%s': %s", self.srvname, e) logger.info("could not undefine libvirt domain '%s': %s", self.srvname, e)
def package(self, output=None, keep_box_file=False): def package(self, output=None, vagrantfile=None, keep_box_file=False):
if not output: if not output:
output = "buildserver.box" output = "buildserver.box"
logger.debug('no output name set for packaging \'%s\',' + logger.debug('no output name set for packaging \'%s\',' +
@ -197,20 +222,9 @@ class LibvirtBuildVm(FDroidBuildVm):
"virtual_size": math.ceil(img_info['virtual-size'] / (1024. ** 3)) + 1, "virtual_size": math.ceil(img_info['virtual-size'] / (1024. ** 3)) + 1,
} }
vagrantfile = """Vagrant.configure("2") do |config| if not vagrantfile:
config.ssh.username = "vagrant" vagrantfile = 'Vagrant.configure("2") do |config|\nend'
config.ssh.password = "vagrant"
config.vm.provider :libvirt do |libvirt|
libvirt.driver = "kvm"
libvirt.host = ""
libvirt.connect_via_ssh = false
libvirt.storage_pool_name = "default"
end
end
"""
with open('metadata.json', 'w') as fp: with open('metadata.json', 'w') as fp:
fp.write(json.dumps(metadata)) fp.write(json.dumps(metadata))
with open('Vagrantfile', 'w') as fp: with open('Vagrantfile', 'w') as fp:
@ -230,6 +244,13 @@ end
logger.warn('could not connect to storage-pool \'default\',' + logger.warn('could not connect to storage-pool \'default\',' +
'skipping packaging buildserver box') 'skipping packaging buildserver box')
def box_remove(self, boxname):
super().box_remove(boxname)
try:
self._check_call(['virsh', '-c', 'qemu:///system', 'vol-delete', '--pool', 'default', '%s_vagrant_box_image_0.img' % (boxname)])
except subprocess.CalledProcessError as e:
logger.info('tired removing \'%s\', file was not present in first place: %s', boxname, e)
class VirtualboxBuildVm(FDroidBuildVm): class VirtualboxBuildVm(FDroidBuildVm):
pass pass

View file

@ -12,6 +12,7 @@ import hashlib
import yaml import yaml
import json import json
import logging import logging
import textwrap
from clint.textui import progress from clint.textui import progress
from optparse import OptionParser from optparse import OptionParser
import fdroidserver.tail import fdroidserver.tail
@ -525,12 +526,27 @@ def main():
if os.path.exists(boxfile): if os.path.exists(boxfile):
os.remove(boxfile) os.remove(boxfile)
vm.package(output=boxfile, debug_keep_box_file=options.debug_keep_box_file) vagrantfile = textwrap.dedent("""\
Vagrant.configure("2") do |config|
config.ssh.username = "vagrant"
config.ssh.password = "vagrant"
config.vm.provider :libvirt do |libvirt|
libvirt.driver = "kvm"
libvirt.host = ""
libvirt.connect_via_ssh = false
libvirt.storage_pool_name = "default"
end
end""")
vm.package(output=boxfile, vagrantfile=vagrantfile, keep_box_file=options.keep_box_file)
logger.info("Adding box") logger.info("Adding box")
v.box_add('buildserver', boxfile, force=True) vm.box_add('buildserver', boxfile, force=True)
if not 'buildserver' in subprocess.check_output(['vagrant', 'box', 'list']).decode('utf-8'): if 'buildserver' not in subprocess.check_output(['vagrant', 'box', 'list']).decode('utf-8'):
logger.critical('could not add box \'%s\' as \'buildserver\', terminating', boxfile) logger.critical('could not add box \'%s\' as \'buildserver\', terminating', boxfile)
sys.exit(1) sys.exit(1)