base.py
124 lines
| 4.3 KiB
| text/x-python
|
PythonLexer
r5607 | # Copyright (C) 2010-2024 RhodeCode GmbH | |||
r5325 | # | |||
# This program is free software: you can redistribute it and/or modify | ||||
# it under the terms of the GNU Affero General Public License, version 3 | ||||
# (only), as published by the Free Software Foundation. | ||||
# | ||||
# This program is distributed in the hope that it will be useful, | ||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
# GNU General Public License for more details. | ||||
# | ||||
# You should have received a copy of the GNU Affero General Public License | ||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
# | ||||
# This program is dual-licensed. If you wish to learn more about the | ||||
# RhodeCode Enterprise Edition, including its added features, Support services, | ||||
# and proprietary license terms, please see https://rhodecode.com/licenses/ | ||||
r5459 | ||||
r5325 | import logging | |||
r5607 | import traceback | |||
r5325 | ||||
r5607 | from rhodecode.model import meta | |||
from rhodecode.lib import hooks_base | ||||
from rhodecode.lib.utils2 import AttributeDict | ||||
from rhodecode.lib.exceptions import HTTPLockedRepo, HTTPBranchProtected | ||||
r5459 | ||||
r5325 | ||||
log = logging.getLogger(__name__) | ||||
class BaseHooksCallbackDaemon: | ||||
""" | ||||
Basic context manager for actions that don't require some extra | ||||
""" | ||||
def __init__(self): | ||||
pass | ||||
def __enter__(self): | ||||
log.debug('Running `%s` callback daemon', self.__class__.__name__) | ||||
return self | ||||
def __exit__(self, exc_type, exc_val, exc_tb): | ||||
log.debug('Exiting `%s` callback daemon', self.__class__.__name__) | ||||
r5607 | class Hooks(object): | |||
""" | ||||
Exposes the hooks module for calling them using the local HooksModuleCallbackDaemon | ||||
""" | ||||
def __init__(self, request=None, log_prefix=''): | ||||
self.log_prefix = log_prefix | ||||
self.request = request | ||||
r5325 | ||||
r5607 | def repo_size(self, extras): | |||
log.debug("%sCalled repo_size of %s object", self.log_prefix, self) | ||||
return self._call_hook(hooks_base.repo_size, extras) | ||||
r5325 | ||||
r5607 | def pre_pull(self, extras): | |||
log.debug("%sCalled pre_pull of %s object", self.log_prefix, self) | ||||
return self._call_hook(hooks_base.pre_pull, extras) | ||||
r5325 | ||||
r5607 | def post_pull(self, extras): | |||
log.debug("%sCalled post_pull of %s object", self.log_prefix, self) | ||||
return self._call_hook(hooks_base.post_pull, extras) | ||||
def pre_push(self, extras): | ||||
log.debug("%sCalled pre_push of %s object", self.log_prefix, self) | ||||
return self._call_hook(hooks_base.pre_push, extras) | ||||
r5459 | ||||
r5607 | def post_push(self, extras): | |||
log.debug("%sCalled post_push of %s object", self.log_prefix, self) | ||||
return self._call_hook(hooks_base.post_push, extras) | ||||
def _call_hook(self, hook, extras): | ||||
extras = AttributeDict(extras) | ||||
_server_url = extras['server_url'] | ||||
r5459 | ||||
r5607 | extras.request = self.request | |||
try: | ||||
result = hook(extras) | ||||
if result is None: | ||||
raise Exception(f'Failed to obtain hook result from func: {hook}') | ||||
except HTTPBranchProtected as error: | ||||
# Those special cases don't need error reporting. It's a case of | ||||
# locked repo or protected branch | ||||
result = AttributeDict({ | ||||
'status': error.code, | ||||
'output': error.explanation | ||||
}) | ||||
except HTTPLockedRepo as error: | ||||
# Those special cases don't need error reporting. It's a case of | ||||
# locked repo or protected branch | ||||
result = AttributeDict({ | ||||
'status': error.code, | ||||
'output': error.explanation | ||||
}) | ||||
except Exception as error: | ||||
# locked needs different handling since we need to also | ||||
# handle PULL operations | ||||
log.exception('%sException when handling hook %s', self.log_prefix, hook) | ||||
exc_tb = traceback.format_exc() | ||||
error_args = error.args | ||||
return { | ||||
'status': 128, | ||||
'output': '', | ||||
'exception': type(error).__name__, | ||||
'exception_traceback': exc_tb, | ||||
'exception_args': error_args, | ||||
} | ||||
finally: | ||||
meta.Session.remove() | ||||
r5589 | ||||
r5607 | log.debug('%sGot hook call response %s', self.log_prefix, result) | |||
return { | ||||
'status': result.status, | ||||
'output': result.output, | ||||
} | ||||
r5325 | ||||
r5607 | def __enter__(self): | |||
return self | ||||
r5325 | ||||
r5607 | def __exit__(self, exc_type, exc_val, exc_tb): | |||
pass | ||||