113 lines
No EOL
2.8 KiB
Python
113 lines
No EOL
2.8 KiB
Python
import logging
|
|
import io
|
|
|
|
from github import Github
|
|
from tempfile import SpooledTemporaryFile
|
|
|
|
from app import app
|
|
|
|
|
|
user_files = app.config['USERFILES']
|
|
client = app.config['HTTPCLIENT']
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
ZIPBALL = 'application/zip'
|
|
CHUNK_SIZE = 512 * 1024
|
|
|
|
|
|
class BuildArchiveException(Exception):
|
|
pass
|
|
|
|
|
|
class InvalidServiceException(Exception):
|
|
pass
|
|
|
|
|
|
class BuildTrigger(object):
|
|
def __init__(self):
|
|
pass
|
|
|
|
def list_build_sources(self, auth_token):
|
|
"""
|
|
Take the auth information for the specific trigger type and load the
|
|
list of build sources(repositories).
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
def handle_trigger_request(self, request, auth_token, config):
|
|
"""
|
|
Transform the incoming request data into a set of actions.
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
@classmethod
|
|
def service_name(cls):
|
|
"""
|
|
Particular service implemented by subclasses.
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
@classmethod
|
|
def get_trigger_for_service(cls, service):
|
|
for subc in cls.__subclasses__():
|
|
if subc.service_name() == service:
|
|
return subc()
|
|
|
|
raise InvalidServiceException('Unable to find service: %s' % service)
|
|
|
|
|
|
def raise_unsupported():
|
|
raise io.UnsupportedOperation
|
|
|
|
|
|
class GithubBuildTrigger(BuildTrigger):
|
|
@staticmethod
|
|
def _get_client(auth_token):
|
|
return Github(auth_token, client_id=app.config['GITHUB_CLIENT_ID'],
|
|
client_secret=app.config['GITHUB_CLIENT_SECRET'])
|
|
|
|
@classmethod
|
|
def service_name(cls):
|
|
return 'github'
|
|
|
|
def list_build_sources(self, auth_token):
|
|
gh_client = self._get_client(auth_token)
|
|
usr = gh_client.get_user()
|
|
|
|
repo_list = [repo.full_name for repo in usr.get_repos()]
|
|
for org in usr.get_orgs():
|
|
repo_list.extend((repo.full_name for repo in org.get_repos()))
|
|
|
|
return repo_list
|
|
|
|
def handle_trigger_request(self, request, auth_token, config):
|
|
payload = request.get_json()
|
|
logger.debug('Payload %s', payload)
|
|
ref = payload['ref']
|
|
commit_id = payload['head_commit']['id'][0:7]
|
|
|
|
gh_client = self._get_client(auth_token)
|
|
|
|
repo_full_name = '%s/%s' % (payload['repository']['owner']['name'],
|
|
payload['repository']['name'])
|
|
repo = gh_client.get_repo(repo_full_name)
|
|
|
|
logger.debug('Github repo: %s', repo)
|
|
|
|
# Prepare the download and upload URLs
|
|
branch_name = ref.split('/')[-1]
|
|
archive_link = repo.get_archive_link('zipball', branch_name)
|
|
download_archive = client.get(archive_link, stream=True)
|
|
|
|
with SpooledTemporaryFile(CHUNK_SIZE) as zipball:
|
|
for chunk in download_archive.iter_content(CHUNK_SIZE):
|
|
zipball.write(chunk)
|
|
|
|
dockerfile_id = user_files.store_file(zipball, ZIPBALL)
|
|
|
|
logger.debug('Successfully prepared job')
|
|
|
|
return dockerfile_id, branch_name, commit_id |