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

Thomas De Schampheleire patrickdepinguin at gmail.com
Mon Apr 1 20:25:31 UTC 2019


# HG changeset patch
# User Thomas De Schampheleire <thomas.de_schampheleire at nokia.com>
# Date 1554150088 -7200
#      Mon Apr 01 22:21:28 2019 +0200
# Branch stable
# Node ID 83678cb1c0fa84473f686d94867c777c2671632b
# Parent  953047e8c88a9c5ccaa4ddc1bb417622de37f01f
hooks: fix potentially invalid interpreter in git hooks (Issue #333)

Commit 5e501b6ee639c2cf25080ba8c3d53f4e4b6ad32e 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 git hooks did not work in this case:

    $ 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'

Try to determine a better interpreter for the git hooks by covering multiple
cases.

In the case of Windows without virtualenv, we are not 100% sure that the
value will be valid. More heuristics could be added there, but if we can
assume that most installations on Windows will effectively use a virtualenv,
which have their own handling in the new code, it may not be worth the
complexity.

diff --git a/kallithea/model/scm.py b/kallithea/model/scm.py
--- a/kallithea/model/scm.py
+++ b/kallithea/model/scm.py
@@ -720,6 +720,30 @@ class ScmModel(object):
 
         return choices, hist_l
 
+    def _get_python_executable(self):
+        """Return a Python executable for use in hooks
+
+        This is not simply sys.executable as that points to uwsgi if using
+        uwsgi.
+
+        The returned string is valid when run in the current PATH, it is not
+        necessarily a full path by itself.
+        """
+        # If we are running in a virtualenv, the python in the PATH is the
+        # right one
+        if 'VIRTUAL_ENV' in os.environ:
+            return 'python'
+
+        # On Windows, there is no 'python2' executable. We'll use 'python' and
+        # hope that the user has set their PATH correctly so it points to
+        # Python 2, not Python 3.
+        if kallithea.is_windows:
+            return 'python'
+
+        # On Unix, outside of a virtualenv, there should be a 'python2'
+        # executable in the PATH
+        return 'python2'
+
     def install_git_hooks(self, repo, force_create=False):
         """
         Creates a kallithea hook inside a git repository
@@ -734,11 +758,11 @@ class ScmModel(object):
         if not os.path.isdir(loc):
             os.makedirs(loc)
 
-        tmpl_post = "#!/usr/bin/env %s\n" % sys.executable or 'python2'
+        tmpl_post = "#!/usr/bin/env %s\n" % self._get_python_executable()
         tmpl_post += pkg_resources.resource_string(
             'kallithea', os.path.join('config', 'post_receive_tmpl.py')
         )
-        tmpl_pre = "#!/usr/bin/env %s\n" % sys.executable or 'python2'
+        tmpl_pre = "#!/usr/bin/env %s\n" % self._get_python_executable()
         tmpl_pre += pkg_resources.resource_string(
             'kallithea', os.path.join('config', 'pre_receive_tmpl.py')
         )


More information about the kallithea-general mailing list