From 5675ea31c8e92a6cc8e29daf96c33278ddc7c6f2 Mon Sep 17 00:00:00 2001 From: arkn98 <2424696-arkn98@users.noreply.gitlab.com> Date: Sun, 20 Aug 2023 01:00:58 -0400 Subject: [PATCH] streamcache: add support for symlinks Streamcache.filestore, currently, doesn't work when its directory is a symlink; the cleanup function ends up deleting it (see [1]). This commit fixes it by resolving the symlink to its absolute path during configuration. The side-effects of this change are: - The log messages, label values, etc. will use the resolved path instead of the value set in pack_objects_cache.dir, if it was a symlink. - Since we lstat the path to check if it is a symlink, the errors that might happen during the cleanup (when `cleanWalk()` is run) can now happen during configuration. 1. https://gitlab.com/gitlab-org/gitaly/-/issues/4845 Fixes: https://gitlab.com/gitlab-org/gitaly/-/issues/4845 Changelog: added Signed-off-by: arkn98 <2424696-arkn98@users.noreply.gitlab.com> --- internal/gitaly/config/config.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/internal/gitaly/config/config.go b/internal/gitaly/config/config.go index 5b02d15bfe9..1bdb7e25ee4 100644 --- a/internal/gitaly/config/config.go +++ b/internal/gitaly/config/config.go @@ -934,9 +934,40 @@ func (cfg *Cfg) configurePackObjectsCache() error { return errPackObjectsCacheRelativePath } + realPath, err := evalSymlink(poc.Dir) + if err != nil { + return fmt.Errorf("pack_objects_cache.dir symlink cannot be resolved: %w", err) + } + poc.Dir = realPath + return nil } +func evalSymlink(path string) (string, error) { + // check if path is a symlink + fileInfo, err := os.Lstat(path) + if err != nil { + return "", err + } + + if fileInfo.Mode()&os.ModeSymlink == 0 { + // path is not a symlink + return path, nil + } + + realPath, err := filepath.EvalSymlinks(path) + if err != nil { + return "", err + } + + // the evaluated path can be relative + if !filepath.IsAbs(realPath) { + return filepath.Abs(realPath) + } + + return realPath, nil +} + // SetupRuntimeDirectory creates a new runtime directory. Runtime directory contains internal // runtime data generated by Gitaly such as the internal sockets. If cfg.RuntimeDir is set, // it's used as the parent directory for the runtime directory. Runtime directory owner process -- GitLab