From 85985074d45832c8e0fb9295eda1f2614b42f7e3 Mon Sep 17 00:00:00 2001 From: Marcus Hoffmann Date: Mon, 15 Jan 2018 01:03:47 +0100 Subject: [PATCH] build: enable watchdog timer for each build that kills in 2 hours This introduces locking for the commonly used vagrant functions in vmtools because vagrant fails when another vagrant command is already running. --- fdroidserver/build.py | 17 +++++++++++++++++ fdroidserver/vmtools.py | 32 ++++++++++++++++++++------------ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 61cda139..cb030ebb 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -25,6 +25,7 @@ import re import resource import sys import tarfile +import threading import traceback import time import requests @@ -978,6 +979,13 @@ def trybuild(app, build, build_dir, output_dir, log_dir, also_check_dir, return True +def force_halt_build(): + """Halt the currently running Vagrant VM, to be called from a Timer""" + logging.error(_('Force halting build after timeout!')) + vm = vmtools.get_build_vm('builder') + vm.halt() + + def parse_commandline(): """Parse the command line. Returns options, parser.""" @@ -1143,6 +1151,12 @@ def main(): first = True for build in app.builds: + if options.server: # enable watchdog timer + timer = threading.Timer(7200, force_halt_build) + timer.start() + else: + timer = None + wikilog = None build_starttime = common.get_wiki_timestamp() tools_version_log = '' @@ -1283,6 +1297,9 @@ def main(): except Exception as e: logging.error("Error while attempting to publish build log: %s" % e) + if timer: + timer.cancel() # kill the watchdog timer + for app in build_succeeded: logging.info("success: %s" % (app.id)) diff --git a/fdroidserver/vmtools.py b/fdroidserver/vmtools.py index 6671a3eb..33544ac5 100644 --- a/fdroidserver/vmtools.py +++ b/fdroidserver/vmtools.py @@ -29,6 +29,9 @@ from .common import FDroidException from logging import getLogger from fdroidserver import _ +import threading + +lock = threading.Lock() logger = getLogger('fdroidserver-vmtools') @@ -175,7 +178,6 @@ class FDroidBuildVm(): This is intended to be a hypervisor independant, fault tolerant wrapper around the vagrant functions we use. """ - def __init__(self, srvdir): """Create new server class. """ @@ -191,21 +193,27 @@ class FDroidBuildVm(): self.vgrnt = vagrant.Vagrant(root=srvdir, out_cm=vagrant.stdout_cm, err_cm=vagrant.stdout_cm) def up(self, provision=True): - try: - self.vgrnt.up(provision=provision) - self.srvuuid = self._vagrant_fetch_uuid() - except subprocess.CalledProcessError as e: - raise FDroidBuildVmException("could not bring up vm '%s'" % self.srvname) from e + global lock + with lock: + try: + self.vgrnt.up(provision=provision) + self.srvuuid = self._vagrant_fetch_uuid() + except subprocess.CalledProcessError as e: + raise FDroidBuildVmException("could not bring up vm '%s'" % self.srvname) from e def suspend(self): - logger.info('suspending buildserver') - try: - self.vgrnt.suspend() - except subprocess.CalledProcessError as e: - raise FDroidBuildVmException("could not suspend vm '%s'" % self.srvname) from e + global lock + with lock: + logger.info('suspending buildserver') + try: + self.vgrnt.suspend() + except subprocess.CalledProcessError as e: + raise FDroidBuildVmException("could not suspend vm '%s'" % self.srvname) from e def halt(self): - self.vgrnt.halt(force=True) + global lock + with lock: + self.vgrnt.halt(force=True) def destroy(self): """Remove every trace of this VM from the system.