git: Support setup of the hooks directory at runtime
Gitaly's hooks are currently located in the Ruby directory, which we can (hopefully) get rid off soon. As a consequence, we also need to move our hooks somewhere else. While we could just create a different on-disk directory which is installed alongside with Gitaly, this creates more complexity than is worth it. Instead, we can just set up the hook directory at runtime by creating a temporary directory which has all the necessary hooks set up. Like this, we have one thing less that needs to be configured given that the only configuration we need for this to work is the location of the "gitaly-hooks" binary, which is easily derived from the binary path.
This new temporary directory is being created by the Git command factory
at creation time. Ideally, this was done by just creating symlinking the
required hooks to the gitaly-hooks
binary. Unfortunately though, it
depends on the first parameter being set to the name of the hook that is
about to be executed. This is rather pointless: it could just derive the
name from its zeroth argument, which would be set to the symlinks path
anyway. That would require a separate change to gitaly-hooks
though,
and due to backwards-compatibility reasons that would require a full
release cycle.
Instead, we're writing a wrapper script into the hook directory that's
the same as our current gitlab-shell-hook
script. There are two
differences though:
1. The new script doesn't need the `GITALY_BIN_DIR` environment
variable anymore to resolve the path of `gitaly-hooks`, but
instead has its path resolved at creation-time of the script
already.
2. The new script sets both the zeroth and first argument of
`gitaly-hooks` to its own name. This will eventually allow us to
migrate `gitaly-hooks` to resolve the hook name via its zeroth
argument. In the end, this means that we can then get rid of the
wrapper script altogether.
This change is done behind a new feature flag given that execution of hooks is essential to all writing code paths. This feature flag is injected with a random value into all of our tests to assert that they work correctly both with the flag enabled and disabled.
Changelog: changed
Closes #3932 (closed)