diff options
author | Sami Hiltunen <shiltunen@gitlab.com> | 2023-05-16 18:22:06 +0300 |
---|---|---|
committer | Sami Hiltunen <shiltunen@gitlab.com> | 2023-05-16 18:22:06 +0300 |
commit | 62290e3154e12e5d668fbfebce58673920e469bc (patch) | |
tree | 6d5a3b4e511996b718f67e52d150dc1348cb6868 | |
parent | d3fec72e7b050effa9177f4eeea47bd1f638c533 (diff) |
Execute custom hooks from transaction's snapshotsmh-wal-user-commit-files
Each transaction has a read snapshot that maintains its isolation
from concurrent writes. The snapshot includes also the version of
custom hooks. When the hooks are executed or read, the operation
should be targeted at the correct version of hooks. The transaction's
snapshot includes the absolute path to the custom hooks on the disk.
This commit teaches HookManager to execute the snapshotted hooks
from the directory included in the transaction.
While the HookManager knows how to execute the correct hooks now,
not all of the call sites pass a transaction yet.
-rw-r--r-- | internal/gitaly/hook/custom.go | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/internal/gitaly/hook/custom.go b/internal/gitaly/hook/custom.go index a659e81c5..35082881d 100644 --- a/internal/gitaly/hook/custom.go +++ b/internal/gitaly/hook/custom.go @@ -38,11 +38,17 @@ func (e CustomHookError) Unwrap() error { return e.err } -// newCustomHooksExecutor creates a new hooks executor for custom hooks. Hooks -// are looked up and executed in the following order: +// newCustomHooksExecutor creates a new hooks executor for custom hooks. // -// 1. <repository>.git/custom_hooks/<hook_name> - per project hook -// 2. <repository>.git/custom_hooks/<hook_name>.d/* - per project hooks +// Repository specific custom hooks are executed by default from `<repo>.git/custom_hooks`. +// This is the non-WAL behavior where hooks are updated in place. With WAL, the hooks are +// managed with MVCC. If the transaction is set, we'll use the hook path from its snapshot +// to ensure we execute the correct version of the hooks. +// +// Hooks are looked up and executed in the following order: +// +// 1. <repository specific hooks>/<hook_name> - per project hook +// 2. <repository specific hooks>/<hook_name>.d/* - per project hooks // 3. <custom_hooks_dir>/hooks/<hook_name>.d/* - global hooks // // Any files which are either not executable or have a trailing `~` are ignored. @@ -52,13 +58,18 @@ func (m *GitLabHookManager) newCustomHooksExecutor(tx *gitaly.Transaction, repo return nil, err } + hookPath := filepath.Join(repoPath, "custom_hooks") + if tx != nil { + hookPath = tx.Snapshot().HookPath + } + var hookFiles []string - projectCustomHookFile := filepath.Join(repoPath, "custom_hooks", hookName) + projectCustomHookFile := filepath.Join(hookPath, hookName) if isValidHook(projectCustomHookFile) { hookFiles = append(hookFiles, projectCustomHookFile) } - projectCustomHookDir := filepath.Join(repoPath, "custom_hooks", fmt.Sprintf("%s.d", hookName)) + projectCustomHookDir := filepath.Join(hookPath, fmt.Sprintf("%s.d", hookName)) files, err := findHooks(projectCustomHookDir) if err != nil { return nil, err |