# HG changeset patch # User Mads Kiilerich # Date 2019-12-29 01:41:47 # Node ID ba6418fde72f286a95f207fb14eeeee2ac788a55 # Parent 488b52cad8905eac29645b8dad77117bfd73184d git: more elegant handling of installed pre/post-receive hook failing on direct repo access The hook would fail with a long backtrace when get_hook_environment raise an error exception. Instead, as first thing in the entry point from the hook, catch that situation and report it nicely before "quietly" skipping the hook: [mk@here myrepo]$ git push Enumerating objects: 3, done. Counting objects: 100% (3/3), done. Writing objects: 100% (3/3), 204 bytes | 204.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) remote: Skipping Kallithea Git post-recieve hook 'hooks/post-receive'. remote: Git was apparently not invoked by Kallithea: Environment variable KALLITHEA_EXTRAS not found To /tmp/somerepo * [new branch] master -> master [mk@here myrepo]$ We could be paranoid and let it (and the pre hook) fail ... but that doesn't seem helpful. Reported by Edmund Wong at [1]. [1] https://lists.sfconservancy.org/pipermail/kallithea-general/2019q4/003071.html diff --git a/kallithea/lib/hooks.py b/kallithea/lib/hooks.py --- a/kallithea/lib/hooks.py +++ b/kallithea/lib/hooks.py @@ -27,12 +27,13 @@ Original author and date, and relevant c import binascii import os +import sys import time from kallithea.lib import helpers as h from kallithea.lib.exceptions import UserCreationError from kallithea.lib.utils import action_logger, make_ui, setup_cache_regions -from kallithea.lib.utils2 import get_hook_environment, safe_str, safe_unicode +from kallithea.lib.utils2 import HookEnvironmentError, get_hook_environment, safe_str, safe_unicode from kallithea.lib.vcs.backends.base import EmptyChangeset from kallithea.lib.vcs.utils.hgcompat import revrange from kallithea.model.db import Repository, User @@ -340,7 +341,11 @@ def handle_git_pre_receive(repo_path, gi def handle_git_post_receive(repo_path, git_stdin_lines): """Called from Git post-receive hook""" - baseui, repo = _hook_environment(repo_path) + try: + baseui, repo = _hook_environment(repo_path) + except HookEnvironmentError as e: + sys.stderr.write("Skipping Kallithea Git post-recieve hook %r.\nGit was apparently not invoked by Kallithea: %s\n" % (sys.argv[0], e)) + return 0 # the post push hook should never use the cached instance scm_repo = repo.scm_instance_no_cache() diff --git a/kallithea/lib/utils2.py b/kallithea/lib/utils2.py --- a/kallithea/lib/utils2.py +++ b/kallithea/lib/utils2.py @@ -522,6 +522,9 @@ def obfuscate_url_pw(engine): return str(_url) +class HookEnvironmentError(Exception): pass + + def get_hook_environment(): """ Get hook context by deserializing the global KALLITHEA_EXTRAS environment @@ -535,13 +538,13 @@ def get_hook_environment(): try: extras = json.loads(os.environ['KALLITHEA_EXTRAS']) except KeyError: - raise Exception("Environment variable KALLITHEA_EXTRAS not found") + raise HookEnvironmentError("Environment variable KALLITHEA_EXTRAS not found") try: for k in ['username', 'repository', 'scm', 'action', 'ip']: extras[k] except KeyError: - raise Exception('Missing key %s in KALLITHEA_EXTRAS %s' % (k, extras)) + raise HookEnvironmentError('Missing key %s in KALLITHEA_EXTRAS %s' % (k, extras)) return AttributeDict(extras)