Merge pull request #2041 from charltonaustin/add_cancel_to_building_build

Adding in the behavior for cancelling a build while it is being built.
This commit is contained in:
Charlton Austin 2016-11-18 11:02:37 -05:00 committed by GitHub
commit 96173485f8
7 changed files with 120 additions and 16 deletions

View file

@ -246,6 +246,10 @@ class BuildComponent(BaseComponent):
try:
if self._build_status.set_phase(phase, log_data.get('status_data')):
logger.debug('Build %s has entered a new phase: %s', self.builder_realm, phase)
elif self._current_job.repo_build.phase == BUILD_PHASE.CANCELLED:
build_id = self._current_job.repo_build.uuid
logger.debug('Trying to move cancelled build into phase: %s with id: %s', phase, build_id)
return False
except InvalidRepositoryBuildException:
build_id = self._current_job.repo_build.uuid
logger.info('Build %s was not found; repo was probably deleted', build_id)

View file

@ -0,0 +1,25 @@
import logging
from buildman.manager.etcd_canceller import EtcdCanceller
from buildman.manager.noop_canceller import NoopCanceller
logger = logging.getLogger(__name__)
CANCELLERS = {'ephemeral': EtcdCanceller}
class BuildCanceller(object):
""" A class to manage cancelling a build """
def __init__(self, app=None):
build_manager_config = app.config.get('BUILD_MANAGER')
if app is None or build_manager_config is None:
self.handler = NoopCanceller()
return
canceller = CANCELLERS.get(build_manager_config[0], NoopCanceller)
self.handler = canceller(build_manager_config[1])
def try_cancel_build(self, uuid):
""" A method to kill a running build """
return self.handler.try_cancel_build(uuid)

View file

@ -0,0 +1,37 @@
import logging
import etcd
logger = logging.getLogger(__name__)
class EtcdCanceller(object):
""" A class that sends a message to etcd to cancel a build """
def __init__(self, config):
etcd_host = config.get('ETCD_HOST', '127.0.0.1')
etcd_port = config.get('ETCD_PORT', 2379)
etcd_ca_cert = config.get('ETCD_CA_CERT', None)
etcd_auth = config.get('ETCD_CERT_AND_KEY', None)
if etcd_auth is not None:
etcd_auth = tuple(etcd_auth)
etcd_protocol = 'http' if etcd_auth is None else 'https'
logger.debug('Connecting to etcd on %s:%s', etcd_host, etcd_port)
self._cancel_prefix = config.get('ETCD_CANCEL_PREFIX', 'cancel/')
self._etcd_client = etcd.Client(
host=etcd_host,
port=etcd_port,
cert=etcd_auth,
ca_cert=etcd_ca_cert,
protocol=etcd_protocol,
read_timeout=5)
def try_cancel_build(self, build_uuid):
""" Writes etcd message to cancel build_uuid. """
logger.info("Cancelling build %s".format(build_uuid))
try:
self._etcd_client.write("{}{}".format(self._cancel_prefix, build_uuid), build_uuid)
return True
except etcd.EtcdException:
logger.exception("Failed to write to etcd client %s", build_uuid)
return False

View file

@ -0,0 +1,8 @@
class NoopCanceller(object):
""" A class that can not cancel a build """
def __init__(self, config=None):
pass
def try_cancel_build(self, uuid):
""" Does nothing and fails to cancel build. """
return False