1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-07-07 09:50:07 +02:00

makebuildserver debugging log details

This commit is contained in:
Michael Pöhn 2017-03-24 20:04:50 +01:00 committed by Hans-Christoph Steiner
parent 2aa5523011
commit 440509cf8a
2 changed files with 96 additions and 44 deletions

View File

@ -52,7 +52,7 @@ echo "debian_mirror = 'https://deb.debian.org/debian/'" > $WORKSPACE/makebuildse
echo "boot_timeout = 1200" >> $WORKSPACE/makebuildserver.config.py echo "boot_timeout = 1200" >> $WORKSPACE/makebuildserver.config.py
echo "apt_package_cache = True" >> $WORKSPACE/makebuildserver.config.py echo "apt_package_cache = True" >> $WORKSPACE/makebuildserver.config.py
echo "copy_caches_from_host = True" >> $WORKSPACE/makebuildserver.config.py echo "copy_caches_from_host = True" >> $WORKSPACE/makebuildserver.config.py
./makebuildserver --verbose --clean ./makebuildserver -vv --clean
if [ -z "`vagrant box list | egrep '^buildserver\s+\((libvirt|virtualbox), [0-9]+\)$'`" ]; then if [ -z "`vagrant box list | egrep '^buildserver\s+\((libvirt|virtualbox), [0-9]+\)$'`" ]; then
vagrant box list vagrant box list

View File

