[PATCH 3 of 3 v2] hooks: fix potentially invalid interpreter in git hooks (Issue #333)

Thomas De Schampheleire patrickdepinguin at gmail.com
Wed Apr 3 20:28:31 UTC 2019


# HG changeset patch
# User Thomas De Schampheleire <thomas.de_schampheleire at nokia.com>
# Date 1554323208 -7200
#      Wed Apr 03 22:26:48 2019 +0200
# Branch stable
# Node ID 0d91f710606b72027456a1183794ee38f26fe741
# Parent  06b511848fb1a3ead56de583e19df5f317bdf7e0
hooks: fix potentially invalid interpreter in git hooks (Issue #333)

Commit 5e501b6ee639 introduced the use of 'sys.executable' as interpreter
for git hooks instead of 'python2' with the following argument:

    "Windows doesn't necessarily have "python2" available in $PATH, but we
    still want to make sure we don't end up invoking a python3. Using the
    absolute path seems more safe."

But, sys.executable does not necessarily point to Python. When Kallithea is
started under uWSGI, sys.executable points to the uwsgi executable. As a
result, the interpreter encoded in the git hooks on the server repositories
would be:

    #!/usr/bin/env /path/to/uwsgi

And pushing to such repo would result in following client errors:

    $ git push
    Password for 'http://user@localhost:5050':
    Enumerating objects: 3, done.
    Counting objects: 100% (3/3), done.
    Writing objects: 100% (3/3), 241 bytes | 241.00 KiB/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    remote: unable to load configuration from hooks/pre-receive
    To http://localhost:5050/gitrepo-new
     ! [remote rejected] master -> master (pre-receive hook declined)
    error: failed to push some refs to 'http://user@localhost:5050/gitrepo-new'


The approach taken by this commit is:

- Introduce a new configuration setting: hook_python_path, and use its value
  as the Python interpreter to use in git hooks.
- If the value is absent or empty, fall back to the current logic
  'sys.executable' or if that is also invalid, 'python2'.
- Let `kallithea-cli config-create` fill in its own interpreter as default
  value, which should be valid as long as the virtual environment is not
  moved/replaced.
- To avoid private paths being encoded in development.ini, pass an empty
  default value.

The main downside of this approach is its fragility in case a new virtualenv
is used. Previously, the configuration file was the same regardless of
virtualenv, but this is no longer true after this patch.

Suggested-by: Mads Kiilerich <mads at kiilerich.com>

diff --git a/development.ini b/development.ini
--- a/development.ini
+++ b/development.ini
@@ -117,6 +117,16 @@ use_htsts = false
 ## number of commits stats will parse on each iteration
 commit_parse_limit = 25
 
+## Path to Python executable to be used in git hooks.
+## When empty, the value of 'sys.executable' at the time of installation
+## of the git hooks is used, which is correct in many cases but not when
+## using uwsgi.
+## When creating a config file via `kallithea-cli config-create`, the
+## Python executable used for that invocation is filled in below.
+## If you change this setting, you should reinstall the git hooks via
+## Admin > Settings > Remap and Rescan.
+hook_python_path =
+
 ## path to git executable
 git_path = git
 
diff --git a/kallithea/lib/inifile.py b/kallithea/lib/inifile.py
--- a/kallithea/lib/inifile.py
+++ b/kallithea/lib/inifile.py
@@ -23,6 +23,7 @@ other custom values.
 import logging
 import re
 import os
+import sys
 
 import mako.template
 
@@ -40,6 +41,7 @@ default_variables = {
     'host': '127.0.0.1',
     'port': '5000',
     'uuid': lambda: 'VERY-SECRET',
+    'python_executable': sys.executable or '',
 }
 
 
diff --git a/kallithea/lib/paster_commands/template.ini.mako b/kallithea/lib/paster_commands/template.ini.mako
--- a/kallithea/lib/paster_commands/template.ini.mako
+++ b/kallithea/lib/paster_commands/template.ini.mako
@@ -211,6 +211,16 @@ use_htsts = false
 <%text>## number of commits stats will parse on each iteration</%text>
 commit_parse_limit = 25
 
+<%text>## Path to Python executable to be used in git hooks.</%text>
+<%text>## When empty, the value of 'sys.executable' at the time of installation</%text>
+<%text>## of the git hooks is used, which is correct in many cases but not when</%text>
+<%text>## using uwsgi.</%text>
+<%text>## When creating a config file via `kallithea-cli config-create`, the</%text>
+<%text>## Python executable used for that invocation is filled in below.</%text>
+<%text>## If you change this setting, you should reinstall the git hooks via</%text>
+<%text>## Admin > Settings > Remap and Rescan.</%text>
+hook_python_path = ${python_executable}
+
 <%text>## path to git executable</%text>
 git_path = git
 
diff --git a/kallithea/model/scm.py b/kallithea/model/scm.py
--- a/kallithea/model/scm.py
+++ b/kallithea/model/scm.py
@@ -721,8 +721,11 @@ class ScmModel(object):
         return choices, hist_l
 
     def _get_python_executable(self):
-        """Return a Python executable for use in hooks."""
-        return sys.executable or 'python2'
+        """Return a Python executable for use in hooks.
+
+        This is not simply sys.executable because under uwsgi it will be the
+        uwsgi program itself."""
+        return kallithea.CONFIG.get('hook_python_path', sys.executable) or 'python2'
 
     def install_git_hooks(self, repo, force_create=False):
         """
diff --git a/scripts/generate-ini.py b/scripts/generate-ini.py
--- a/scripts/generate-ini.py
+++ b/scripts/generate-ini.py
@@ -48,6 +48,7 @@ ini_files = [
             },
         },
         {
+            'python_executable': '',
         },
     ),
 ]


More information about the kallithea-general mailing list