Get build preparation working for bitbucket and do a lot of code cleanup around this process across all the triggers. Note: tests are not yet updated.
This commit is contained in:
parent
6479f8ddc9
commit
d5c70878c5
6 changed files with 432 additions and 226 deletions
186
endpoints/building.py
Normal file
186
endpoints/building.py
Normal file
|
@ -0,0 +1,186 @@
|
|||
import logging
|
||||
import json
|
||||
|
||||
from app import app, dockerfile_build_queue
|
||||
from data import model
|
||||
from data.database import db
|
||||
from auth.auth_context import get_authenticated_user
|
||||
from endpoints.notificationhelper import spawn_notification
|
||||
from flask import request
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def start_build(repository, prepared_build, pull_robot_name=None):
|
||||
host = app.config['SERVER_HOSTNAME']
|
||||
repo_path = '%s/%s/%s' % (host, repository.namespace_user.username, repository.name)
|
||||
|
||||
token = model.create_access_token(repository, 'write', kind='build-worker',
|
||||
friendly_name='Repository Build Token')
|
||||
logger.debug('Creating build %s with repo %s tags %s',
|
||||
prepared_build.build_name, repo_path, prepared_build.tags)
|
||||
|
||||
job_config = {
|
||||
'docker_tags': prepared_build.tags,
|
||||
'registry': host,
|
||||
'build_subdir': prepared_build.subdirectory,
|
||||
'trigger_metadata': prepared_build.metadata or {},
|
||||
'is_manual': prepared_build.is_manual,
|
||||
'manual_user': get_authenticated_user().username if get_authenticated_user() else None
|
||||
}
|
||||
|
||||
with app.config['DB_TRANSACTION_FACTORY'](db):
|
||||
build_request = model.create_repository_build(repository, token, job_config,
|
||||
prepared_build.dockerfile_id,
|
||||
prepared_build.build_name,
|
||||
prepared_build.trigger,
|
||||
pull_robot_name=pull_robot_name)
|
||||
|
||||
json_data = json.dumps({
|
||||
'build_uuid': build_request.uuid,
|
||||
'pull_credentials': model.get_pull_credentials(pull_robot_name) if pull_robot_name else None
|
||||
})
|
||||
|
||||
queue_id = dockerfile_build_queue.put([repository.namespace_user.username, repository.name],
|
||||
json_data,
|
||||
retries_remaining=3)
|
||||
|
||||
build_request.queue_id = queue_id
|
||||
build_request.save()
|
||||
|
||||
# Add the build to the repo's log and spawn the build_queued notification.
|
||||
event_log_metadata = {
|
||||
'build_uuid': build_request.uuid,
|
||||
'docker_tags': prepared_build.tags,
|
||||
'repo': repository.name,
|
||||
'namespace': repository.namespace_user.username,
|
||||
'is_manual': prepared_build.is_manual,
|
||||
'manual_user': get_authenticated_user().username if get_authenticated_user() else None
|
||||
}
|
||||
|
||||
if prepared_build.trigger:
|
||||
event_log_metadata['trigger_id'] = prepared_build.trigger.uuid
|
||||
event_log_metadata['trigger_kind'] = prepared_build.trigger.service.name
|
||||
|
||||
model.log_action('build_dockerfile', repository.namespace_user.username, ip=request.remote_addr,
|
||||
metadata=event_log_metadata, repository=repository)
|
||||
|
||||
spawn_notification(repository, 'build_queued', event_log_metadata,
|
||||
subpage='build?current=%s' % build_request.uuid,
|
||||
pathargs=['build', build_request.uuid])
|
||||
|
||||
return build_request
|
||||
|
||||
|
||||
class PreparedBuild(object):
|
||||
""" Class which holds all the information about a prepared build. The build queuing service
|
||||
will use this result to actually invoke the build.
|
||||
"""
|
||||
def __init__(self, trigger=None):
|
||||
self._dockerfile_id = None
|
||||
self._tags = None
|
||||
self._build_name = None
|
||||
self._subdirectory = None
|
||||
self._metadata = None
|
||||
self._trigger = trigger
|
||||
self._is_manual = None
|
||||
|
||||
@staticmethod
|
||||
def get_display_name(sha):
|
||||
return sha[0:7]
|
||||
|
||||
def tags_from_ref(self, ref, default_branch='master'):
|
||||
branch = ref.split('/')[-1]
|
||||
tags = {branch}
|
||||
|
||||
if branch == default_branch:
|
||||
tags.add('latest')
|
||||
|
||||
self.tags = tags
|
||||
|
||||
def name_from_sha(self, sha):
|
||||
self.build_name = PreparedBuild.get_display_name(sha)
|
||||
|
||||
@property
|
||||
def is_manual(self):
|
||||
if self._is_manual is None:
|
||||
raise Exception('Property is_manual not set')
|
||||
|
||||
return self._is_manual
|
||||
|
||||
@is_manual.setter
|
||||
def is_manual(self, value):
|
||||
if self._is_manual is not None:
|
||||
raise Exception('Property is_manual already set')
|
||||
|
||||
self._is_manual = value
|
||||
|
||||
@property
|
||||
def trigger(self):
|
||||
return self._trigger
|
||||
|
||||
@property
|
||||
def dockerfile_id(self):
|
||||
return self._dockerfile_id
|
||||
|
||||
@dockerfile_id.setter
|
||||
def dockerfile_id(self, value):
|
||||
if self._dockerfile_id:
|
||||
raise Exception('Property dockerfile_id already set')
|
||||
|
||||
self._dockerfile_id = value
|
||||
|
||||
@property
|
||||
def tags(self):
|
||||
if not self._tags:
|
||||
raise Exception('Missing property tags')
|
||||
|
||||
return self._tags
|
||||
|
||||
@tags.setter
|
||||
def tags(self, value):
|
||||
if self._tags:
|
||||
raise Exception('Property tags already set')
|
||||
|
||||
self._tags = list(value)
|
||||
|
||||
@property
|
||||
def build_name(self):
|
||||
if not self._build_name:
|
||||
raise Exception('Missing property build_name')
|
||||
|
||||
return self._build_name
|
||||
|
||||
@build_name.setter
|
||||
def build_name(self, value):
|
||||
if self._build_name:
|
||||
raise Exception('Property build_name already set')
|
||||
|
||||
self._build_name = value
|
||||
|
||||
@property
|
||||
def subdirectory(self):
|
||||
if self._subdirectory is None:
|
||||
raise Exception('Missing property subdirectory')
|
||||
|
||||
return self._subdirectory
|
||||
|
||||
@subdirectory.setter
|
||||
def subdirectory(self, value):
|
||||
if self._subdirectory:
|
||||
raise Exception('Property subdirectory already set')
|
||||
|
||||
self._subdirectory = value
|
||||
|
||||
@property
|
||||
def metadata(self):
|
||||
if self._metadata is None:
|
||||
raise Exception('Missing property metadata')
|
||||
|
||||
return self._metadata
|
||||
|
||||
@metadata.setter
|
||||
def metadata(self, value):
|
||||
if self._metadata:
|
||||
raise Exception('Property metadata already set')
|
||||
|
||||
self._metadata = value
|
Reference in a new issue