474fffd01f
If we just return the ID, then peewee just fills in the other fields with defaults (such as UUID).
186 lines
6.4 KiB
Python
186 lines
6.4 KiB
Python
import json
|
|
|
|
from peewee import JOIN_LEFT_OUTER
|
|
from datetime import timedelta, datetime
|
|
|
|
from data.database import (BuildTriggerService, RepositoryBuildTrigger, Repository, Namespace, User,
|
|
RepositoryBuild, BUILD_PHASE, db_for_update, db_random_func)
|
|
from data.model import (InvalidBuildTriggerException, InvalidRepositoryBuildException,
|
|
db_transaction, user as user_model)
|
|
|
|
|
|
PRESUMED_DEAD_BUILD_AGE = timedelta(days=15)
|
|
|
|
|
|
def update_build_trigger(trigger, config, auth_token=None):
|
|
trigger.config = json.dumps(config or {})
|
|
if auth_token is not None:
|
|
trigger.auth_token = auth_token
|
|
trigger.save()
|
|
|
|
|
|
def create_build_trigger(repo, service_name, auth_token, user, pull_robot=None, config=None):
|
|
config = config or {}
|
|
service = BuildTriggerService.get(name=service_name)
|
|
trigger = RepositoryBuildTrigger.create(repository=repo, service=service,
|
|
auth_token=auth_token,
|
|
connected_user=user,
|
|
pull_robot=pull_robot,
|
|
config=json.dumps(config))
|
|
return trigger
|
|
|
|
|
|
def get_build_trigger(trigger_uuid):
|
|
try:
|
|
return (RepositoryBuildTrigger
|
|
.select(RepositoryBuildTrigger, BuildTriggerService, Repository, Namespace)
|
|
.join(BuildTriggerService)
|
|
.switch(RepositoryBuildTrigger)
|
|
.join(Repository)
|
|
.join(Namespace, on=(Repository.namespace_user == Namespace.id))
|
|
.switch(RepositoryBuildTrigger)
|
|
.join(User)
|
|
.where(RepositoryBuildTrigger.uuid == trigger_uuid)
|
|
.get())
|
|
except RepositoryBuildTrigger.DoesNotExist:
|
|
msg = 'No build trigger with uuid: %s' % trigger_uuid
|
|
raise InvalidBuildTriggerException(msg)
|
|
|
|
|
|
def list_build_triggers(namespace_name, repository_name):
|
|
return (RepositoryBuildTrigger
|
|
.select(RepositoryBuildTrigger, BuildTriggerService, Repository)
|
|
.join(BuildTriggerService)
|
|
.switch(RepositoryBuildTrigger)
|
|
.join(Repository)
|
|
.join(Namespace, on=(Repository.namespace_user == Namespace.id))
|
|
.where(Namespace.username == namespace_name, Repository.name == repository_name))
|
|
|
|
|
|
def list_trigger_builds(namespace_name, repository_name, trigger_uuid,
|
|
limit):
|
|
return (list_repository_builds(namespace_name, repository_name, limit)
|
|
.where(RepositoryBuildTrigger.uuid == trigger_uuid))
|
|
|
|
|
|
def get_repository_for_resource(resource_key):
|
|
try:
|
|
return (Repository
|
|
.select(Repository, Namespace)
|
|
.join(Namespace, on=(Repository.namespace_user == Namespace.id))
|
|
.switch(Repository)
|
|
.join(RepositoryBuild)
|
|
.where(RepositoryBuild.resource_key == resource_key)
|
|
.get())
|
|
except Repository.DoesNotExist:
|
|
return None
|
|
|
|
|
|
def _get_build_base_query():
|
|
return (RepositoryBuild
|
|
.select(RepositoryBuild, RepositoryBuildTrigger, BuildTriggerService, Repository,
|
|
Namespace, User)
|
|
.join(Repository)
|
|
.join(Namespace, on=(Repository.namespace_user == Namespace.id))
|
|
.switch(RepositoryBuild)
|
|
.join(User, JOIN_LEFT_OUTER)
|
|
.switch(RepositoryBuild)
|
|
.join(RepositoryBuildTrigger, JOIN_LEFT_OUTER)
|
|
.join(BuildTriggerService, JOIN_LEFT_OUTER)
|
|
.order_by(RepositoryBuild.started.desc()))
|
|
|
|
|
|
def get_repository_build(build_uuid):
|
|
try:
|
|
return _get_build_base_query().where(RepositoryBuild.uuid == build_uuid).get()
|
|
|
|
except RepositoryBuild.DoesNotExist:
|
|
msg = 'Unable to locate a build by id: %s' % build_uuid
|
|
raise InvalidRepositoryBuildException(msg)
|
|
|
|
|
|
def list_repository_builds(namespace_name, repository_name, limit,
|
|
include_inactive=True, since=None):
|
|
query = (_get_build_base_query()
|
|
.where(Repository.name == repository_name, Namespace.username == namespace_name)
|
|
.limit(limit))
|
|
|
|
if since is not None:
|
|
query = query.where(RepositoryBuild.started >= since)
|
|
|
|
if not include_inactive:
|
|
query = query.where(RepositoryBuild.phase != BUILD_PHASE.ERROR,
|
|
RepositoryBuild.phase != BUILD_PHASE.COMPLETE)
|
|
|
|
return query
|
|
|
|
|
|
def get_recent_repository_build(namespace_name, repository_name):
|
|
query = list_repository_builds(namespace_name, repository_name, 1)
|
|
try:
|
|
return query.get()
|
|
except RepositoryBuild.DoesNotExist:
|
|
return None
|
|
|
|
|
|
def create_repository_build(repo, access_token, job_config_obj, dockerfile_id,
|
|
display_name, trigger=None, pull_robot_name=None):
|
|
pull_robot = None
|
|
if pull_robot_name:
|
|
pull_robot = user_model.lookup_robot(pull_robot_name)
|
|
|
|
return RepositoryBuild.create(repository=repo, access_token=access_token,
|
|
job_config=json.dumps(job_config_obj),
|
|
display_name=display_name, trigger=trigger,
|
|
resource_key=dockerfile_id,
|
|
pull_robot=pull_robot)
|
|
|
|
|
|
def get_pull_robot_name(trigger):
|
|
if not trigger.pull_robot:
|
|
return None
|
|
|
|
return trigger.pull_robot.username
|
|
|
|
|
|
def cancel_repository_build(build, work_queue):
|
|
with db_transaction():
|
|
# Reload the build for update.
|
|
try:
|
|
build = db_for_update(RepositoryBuild.select().where(RepositoryBuild.id == build.id)).get()
|
|
except RepositoryBuild.DoesNotExist:
|
|
return False
|
|
|
|
if build.phase != BUILD_PHASE.WAITING or not build.queue_id:
|
|
return False
|
|
|
|
# Try to cancel the queue item.
|
|
if not work_queue.cancel(build.queue_id):
|
|
return False
|
|
|
|
# Delete the build row.
|
|
build.delete_instance()
|
|
return True
|
|
|
|
|
|
def get_archivable_build():
|
|
presumed_dead_date = datetime.utcnow() - PRESUMED_DEAD_BUILD_AGE
|
|
candidates = (RepositoryBuild
|
|
.select(RepositoryBuild.id)
|
|
.where((RepositoryBuild.phase == BUILD_PHASE.COMPLETE) |
|
|
(RepositoryBuild.phase == BUILD_PHASE.ERROR) |
|
|
(RepositoryBuild.started < presumed_dead_date),
|
|
RepositoryBuild.logs_archived == False)
|
|
.limit(50)
|
|
.alias('candidates'))
|
|
|
|
try:
|
|
found_id = (RepositoryBuild
|
|
.select(candidates.c.id)
|
|
.from_(candidates)
|
|
.order_by(db_random_func())
|
|
.get())
|
|
return RepositoryBuild.get(id=found_id)
|
|
except RepositoryBuild.DoesNotExist:
|
|
return None
|
|
|