80 lines
2.7 KiB
Python
80 lines
2.7 KiB
Python
import json
|
|
|
|
from cachetools import lru_cache
|
|
from endpoints.notificationhelper import spawn_notification
|
|
from data import model
|
|
|
|
|
|
class BuildJobLoadException(Exception):
|
|
""" Exception raised if a build job could not be instantiated for some reason. """
|
|
pass
|
|
|
|
class BuildJob(object):
|
|
""" Represents a single in-progress build job. """
|
|
def __init__(self, job_item):
|
|
self.job_item = job_item
|
|
|
|
try:
|
|
self.job_details = json.loads(job_item.body)
|
|
except ValueError:
|
|
raise BuildJobLoadException(
|
|
'Could not parse build queue item config with ID %s' % self.job_details['build_uuid']
|
|
)
|
|
|
|
def send_notification(self, kind, error_message=None):
|
|
tags = self.build_config.get('docker_tags', ['latest'])
|
|
event_data = {
|
|
'build_id': self.repo_build.uuid,
|
|
'build_name': self.repo_build.display_name,
|
|
'docker_tags': tags,
|
|
'trigger_id': self.repo_build.trigger.uuid,
|
|
'trigger_kind': self.repo_build.trigger.service.name
|
|
}
|
|
|
|
if error_message is not None:
|
|
event_data['error_message'] = error_message
|
|
|
|
spawn_notification(self.repo_build.repository, kind, event_data,
|
|
subpage='build?current=%s' % self.repo_build.uuid,
|
|
pathargs=['build', self.repo_build.uuid])
|
|
|
|
|
|
@lru_cache(maxsize=1)
|
|
def _load_repo_build(self):
|
|
try:
|
|
return model.get_repository_build(self.job_details['build_uuid'])
|
|
except model.InvalidRepositoryBuildException:
|
|
raise BuildJobLoadException(
|
|
'Could not load repository build with ID %s' % self.job_details['build_uuid'])
|
|
|
|
@property
|
|
def repo_build(self):
|
|
return self._load_repo_build()
|
|
|
|
@property
|
|
def pull_credentials(self):
|
|
""" Returns the pull credentials for this job, or None if none. """
|
|
return self.job_details.get('pull_credentials')
|
|
|
|
@property
|
|
def build_config(self):
|
|
try:
|
|
return json.loads(self.repo_build.job_config)
|
|
except ValueError:
|
|
raise BuildJobLoadException(
|
|
'Could not parse repository build job config with ID %s' % self.job_details['build_uuid']
|
|
)
|
|
|
|
def determine_cached_tag(self):
|
|
""" Returns the tag to pull to prime the cache or None if none. """
|
|
# TODO(jschorr): Change this to use the more complicated caching rules, once we have caching
|
|
# be a pull of things besides the constructed tags.
|
|
tags = self.build_config.get('docker_tags', ['latest'])
|
|
existing_tags = model.list_repository_tags(self.repo_build.repository.namespace_user.username,
|
|
self.repo_build.repository.name)
|
|
|
|
cached_tags = set(tags) & set([tag.name for tag in existing_tags])
|
|
if cached_tags:
|
|
return list(cached_tags)[0]
|
|
|
|
return None
|