Adding in cancel for a build that is building.

This commit is contained in:
Charlton Austin 2016-10-27 13:18:02 -04:00
parent e57eece6c1
commit fd7c566d31
7 changed files with 120 additions and 16 deletions

View file

@ -10,6 +10,8 @@ from data.model import (InvalidBuildTriggerException, InvalidRepositoryBuildExce
PRESUMED_DEAD_BUILD_AGE = timedelta(days=15)
PHASES_NOT_ALLOWED_TO_CANCEL_FROM = (BUILD_PHASE.PUSHING, BUILD_PHASE.COMPLETE,
BUILD_PHASE.ERROR, BUILD_PHASE.INTERNAL_ERROR)
def update_build_trigger(trigger, config, auth_token=None):
@ -143,54 +145,79 @@ def get_pull_robot_name(trigger):
return trigger.pull_robot.username
def _get_build_row_for_update(build_uuid):
return db_for_update(RepositoryBuild.select().where(RepositoryBuild.uuid == build_uuid)).get()
def update_phase(build_uuid, phase):
""" A function to change the phase of a build """
with db_transaction():
try:
build = get_repository_build(build_uuid)
build.phase = phase
build.save()
return True
except InvalidRepositoryBuildException:
try:
build = _get_build_row_for_update(build_uuid)
except RepositoryBuild.DoesNotExist:
return False
# Can't update a cancelled build
if build.phase == BUILD_PHASE.CANCELLED:
return False
build.phase = phase
build.save()
return True
def create_cancel_build_in_queue(build, build_queue):
""" A function to cancel a build before it leaves the queue """
def cancel_build():
if build.phase != BUILD_PHASE.WAITING or not build.queue_id:
cancelled = False
if build.queue_id is not None:
cancelled = build_queue.cancel(build.queue_id)
if build.phase != BUILD_PHASE.WAITING:
return False
cancelled = build_queue.cancel(build.queue_id)
if cancelled:
# Delete the build row.
build.delete_instance()
return cancelled
return cancel_build
def create_cancel_build_in_manager(build):
def create_cancel_build_in_manager(build, build_canceller):
""" A function to cancel the build before it starts to push """
def cancel_build():
return False
original_phase = build.phase
if build.phase in PHASES_NOT_ALLOWED_TO_CANCEL_FROM:
return False
build.phase = BUILD_PHASE.CANCELLED
build.save()
if not build_canceller.try_cancel_build(build.uuid):
build.phase = original_phase
build.save()
return False
return True
return cancel_build
def cancel_repository_build(build, build_queue):
""" This tries to cancel the build returns true if request is successful false if it can't be cancelled """
with db_transaction():
from app import build_canceller
# Reload the build for update.
# We are loading the build for update so checks should be as quick as possible.
try:
build = db_for_update(RepositoryBuild.select().where(RepositoryBuild.id == build.id)).get()
build = _get_build_row_for_update(build.uuid)
except RepositoryBuild.DoesNotExist:
return False
cancel_builds = [create_cancel_build_in_queue(build, build_queue),
create_cancel_build_in_manager(build), ]
create_cancel_build_in_manager(build, build_canceller), ]
for cancelled in cancel_builds:
if cancelled():
# Delete the build row.
# TODO Charlie 2016-11-11 Add in message that says build was cancelled and remove the delete build.
build.delete_instance()
return True
return False