Merge pull request #636 from jzelinskie/timeouts

raise a 520 for any GitLab timeouts
This commit is contained in:
Jimmy Zelinskie 2015-10-13 17:36:38 -04:00
commit d0fcfa6d6a
2 changed files with 31 additions and 0 deletions

View file

@ -1,5 +1,7 @@
import logging import logging
from functools import wraps
from app import app from app import app
from jsonschema import validate from jsonschema import validate
@ -13,8 +15,10 @@ from buildtrigger.basehandler import BuildTriggerHandler
from util.security.ssh import generate_ssh_keypair from util.security.ssh import generate_ssh_keypair
from util.dict_wrappers import JSONPathDict, SafeDictSetter from util.dict_wrappers import JSONPathDict, SafeDictSetter
from endpoints.api import ExternalServiceTimeout
import gitlab import gitlab
import requests
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -68,6 +72,18 @@ GITLAB_WEBHOOK_PAYLOAD_SCHEMA = {
'required': ['ref', 'checkout_sha', 'repository'], 'required': ['ref', 'checkout_sha', 'repository'],
} }
def _catch_timeouts(func):
@wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except requests.exceptions.Timeout:
msg = 'Request to the GitLab API timed out'
logger.exception(msg)
raise ExternalServiceTimeout(msg)
return wrapper
def get_transformed_webhook_payload(gl_payload, default_branch=None, lookup_user=None): def get_transformed_webhook_payload(gl_payload, default_branch=None, lookup_user=None):
""" Returns the Gitlab webhook JSON payload transformed into our own payload """ Returns the Gitlab webhook JSON payload transformed into our own payload
format. If the gl_payload is not valid, returns None. format. If the gl_payload is not valid, returns None.
@ -118,6 +134,7 @@ class GitLabBuildTrigger(BuildTriggerHandler):
def is_active(self): def is_active(self):
return 'hook_id' in self.config return 'hook_id' in self.config
@_catch_timeouts
def activate(self, standard_webhook_url): def activate(self, standard_webhook_url):
config = self.config config = self.config
new_build_source = config['build_source'] new_build_source = config['build_source']
@ -182,6 +199,7 @@ class GitLabBuildTrigger(BuildTriggerHandler):
return config return config
@_catch_timeouts
def list_build_sources(self): def list_build_sources(self):
gl_client = self._get_authorized_client() gl_client = self._get_authorized_client()
current_user = gl_client.currentuser() current_user = gl_client.currentuser()
@ -208,6 +226,7 @@ class GitLabBuildTrigger(BuildTriggerHandler):
return namespaces.values() return namespaces.values()
@_catch_timeouts
def list_build_subdirs(self): def list_build_subdirs(self):
config = self.config config = self.config
gl_client = self._get_authorized_client() gl_client = self._get_authorized_client()
@ -238,6 +257,7 @@ class GitLabBuildTrigger(BuildTriggerHandler):
return [] return []
@_catch_timeouts
def load_dockerfile_contents(self): def load_dockerfile_contents(self):
gl_client = self._get_authorized_client() gl_client = self._get_authorized_client()
path = self.get_dockerfile_path() path = self.get_dockerfile_path()
@ -261,6 +281,7 @@ class GitLabBuildTrigger(BuildTriggerHandler):
return contents return contents
@_catch_timeouts
def list_field_values(self, field_name, limit=None): def list_field_values(self, field_name, limit=None):
if field_name == 'refs': if field_name == 'refs':
branches = self.list_field_values('branch_name') branches = self.list_field_values('branch_name')
@ -299,6 +320,7 @@ class GitLabBuildTrigger(BuildTriggerHandler):
def get_repository_url(self): def get_repository_url(self):
return 'https://gitlab.com/%s' % self.config['build_source'] return 'https://gitlab.com/%s' % self.config['build_source']
@_catch_timeouts
def lookup_user(self, email): def lookup_user(self, email):
gl_client = self._get_authorized_client() gl_client = self._get_authorized_client()
try: try:
@ -312,6 +334,7 @@ class GitLabBuildTrigger(BuildTriggerHandler):
except ValueError: except ValueError:
return None return None
@_catch_timeouts
def get_metadata_for_commit(self, commit_sha, ref, repo): def get_metadata_for_commit(self, commit_sha, ref, repo):
gl_client = self._get_authorized_client() gl_client = self._get_authorized_client()
commit = gl_client.getrepositorycommit(repo['id'], commit_sha) commit = gl_client.getrepositorycommit(repo['id'], commit_sha)
@ -352,6 +375,7 @@ class GitLabBuildTrigger(BuildTriggerHandler):
return metadata return metadata
@_catch_timeouts
def manual_start(self, run_parameters=None): def manual_start(self, run_parameters=None):
gl_client = self._get_authorized_client() gl_client = self._get_authorized_client()
@ -384,6 +408,7 @@ class GitLabBuildTrigger(BuildTriggerHandler):
metadata = self.get_metadata_for_commit(commit_sha, ref, repo) metadata = self.get_metadata_for_commit(commit_sha, ref, repo)
return self.prepare_build(metadata, is_manual=True) return self.prepare_build(metadata, is_manual=True)
@_catch_timeouts
def handle_trigger_request(self, request): def handle_trigger_request(self, request):
payload = request.get_json() payload = request.get_json()
if not payload: if not payload:

View file

@ -49,10 +49,16 @@ class ApiException(Exception):
return rv return rv
class ExternalServiceTimeout(ApiException):
def __init__(self, error_description, payload=None):
ApiException.__init__(self, 'external_service_timeout', 520, error_description, payload)
class InvalidRequest(ApiException): class InvalidRequest(ApiException):
def __init__(self, error_description, payload=None): def __init__(self, error_description, payload=None):
ApiException.__init__(self, 'invalid_request', 400, error_description, payload) ApiException.__init__(self, 'invalid_request', 400, error_description, payload)
class InvalidResponse(ApiException): class InvalidResponse(ApiException):
def __init__(self, error_description, payload=None): def __init__(self, error_description, payload=None):
ApiException.__init__(self, 'invalid_response', 400, error_description, payload) ApiException.__init__(self, 'invalid_response', 400, error_description, payload)