@ -14,27 +14,47 @@ import hashlib
import yaml import yaml
import math import math
import json import json
import logging
from clint.textui import progress from clint.textui import progress
from optparse import OptionParser from optparse import OptionParser
import fdroidserver.tail import fdroidserver.tail
if not os.path.exists('makebuildserver') and not os.path.exists('buildserver'):
print('This must be run as ./makebuildserver in fdroidserver.git!')
sys.exit(1)
parser = OptionParser()
#parser.add_option("-v", "--verbose", action="store_true", default=False,
parser.add_option('-v', '--verbose', action="count", dest='verbosity', default=1,
help="Spew out even more information than normal")
parser.add_option('-q', action='store_const', const=0, dest='verbosity')
parser.add_option("-c", "--clean", action="store_true", default=False,
help="Build from scratch, rather than attempting to update the existing server")
parser.add_option('--skip-cache-update', action="store_true", default=False,
help="""Skip downloading and checking cache."""
"""This assumes that the cache is already downloaded completely.""")
options, args = parser.parse_args()
logger = logging.getLogger('fdroid-makebuildserver')
if options.verbosity >= 2:
logging.basicConfig(format='%(message)s', level=logging.DEBUG)
logger.setLevel(logging.DEBUG)
elif options.verbosity == 1:
logging.basicConfig(format='%(message)s', level=logging.INFO)
logger.setLevel(logging.INFO)
elif options.verbosity <= 0:
logging.basicConfig(format='%(message)s', level=logging.WARNING)
logger.setLevel(logging.WARNING)
if not os.path.exists('makebuildserver') and not os.path.exists('buildserver'):
logger.critical('This must be run as ./makebuildserver in fdroidserver.git!')
sys.exit(1)
tail = None tail = None
parser = OptionParser()
parser.add_option("-v", "--verbose", action="store_true", default=False,
help="Spew out even more information than normal")
parser.add_option("-c", "--clean", action="store_true", default=False,
help="Build from scratch, rather than attempting to update the existing server")
options, args = parser.parse_args()
# set up default config # set up default config
cachedir = os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver') cachedir = os.path.join(os.getenv('HOME'), '.cache', 'fdroidserver')
logger.debug('cachedir set to: %s', cachedir)
config = { config = {
'basebox': 'jessie64', 'basebox': 'jessie64',
'baseboxurl': [ 'baseboxurl': [
@ -58,11 +78,12 @@ if os.path.isfile('/usr/bin/systemd-detect-virt'):
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
virt = 'none' virt = 'none'
if virt == 'qemu' or virt == 'kvm' or virt == 'bochs': if virt == 'qemu' or virt == 'kvm' or virt == 'bochs':
print('Running in a VM guest, defaulting to QEMU/KVM via libvirt') logger.info('Running in a VM guest, defaulting to QEMU/KVM via libvirt')
config['vm_provider'] = 'libvirt' config['vm_provider'] = 'libvirt'
config['domain'] = 'buildserver_default' config['domain'] = 'buildserver_default'
elif virt != 'none': elif virt != 'none':
print('Running in an unsupported VM guest (' + virt + ')!') logger.info('Running in an unsupported VM guest (%s)!', virt)
logger.debug('deceted virt: %s', virt)
# load config file, if present # load config file, if present
if os.path.exists('makebuildserver.config.py'): if os.path.exists('makebuildserver.config.py'):
@ -72,24 +93,28 @@ elif os.path.exists('makebs.config.py'):
exec(compile(open('makebs.config.py').read(), 'makebs.config.py', 'exec'), config) exec(compile(open('makebs.config.py').read(), 'makebs.config.py', 'exec'), config)
if '__builtins__' in config: if '__builtins__' in config:
del(config['__builtins__']) # added by compile/exec del(config['__builtins__']) # added by compile/exec
logger.debug("makebuildserver.config.py parsed -> %s", json.dumps(config, indent=4, sort_keys=True))
# Update cached files. # Update cached files.
cachedir = config['cachedir'] cachedir = config['cachedir']
if not os.path.exists(cachedir): if not os.path.exists(cachedir):
os.makedirs(cachedir, 0o755) os.makedirs(cachedir, 0o755)
logger.debug('created cachedir %s because it did not exists.', cachedir)
if config['vm_provider'] == 'libvirt': if config['vm_provider'] == 'libvirt':
tmp = cachedir tmp = cachedir
while tmp != '/': while tmp != '/':
mode = os.stat(tmp).st_mode mode = os.stat(tmp).st_mode
if not (stat.S_IXUSR & mode and stat.S_IXGRP & mode and stat.S_IXOTH & mode): if not (stat.S_IXUSR & mode and stat.S_IXGRP & mode and stat.S_IXOTH & mode):
print('ERROR:', tmp, 'will not be accessible to the VM! To fix, run:') logger.critical('ERROR: %s will not be accessible to the VM! To fix, run:', tmp)
print(' chmod a+X', tmp) logger.critical(' chmod a+X %s', tmp)
sys.exit(1) sys.exit(1)
tmp = os.path.dirname(tmp) tmp = os.path.dirname(tmp)
logger.debug('cache dir %s is accessible for libvirt vm.', cachedir)
if config['apt_package_cache']: if config['apt_package_cache']:
config['aptcachedir'] = cachedir + '/apt/archives' config['aptcachedir'] = cachedir + '/apt/archives'
logger.debug('aptcachedir is set to %s', config['aptcachedir'])
cachefiles = [ cachefiles = [
('https://dl.google.com/android/repository/tools_r25.2.3-linux.zip', ('https://dl.google.com/android/repository/tools_r25.2.3-linux.zip',
@ -299,17 +324,20 @@ def sha256_for_file(path):
def destroy_current_image(v, serverdir): def destroy_current_image(v, serverdir):
global config global config
logger.info('destroying buildserver vm, removing images and vagrand-configs...')
# cannot run vagrant without the config in the YAML file # cannot run vagrant without the config in the YAML file
if os.path.exists(os.path.join(serverdir, 'Vagrantfile.yaml')): if os.path.exists(os.path.join(serverdir, 'Vagrantfile.yaml')):
v.destroy() v.destroy()
elif options.verbose: logger.debug('vagrant destroy completed')
print('Cannot run destroy vagrant setup since Vagrantfile.yaml is not setup!') if logger.level <= logging.DEBUG:
logger.debug('Cannot run destroy vagrant setup since Vagrantfile.yaml is not setup!')
subprocess.check_call(['vagrant', 'global-status', '--prune']) subprocess.check_call(['vagrant', 'global-status', '--prune'])
try: try:
shutil.rmtree(os.path.join(serverdir, '.vagrant')) shutil.rmtree(os.path.join(serverdir, '.vagrant'))
except Exception as e: except Exception as e:
print("could not delete vagrant dir: %s, %s" % (os.path.join(serverdir, '.vagrant'), e)) logger.debug("could not delete vagrant dir: %s, %s", os.path.join(serverdir, '.vagrant'), e)
if config['vm_provider'] == 'libvirt': if config['vm_provider'] == 'libvirt':
import libvirt import libvirt
@ -325,7 +353,7 @@ def destroy_current_image(v, serverdir):
for vol in storagePool.listAllVolumes(): for vol in storagePool.listAllVolumes():
vol.delete() vol.delete()
except libvirt.libvirtError as e: except libvirt.libvirtError as e:
print(e) logger.warn('%s', e)
def kvm_package(boxfile): def kvm_package(boxfile):
@ -385,9 +413,7 @@ def run_via_vagrant_ssh(v, cmdlist):
v._run_vagrant_command(['ssh', '-c', cmd]) v._run_vagrant_command(['ssh', '-c', cmd])
def main(): def update_cache(cachedir, cachefiles):
global cachedir, cachefiles, config, tail
for srcurl, shasum in cachefiles: for srcurl, shasum in cachefiles:
filename = os.path.basename(srcurl) filename = os.path.basename(srcurl)
local_filename = os.path.join(cachedir, filename) local_filename = os.path.join(cachedir, filename)
@ -408,19 +434,19 @@ def main():
content_length = local_length # skip the download content_length = local_length # skip the download
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
content_length = local_length # skip the download content_length = local_length # skip the download
print(e) logger.warn('%s', e)
if local_length == content_length: if local_length == content_length:
download = False download = False
elif local_length > content_length: elif local_length > content_length:
print('deleting corrupt file from cache: ' + local_filename) logger.info('deleting corrupt file from cache: %s', local_filename)
os.remove(local_filename) os.remove(local_filename)
print("Downloading " + filename + " to cache") logger.info("Downloading %s to cache", filename)
elif local_length > -1 and local_length < content_length: elif local_length > -1 and local_length < content_length:
print("Resuming download of " + local_filename) logger.info("Resuming download of %s", local_filename)
resume_header = {'Range': 'bytes=%d-%d' % (local_length, content_length)} resume_header = {'Range': 'bytes=%d-%d' % (local_length, content_length)}
else: else:
print("Downloading " + filename + " to cache") logger.info("Downloading %s to cache", filename)
if download: if download:
r = requests.get(srcurl, headers=resume_header, r = requests.get(srcurl, headers=resume_header,
@ -434,14 +460,37 @@ def main():
v = sha256_for_file(local_filename) v = sha256_for_file(local_filename)
if v == shasum: if v == shasum:
print("\t...shasum verified for " + local_filename) logger.info("\t...shasum verified for %s", local_filename)
else: else:
print("Invalid shasum of '" + v + "' detected for " + local_filename) logger.critical("Invalid shasum of '%s' detected for %s", v, local_filename)
os.remove(local_filename) os.remove(local_filename)
sys.exit(1) sys.exit(1)
def debug_log_vagrant_vm(vm_dir, vm_name):
if options.verbosity >= 3:
_vagrant_dir = os.path.join(vm_dir, '.vagrant')
logger.debug('check %s dir exists? -> %r', _vagrant_dir, os.path.isdir(_vagrant_dir))
logger.debug('> vagrant status')
subprocess.call(['vagrant', 'status'], cwd=vm_dir)
logger.debug('> vagrant box list')
subprocess.call(['vagrant', 'box', 'list'])
logger.debug('> virsh -c qmeu:///system list --all')
subprocess.call(['virsh', '-c', 'qemu:///system', 'list', '--all'])
logger.debug('> virsh -c qemu:///system snapshot-list %s', vm_name)
subprocess.call(['virsh', '-c', 'qemu:///system', 'snapshot-list', vm_name])
def main():
global cachedir, cachefiles, config, tail
if options.skip_cache_update:
logger.info('skipping cache update and verification...')
else:
update_cache(cachedir, cachefiles)
local_qt_filename = os.path.join(cachedir, 'qt-opensource-linux-x64-android-5.7.0.run') local_qt_filename = os.path.join(cachedir, 'qt-opensource-linux-x64-android-5.7.0.run')
print("Setting executable bit for " + local_qt_filename) logger.info("Setting executable bit for %s", local_qt_filename)
os.chmod(local_qt_filename, 0o755) os.chmod(local_qt_filename, 0o755)
# use VirtualBox software virtualization if hardware is not available, # use VirtualBox software virtualization if hardware is not available,
@ -451,11 +500,13 @@ def main():
# all < 10 year old Macs work, and OSX servers as VM host are very # all < 10 year old Macs work, and OSX servers as VM host are very
# rare, but this could also be auto-detected if someone codes it # rare, but this could also be auto-detected if someone codes it
config['hwvirtex'] = 'on' config['hwvirtex'] = 'on'
logger.info('platform is darwnin -> hwvirtex = \'on\'')
elif os.path.exists('/proc/cpuinfo'): elif os.path.exists('/proc/cpuinfo'):
with open('/proc/cpuinfo') as f: with open('/proc/cpuinfo') as f:
contents = f.read() contents = f.read()
if 'vmx' in contents or 'svm' in contents: if 'vmx' in contents or 'svm' in contents:
config['hwvirtex'] = 'on' config['hwvirtex'] = 'on'
logger.info('found \'vmx\' or \'svm\' in /proc/cpuinfo -> hwvirtex = \'on\'')
serverdir = os.path.join(os.getcwd(), 'buildserver') serverdir = os.path.join(os.getcwd(), 'buildserver')
logfilename = os.path.join(serverdir, 'up.log') logfilename = os.path.join(serverdir, 'up.log')
@ -464,7 +515,7 @@ def main():
log_cm = vagrant.make_file_cm(logfilename) log_cm = vagrant.make_file_cm(logfilename)
v = vagrant.Vagrant(root=serverdir, out_cm=log_cm, err_cm=log_cm) v = vagrant.Vagrant(root=serverdir, out_cm=log_cm, err_cm=log_cm)
if options.verbose: if options.verbosity >= 2:
tail = fdroidserver.tail.Tail(logfilename) tail = fdroidserver.tail.Tail(logfilename)
tail.start() tail.start()
@ -476,18 +527,18 @@ def main():
vf = os.path.join(serverdir, 'Vagrantfile.yaml') vf = os.path.join(serverdir, 'Vagrantfile.yaml')
writevf = True writevf = True
if os.path.exists(vf): if os.path.exists(vf):
print('Halting', serverdir) logger.info('Halting %s', serverdir)
v.halt() v.halt()
with open(vf, 'r', encoding='utf-8') as f: with open(vf, 'r', encoding='utf-8') as f:
oldconfig = yaml.load(f) oldconfig = yaml.load(f)
if config != oldconfig: if config != oldconfig:
print("Server configuration has changed, rebuild from scratch is required") logger.info("Server configuration has changed, rebuild from scratch is required")
destroy_current_image(v, serverdir) destroy_current_image(v, serverdir)
else: else:
print("Re-provisioning existing server") logger.info("Re-provisioning existing server")
writevf = False writevf = False
else: else:
print("No existing server - building from scratch") logger.info("No existing server - building from scratch")
if writevf: if writevf:
with open(vf, 'w', encoding='utf-8') as f: with open(vf, 'w', encoding='utf-8') as f:
yaml.dump(config, f) yaml.dump(config, f)
@ -506,17 +557,19 @@ def main():
baseboxurl = config['baseboxurl'] baseboxurl = config['baseboxurl']
else: else:
baseboxurl = config['baseboxurl'][0] baseboxurl = config['baseboxurl'][0]
print('Adding', config['basebox'], 'from', baseboxurl) logger.info('Adding %s from %s', config['basebox'], baseboxurl)
v.box_add(config['basebox'], baseboxurl) v.box_add(config['basebox'], baseboxurl)
needs_mutate = True needs_mutate = True
if needs_mutate: if needs_mutate:
print('Converting', config['basebox'], 'to libvirt format') logger.info('Converting %s to libvirt format', config['basebox'])
v._call_vagrant_command(['mutate', config['basebox'], 'libvirt']) v._call_vagrant_command(['mutate', config['basebox'], 'libvirt'])
print('Removing virtualbox format copy of', config['basebox']) logger.info('Removing virtualbox format copy of %s', config['basebox'])
v.box_remove(config['basebox'], 'virtualbox') v.box_remove(config['basebox'], 'virtualbox')
print("Configuring build server VM") logger.info("Configuring build server VM")
debug_log_vagrant_vm(serverdir, 'buildserver_default')
v.up(provision=True) v.up(provision=True)
debug_log_vagrant_vm(serverdir, 'buildserver_default')
if config['copy_caches_from_host']: if config['copy_caches_from_host']:
ssh_config = v.ssh_config() ssh_config = v.ssh_config()
@ -539,17 +592,16 @@ def main():
run_via_vagrant_ssh(v, ['rm', '-f', '~/.gradle/caches/modules-2/modules-2.lock']) run_via_vagrant_ssh(v, ['rm', '-f', '~/.gradle/caches/modules-2/modules-2.lock'])
run_via_vagrant_ssh(v, ['rm', '-fr', '~/.gradle/caches/*/plugin-resolution/']) run_via_vagrant_ssh(v, ['rm', '-fr', '~/.gradle/caches/*/plugin-resolution/'])
print("Writing buildserver ID")
p = subprocess.Popen(['git', 'rev-parse', 'HEAD'], stdout=subprocess.PIPE, p = subprocess.Popen(['git', 'rev-parse', 'HEAD'], stdout=subprocess.PIPE,
universal_newlines=True) universal_newlines=True)
buildserverid = p.communicate()[0].strip() buildserverid = p.communicate()[0].strip()
print("...ID is " + buildserverid) logger.info("Writing buildserver ID ...ID is %s", buildserverid)
run_via_vagrant_ssh(v, 'sh -c "echo %s >/home/vagrant/buildserverid"' % buildserverid) run_via_vagrant_ssh(v, 'sh -c "echo %s >/home/vagrant/buildserverid"' % buildserverid)
print("Stopping build server VM") logger.info("Stopping build server VM")
v.halt() v.halt()
print("Packaging") logger.info("Packaging")
boxfile = os.path.join(os.getcwd(), 'buildserver.box') boxfile = os.path.join(os.getcwd(), 'buildserver.box')
if os.path.exists(boxfile): if os.path.exists(boxfile):
os.remove(boxfile) os.remove(boxfile)
@ -559,7 +611,7 @@ def main():
else: else:
v.package(output=boxfile) v.package(output=boxfile)
print("Adding box") logger.info("Adding box")
v.box_add('buildserver', boxfile, force=True) v.box_add('buildserver', boxfile, force=True)
os.remove(boxfile) os.remove(boxfile)