Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <psteinhardt@gitlab.com>2023-06-07 16:25:30 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2023-06-07 16:25:30 +0300
commite5d3bdf14db2f202c8d3679a75474f4760ac45c7 (patch)
treedf3473049e7e9f52f049b027394c9f7517534ffa
parent1934b9991139b48ed58d78dc89b35c262acd5150 (diff)
parent7c60bca26b57df5630ca0bc77e284dfe63adb3c3 (diff)
Merge branch 'pks-locator-improve-invalid-repo-reporting' into 'master'
config/locator: Improve error reporting for invalid repositories See merge request https://gitlab.com/gitlab-org/gitaly/-/merge_requests/5891 Merged-by: Patrick Steinhardt <psteinhardt@gitlab.com> Approved-by: Pavlo Strokov <pstrokov@gitlab.com> Reviewed-by: Patrick Steinhardt <psteinhardt@gitlab.com> Reviewed-by: Pavlo Strokov <pstrokov@gitlab.com> Reviewed-by: Justin Tobler <jtobler@gitlab.com>
-rw-r--r--internal/backup/repository.go14
-rw-r--r--internal/cli/gitaly/hooks_test.go4
-rw-r--r--internal/cli/praefect/subcmd_remove_repository_test.go4
-rw-r--r--internal/cli/praefect/subcmd_track_repository.go4
-rw-r--r--internal/git/localrepo/paths_test.go5
-rw-r--r--internal/git/localrepo/remote_extra_test.go3
-rw-r--r--internal/git/objectpool/create.go2
-rw-r--r--internal/git/objectpool/pool.go6
-rw-r--r--internal/git/quarantine/quarantine.go4
-rw-r--r--internal/gitaly/config/locator.go34
-rw-r--r--internal/gitaly/config/locator_test.go118
-rw-r--r--internal/gitaly/hook/custom.go3
-rw-r--r--internal/gitaly/hook/testhelper_test.go2
-rw-r--r--internal/gitaly/linguist/linguist_test.go3
-rw-r--r--internal/gitaly/maintenance/optimize.go2
-rw-r--r--internal/gitaly/repoutil/create.go2
-rw-r--r--internal/gitaly/repoutil/create_test.go7
-rw-r--r--internal/gitaly/repoutil/lock.go2
-rw-r--r--internal/gitaly/repoutil/lock_test.go3
-rw-r--r--internal/gitaly/repoutil/remove.go2
-rw-r--r--internal/gitaly/service/blob/get_blob_test.go11
-rw-r--r--internal/gitaly/service/commit/isancestor_test.go13
-rw-r--r--internal/gitaly/service/commit/stats_test.go27
-rw-r--r--internal/gitaly/service/conflicts/list_conflict_files.go3
-rw-r--r--internal/gitaly/service/diff/find_changed_paths_test.go13
-rw-r--r--internal/gitaly/service/diff/numstat_test.go14
-rw-r--r--internal/gitaly/service/internalgitaly/walkrepos.go2
-rw-r--r--internal/gitaly/service/objectpool/delete_test.go5
-rw-r--r--internal/gitaly/service/operations/apply_patch_test.go15
-rw-r--r--internal/gitaly/service/operations/commit_files_test.go2
-rw-r--r--internal/gitaly/service/operations/merge.go3
-rw-r--r--internal/gitaly/service/ref/find_refs_by_oid_test.go19
-rw-r--r--internal/gitaly/service/ref/refs_test.go24
-rw-r--r--internal/gitaly/service/repository/apply_gitattributes_test.go12
-rw-r--r--internal/gitaly/service/repository/config.go3
-rw-r--r--internal/gitaly/service/repository/create_fork.go3
-rw-r--r--internal/gitaly/service/repository/create_repository_from_bundle_test.go2
-rw-r--r--internal/gitaly/service/repository/create_repository_from_snapshot.go3
-rw-r--r--internal/gitaly/service/repository/create_repository_from_url.go3
-rw-r--r--internal/gitaly/service/repository/fetch_bundle_test.go13
-rw-r--r--internal/gitaly/service/repository/fullpath_test.go10
-rw-r--r--internal/gitaly/service/repository/license_test.go3
-rw-r--r--internal/gitaly/service/repository/object_format_test.go6
-rw-r--r--internal/gitaly/service/repository/optimize_test.go12
-rw-r--r--internal/gitaly/service/repository/prune_unreachable_objects_test.go9
-rw-r--r--internal/gitaly/service/repository/rename.go3
-rw-r--r--internal/gitaly/service/repository/rename_test.go24
-rw-r--r--internal/gitaly/service/repository/replicate.go19
-rw-r--r--internal/gitaly/service/repository/repository_exists.go6
-rw-r--r--internal/gitaly/service/repository/repository_exists_test.go8
-rw-r--r--internal/gitaly/service/repository/repository_info_test.go6
-rw-r--r--internal/gitaly/service/smarthttp/inforefs_test.go23
-rw-r--r--internal/gitaly/service/ssh/upload_pack_test.go2
-rw-r--r--internal/gitaly/storage/locator.go81
-rw-r--r--internal/praefect/commonerr/error.go35
-rw-r--r--internal/praefect/coordinator.go10
-rw-r--r--internal/praefect/coordinator_test.go12
-rw-r--r--internal/praefect/datastore/assignment_test.go6
-rw-r--r--internal/praefect/datastore/repository_store.go38
-rw-r--r--internal/praefect/datastore/repository_store_test.go28
-rw-r--r--internal/praefect/datastore/storage_provider_test.go4
-rw-r--r--internal/praefect/nodes/manager.go4
-rw-r--r--internal/praefect/nodes/per_repository.go4
-rw-r--r--internal/praefect/nodes/per_repository_test.go6
-rw-r--r--internal/praefect/reconciler/reconciler_test.go6
-rw-r--r--internal/praefect/remove_repository.go6
-rw-r--r--internal/praefect/rename_repository.go5
-rw-r--r--internal/praefect/replicator_test.go2
-rw-r--r--internal/praefect/router_node_manager.go4
-rw-r--r--internal/praefect/router_per_repository_test.go3
-rw-r--r--internal/praefect/service/info/metadata.go4
-rw-r--r--internal/praefect/service/info/server.go4
-rw-r--r--internal/tempdir/tempdir_test.go3
73 files changed, 407 insertions, 403 deletions
diff --git a/internal/backup/repository.go b/internal/backup/repository.go
index 957c4b64d..d43574645 100644
--- a/internal/backup/repository.go
+++ b/internal/backup/repository.go
@@ -263,15 +263,19 @@ func newLocalRepository(
// IsEmpty returns true if the repository has no branches.
func (r *localRepository) IsEmpty(ctx context.Context) (bool, error) {
- path, err := r.locator.GetPath(r.repo)
+ path, err := r.locator.GetRepoPath(r.repo, storage.WithRepositoryVerificationSkipped())
if err != nil {
return false, fmt.Errorf("local repository: is empty: %w", err)
}
- if !storage.IsGitDirectory(path) {
- // Backups do not currently differentiate between non-existent and
- // empty. See https://gitlab.com/gitlab-org/gitlab/-/issues/357044
- return true, nil
+ if err := storage.ValidateRepository(path); err != nil {
+ if errors.Is(err, storage.ErrRepositoryNotFound) {
+ // Backups do not currently differentiate between non-existent and
+ // empty. See https://gitlab.com/gitlab-org/gitlab/-/issues/357044
+ return true, nil
+ }
+
+ return false, fmt.Errorf("local repository: verifying repository: %w", err)
}
hasBranches, err := r.repo.HasBranches(ctx)
diff --git a/internal/cli/gitaly/hooks_test.go b/internal/cli/gitaly/hooks_test.go
index 6e92e1028..2ea14ddc6 100644
--- a/internal/cli/gitaly/hooks_test.go
+++ b/internal/cli/gitaly/hooks_test.go
@@ -2,6 +2,7 @@ package gitaly
import (
"bytes"
+ "fmt"
"io"
"io/fs"
"os/exec"
@@ -14,6 +15,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service/setup"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
internalclient "gitlab.com/gitlab-org/gitaly/v16/internal/grpc/client"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/perm"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
@@ -116,7 +118,7 @@ func TestSetHooksSubcommand(t *testing.T) {
},
hooks: testhelper.MustCreateCustomHooksTar(t),
expectedErr: testhelper.GitalyOrPraefect(
- "getting repo path: GetRepoPath: not a git repository:",
+ fmt.Sprintf("getting repo path: %s", storage.ErrRepositoryNotFound),
"rpc error: code = NotFound desc = mutator call: route repository mutator: get repository id: repository \"default\"/\"non-existent\" not found\n",
),
},
diff --git a/internal/cli/praefect/subcmd_remove_repository_test.go b/internal/cli/praefect/subcmd_remove_repository_test.go
index a89ab27ed..57cdc9ddb 100644
--- a/internal/cli/praefect/subcmd_remove_repository_test.go
+++ b/internal/cli/praefect/subcmd_remove_repository_test.go
@@ -188,8 +188,8 @@ func TestRemoveRepositorySubcommand(t *testing.T) {
require.NoError(t, err)
require.False(t, repositoryExists(t, repo))
// Repo is still present on-disk on the Gitaly nodes.
- require.True(t, storage.IsGitDirectory(filepath.Join(g1Cfg.Storages[0].Path, replicaPath)))
- require.True(t, storage.IsGitDirectory(filepath.Join(g2Cfg.Storages[0].Path, replicaPath)))
+ require.NoError(t, storage.ValidateRepository(filepath.Join(g1Cfg.Storages[0].Path, replicaPath)))
+ require.NoError(t, storage.ValidateRepository(filepath.Join(g2Cfg.Storages[0].Path, replicaPath)))
},
assertOutput: func(t *testing.T, out string, repo *gitalypb.Repository) {
assert.Contains(t, out, "Repository found in the database.\n")
diff --git a/internal/cli/praefect/subcmd_track_repository.go b/internal/cli/praefect/subcmd_track_repository.go
index 1c28cbe28..d8381194b 100644
--- a/internal/cli/praefect/subcmd_track_repository.go
+++ b/internal/cli/praefect/subcmd_track_repository.go
@@ -12,10 +12,10 @@ import (
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
glcli "gitlab.com/gitlab-org/gitaly/v16/internal/cli"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/middleware/metadatahandler"
"gitlab.com/gitlab-org/gitaly/v16/internal/log"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/config"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore/glsql"
@@ -275,7 +275,7 @@ func (req *trackRepositoryRequest) trackRepository(
) (int64, error) {
repositoryID, err := ds.ReserveRepositoryID(ctx, req.VirtualStorage, req.RelativePath)
if err != nil {
- if errors.Is(err, commonerr.ErrRepositoryAlreadyExists) {
+ if errors.Is(err, storage.ErrRepositoryAlreadyExists) {
fmt.Fprintf(w, "repository is already tracked in praefect database")
return 0, nil
}
diff --git a/internal/git/localrepo/paths_test.go b/internal/git/localrepo/paths_test.go
index dcd216527..b87c56e5c 100644
--- a/internal/git/localrepo/paths_test.go
+++ b/internal/git/localrepo/paths_test.go
@@ -10,6 +10,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git/localrepo"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/quarantine"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/perm"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
@@ -44,7 +45,7 @@ func TestRepo_Path(t *testing.T) {
require.NoError(t, os.RemoveAll(repoPath))
_, err := repo.Path()
- require.Equal(t, structerr.NewNotFound("GetRepoPath: not a git repository: %q", repoPath), err)
+ require.Equal(t, structerr.NewNotFound("%w", storage.ErrRepositoryNotFound).WithMetadata("repository_path", repoPath), err)
})
t.Run("non-git repository", func(t *testing.T) {
@@ -59,7 +60,7 @@ func TestRepo_Path(t *testing.T) {
require.NoError(t, os.MkdirAll(repoPath, perm.PublicDir))
_, err := repo.Path()
- require.Equal(t, structerr.NewNotFound("GetRepoPath: not a git repository: %q", repoPath), err)
+ require.Equal(t, structerr.NewFailedPrecondition("%w: %q does not exist", storage.ErrRepositoryNotValid, "objects").WithMetadata("repository_path", repoPath), err)
})
}
diff --git a/internal/git/localrepo/remote_extra_test.go b/internal/git/localrepo/remote_extra_test.go
index 69772479c..20cc997ed 100644
--- a/internal/git/localrepo/remote_extra_test.go
+++ b/internal/git/localrepo/remote_extra_test.go
@@ -13,6 +13,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service/hook"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service/repository"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service/ssh"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testcfg"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testserver"
@@ -186,7 +187,7 @@ func TestRepo_FetchInternal(t *testing.T) {
require.Error(t, err)
require.IsType(t, err, localrepo.FetchFailedError{})
- expectedMsg := "GetRepoPath: not a git repository"
+ expectedMsg := storage.ErrRepositoryNotFound.Error()
if testhelper.IsPraefectEnabled() {
expectedMsg = `repository \"default\"/\"does/not/exist\" not found`
}
diff --git a/internal/git/objectpool/create.go b/internal/git/objectpool/create.go
index 18323e05d..4f4787b1a 100644
--- a/internal/git/objectpool/create.go
+++ b/internal/git/objectpool/create.go
@@ -32,7 +32,7 @@ func Create(
proto *gitalypb.ObjectPool,
sourceRepo *localrepo.Repo,
) (*ObjectPool, error) {
- objectPoolPath, err := locator.GetPath(proto.GetRepository())
+ objectPoolPath, err := locator.GetRepoPath(proto.GetRepository(), storage.WithRepositoryVerificationSkipped())
if err != nil {
return nil, err
}
diff --git a/internal/git/objectpool/pool.go b/internal/git/objectpool/pool.go
index 3f4206888..720204320 100644
--- a/internal/git/objectpool/pool.go
+++ b/internal/git/objectpool/pool.go
@@ -52,7 +52,7 @@ func FromProto(
housekeepingManager housekeeping.Manager,
proto *gitalypb.ObjectPool,
) (*ObjectPool, error) {
- poolPath, err := locator.GetPath(proto.GetRepository())
+ poolPath, err := locator.GetRepoPath(proto.GetRepository(), storage.WithRepositoryVerificationSkipped())
if err != nil {
return nil, err
}
@@ -117,7 +117,7 @@ func (o *ObjectPool) IsValid() bool {
return false
}
- return storage.IsGitDirectory(path)
+ return storage.ValidateRepository(path) == nil
}
// Remove will remove the pool, and all its contents without preparing and/or
@@ -220,7 +220,7 @@ func objectPathRelativeToStorage(locator storage.Locator, storageName, path, rep
poolObjectDirFullPath := filepath.Join(objectDirPath, path)
- if !storage.IsGitDirectory(filepath.Dir(poolObjectDirFullPath)) {
+ if storage.ValidateRepository(filepath.Dir(poolObjectDirFullPath)) != nil {
return "", ErrInvalidPoolRepository
}
diff --git a/internal/git/quarantine/quarantine.go b/internal/git/quarantine/quarantine.go
index b6d569c55..115de6ace 100644
--- a/internal/git/quarantine/quarantine.go
+++ b/internal/git/quarantine/quarantine.go
@@ -33,7 +33,7 @@ type Dir struct {
// New creates a new quarantine directory and returns the directory. The repository is cleaned
// up when the user invokes the Migrate() functionality on the Dir.
func New(ctx context.Context, repo *gitalypb.Repository, locator storage.Locator) (*Dir, error) {
- repoPath, err := locator.GetPath(repo)
+ repoPath, err := locator.GetRepoPath(repo, storage.WithRepositoryVerificationSkipped())
if err != nil {
return nil, structerr.NewInternal("getting repo path: %w", err)
}
@@ -89,7 +89,7 @@ func (d *Dir) QuarantinedRepo() *gitalypb.Repository {
// Migrate migrates all objects part of the quarantine directory into the main repository and thus
// makes them generally available. This implementation follows the git.git's `tmp_objdir_migrate()`.
func (d *Dir) Migrate() error {
- repoPath, err := d.locator.GetPath(d.repo)
+ repoPath, err := d.locator.GetRepoPath(d.repo, storage.WithRepositoryVerificationSkipped())
if err != nil {
return fmt.Errorf("migrating quarantine: %w", err)
}
diff --git a/internal/gitaly/config/locator.go b/internal/gitaly/config/locator.go
index a69d947c8..539ead41d 100644
--- a/internal/gitaly/config/locator.go
+++ b/internal/gitaly/config/locator.go
@@ -44,22 +44,6 @@ func (l *configLocator) GetRepoPath(repo storage.Repository, opts ...storage.Get
opt(&cfg)
}
- repoPath, err := l.GetPath(repo)
- if err != nil {
- return "", err
- }
-
- if cfg.SkipRepositoryVerification || storage.IsGitDirectory(repoPath) {
- return repoPath, nil
- }
-
- return "", structerr.NewNotFound("GetRepoPath: not a git repository: %q", repoPath)
-}
-
-// GetPath returns the path of the repo passed as first argument. An error is
-// returned when either the storage can't be found or the path includes
-// constructs trying to perform directory traversal.
-func (l *configLocator) GetPath(repo storage.Repository) (string, error) {
storagePath, err := l.GetStorageByName(repo.GetStorageName())
if err != nil {
return "", err
@@ -67,22 +51,30 @@ func (l *configLocator) GetPath(repo storage.Repository) (string, error) {
if _, err := os.Stat(storagePath); err != nil {
if os.IsNotExist(err) {
- return "", structerr.NewNotFound("GetPath: does not exist: %w", err)
+ return "", structerr.NewNotFound("storage does not exist").WithMetadata("storage_path", storagePath)
}
- return "", structerr.NewInternal("GetPath: storage path: %w", err)
+ return "", structerr.New("storage path: %w", err).WithMetadata("storage_path", storagePath)
}
relativePath := repo.GetRelativePath()
if len(relativePath) == 0 {
- err := structerr.NewInvalidArgument("GetPath: relative path missing")
+ err := structerr.NewInvalidArgument("relative path is not set")
return "", err
}
if _, err := storage.ValidateRelativePath(storagePath, relativePath); err != nil {
- return "", structerr.NewInvalidArgument("GetRepoPath: %w", err)
+ return "", structerr.NewInvalidArgument("%w", err).WithMetadata("relative_path", relativePath)
+ }
+
+ repoPath := filepath.Join(storagePath, relativePath)
+
+ if !cfg.SkipRepositoryVerification {
+ if err := storage.ValidateRepository(repoPath); err != nil {
+ return "", err
+ }
}
- return filepath.Join(storagePath, relativePath), nil
+ return repoPath, nil
}
// GetStorageByName will return the path for the storage, which is fetched by
diff --git a/internal/gitaly/config/locator_test.go b/internal/gitaly/config/locator_test.go
index 94af343d4..e3b596373 100644
--- a/internal/gitaly/config/locator_test.go
+++ b/internal/gitaly/config/locator_test.go
@@ -1,12 +1,9 @@
package config_test
import (
- "fmt"
- "io/fs"
"os"
"path/filepath"
"strings"
- "syscall"
"testing"
"github.com/stretchr/testify/require"
@@ -62,28 +59,25 @@ func TestConfigLocator_GetRepoPath(t *testing.T) {
expErr: structerr.NewInvalidArgument(`GetStorageByName: no such storage: "invalid"`),
},
{
- desc: "storage doesn't exist on disk",
- repo: &gitalypb.Repository{StorageName: cfg.Storages[1].Name, RelativePath: repo.RelativePath},
- expErr: structerr.NewNotFound(`GetPath: does not exist: %w`, &fs.PathError{
- Op: "stat",
- Path: cfg.Storages[1].Path,
- Err: syscall.ENOENT,
- }),
+ desc: "storage doesn't exist on disk",
+ repo: &gitalypb.Repository{StorageName: cfg.Storages[1].Name, RelativePath: repo.RelativePath},
+ expErr: structerr.NewNotFound("storage does not exist").WithMetadata("storage_path", cfg.Storages[1].Path),
},
{
desc: "relative path is empty",
repo: &gitalypb.Repository{StorageName: storageName, RelativePath: ""},
- expErr: structerr.NewInvalidArgument("GetPath: relative path missing"),
+ expErr: structerr.NewInvalidArgument("relative path is not set"),
},
{
desc: "unknown relative path",
repo: &gitalypb.Repository{StorageName: storageName, RelativePath: "invalid"},
- expErr: structerr.NewNotFound(`GetRepoPath: not a git repository: %q`, filepath.Join(cfg.Storages[0].Path, "invalid")),
+ expErr: structerr.NewNotFound("%w", storage.ErrRepositoryNotFound).WithMetadata("repository_path", filepath.Join(cfg.Storages[0].Path, "invalid")),
},
{
- desc: "path exists but not a git repository",
- repo: &gitalypb.Repository{StorageName: storageName, RelativePath: notRepositoryFolder},
- expErr: structerr.NewNotFound(`GetRepoPath: not a git repository: %q`, filepath.Join(cfg.Storages[0].Path, notRepositoryFolder)),
+ desc: "path exists but not a git repository",
+ repo: &gitalypb.Repository{StorageName: storageName, RelativePath: notRepositoryFolder},
+ expErr: structerr.NewFailedPrecondition("%w: %q does not exist", storage.ErrRepositoryNotValid, "objects").
+ WithMetadata("repository_path", filepath.Join(cfg.Storages[0].Path, notRepositoryFolder)),
},
{
desc: "unknown relative path without repo verification",
@@ -100,7 +94,7 @@ func TestConfigLocator_GetRepoPath(t *testing.T) {
{
desc: "relative path escapes parent folder",
repo: &gitalypb.Repository{StorageName: storageName, RelativePath: "../.."},
- expErr: structerr.NewInvalidArgument(`GetRepoPath: %w`, fmt.Errorf("relative path escapes root directory")),
+ expErr: structerr.NewInvalidArgument("%w", storage.ErrRelativePathEscapesRoot).WithMetadata("relative_path", "../.."),
},
{
desc: "proper repository path",
@@ -116,98 +110,6 @@ func TestConfigLocator_GetRepoPath(t *testing.T) {
}
}
-func TestConfigLocator_GetPath(t *testing.T) {
- t.Parallel()
- const storageName = "exists"
- ctx := testhelper.Context(t)
- cfg := testcfg.Build(t, testcfg.WithStorages(storageName, "removed"))
- cfg.SocketPath = testserver.RunGitalyServer(t, cfg, setup.RegisterAll)
- repo, _ := gittest.CreateRepository(t, ctx, cfg)
-
- // The storage name still present in the storages list, but not on the disk.
- require.NoError(t, os.RemoveAll(cfg.Storages[1].Path))
-
- // The repository path exists on the disk, but it is not a git repository.
- const notRepositoryFolder = "not-a-git-repo"
- require.NoError(t, os.MkdirAll(filepath.Join(cfg.Storages[0].Path, notRepositoryFolder), perm.SharedDir))
-
- for _, tc := range []struct {
- desc string
- repo *gitalypb.Repository
- path string
- }{
- {
- desc: "proper repository path",
- repo: repo,
- path: filepath.Join(cfg.Storages[0].Path, repo.RelativePath),
- },
- {
- desc: "path doesn't exist",
- repo: &gitalypb.Repository{StorageName: storageName, RelativePath: "doesnt/exist"},
- path: filepath.Join(cfg.Storages[0].Path, "doesnt/exist"),
- },
- {
- desc: "path exists but not a git repository",
- repo: &gitalypb.Repository{StorageName: storageName, RelativePath: notRepositoryFolder},
- path: filepath.Join(cfg.Storages[0].Path, notRepositoryFolder),
- },
- {
- desc: "relative path includes travels",
- repo: &gitalypb.Repository{StorageName: storageName, RelativePath: "some/../other"},
- path: filepath.Join(cfg.Storages[0].Path, "other"),
- },
- } {
- t.Run(tc.desc, func(t *testing.T) {
- locator := config.NewLocator(cfg)
- path, err := locator.GetPath(tc.repo)
- require.NoError(t, err)
- require.Equal(t, tc.path, path)
- })
- }
-
- for _, tc := range []struct {
- desc string
- repo *gitalypb.Repository
- expErr error
- }{
- {
- desc: "storage is empty",
- repo: &gitalypb.Repository{RelativePath: repo.RelativePath},
- expErr: structerr.NewInvalidArgument(`GetStorageByName: no such storage: ""`),
- },
- {
- desc: "unknown storage",
- repo: &gitalypb.Repository{StorageName: "invalid", RelativePath: repo.RelativePath},
- expErr: structerr.NewInvalidArgument(`GetStorageByName: no such storage: "invalid"`),
- },
- {
- desc: "storage doesn't exist on disk",
- repo: &gitalypb.Repository{StorageName: cfg.Storages[1].Name, RelativePath: repo.RelativePath},
- expErr: structerr.NewNotFound(`GetPath: does not exist: %w`, &fs.PathError{
- Op: "stat",
- Path: cfg.Storages[1].Path,
- Err: syscall.ENOENT,
- }),
- },
- {
- desc: "relative path is empty",
- repo: &gitalypb.Repository{StorageName: storageName, RelativePath: ""},
- expErr: structerr.NewInvalidArgument("GetPath: relative path missing"),
- },
- {
- desc: "relative path escapes parent folder",
- repo: &gitalypb.Repository{StorageName: storageName, RelativePath: "../.."},
- expErr: structerr.NewInvalidArgument(`GetRepoPath: %w`, fmt.Errorf("relative path escapes root directory")),
- },
- } {
- t.Run(tc.desc, func(t *testing.T) {
- locator := config.NewLocator(cfg)
- _, err := locator.GetPath(tc.repo)
- require.Equal(t, tc.expErr, err)
- })
- }
-}
-
func TestConfigLocator_CacheDir(t *testing.T) {
t.Parallel()
const storageName = "exists"
diff --git a/internal/gitaly/hook/custom.go b/internal/gitaly/hook/custom.go
index 6ccf968a0..c4faf0680 100644
--- a/internal/gitaly/hook/custom.go
+++ b/internal/gitaly/hook/custom.go
@@ -11,6 +11,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/command"
"gitlab.com/gitlab-org/gitaly/v16/internal/git"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/env"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
"golang.org/x/sys/unix"
@@ -159,7 +160,7 @@ func isValidHook(path string) bool {
}
func (m *GitLabHookManager) customHooksEnv(ctx context.Context, payload git.HooksPayload, pushOptions []string, envs []string) ([]string, error) {
- repoPath, err := m.locator.GetPath(payload.Repo)
+ repoPath, err := m.locator.GetRepoPath(payload.Repo, storage.WithRepositoryVerificationSkipped())
if err != nil {
return nil, err
}
diff --git a/internal/gitaly/hook/testhelper_test.go b/internal/gitaly/hook/testhelper_test.go
index 69e0b2ea5..935aef1f5 100644
--- a/internal/gitaly/hook/testhelper_test.go
+++ b/internal/gitaly/hook/testhelper_test.go
@@ -22,7 +22,7 @@ func TestMain(m *testing.M) {
}
func getExpectedEnv(tb testing.TB, ctx context.Context, locator storage.Locator, gitCmdFactory git.CommandFactory, repo *gitalypb.Repository) []string {
- repoPath, err := locator.GetPath(repo)
+ repoPath, err := locator.GetRepoPath(repo, storage.WithRepositoryVerificationSkipped())
require.NoError(tb, err)
expectedEnv := map[string]string{
diff --git a/internal/gitaly/linguist/linguist_test.go b/internal/gitaly/linguist/linguist_test.go
index da96b7d25..c70b2a790 100644
--- a/internal/gitaly/linguist/linguist_test.go
+++ b/internal/gitaly/linguist/linguist_test.go
@@ -13,6 +13,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/localrepo"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/perm"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testcfg"
@@ -509,7 +510,7 @@ func TestInstance_Stats(t *testing.T) {
return repoProto, repoPath, git.ObjectID("b1bb1d1b0b1d1b00")
},
- expectedErr: "GetRepoPath: not a git repository",
+ expectedErr: storage.ErrRepositoryNotFound.Error(),
},
{
desc: "missing commit",
diff --git a/internal/gitaly/maintenance/optimize.go b/internal/gitaly/maintenance/optimize.go
index fdd9bd1e8..9d866827d 100644
--- a/internal/gitaly/maintenance/optimize.go
+++ b/internal/gitaly/maintenance/optimize.go
@@ -148,7 +148,7 @@ func walkReposShuffled(
return err
}
- if !fi.IsDir() || !storage.IsGitDirectory(path) {
+ if !fi.IsDir() || storage.ValidateRepository(path) != nil {
continue
}
walker.skipDir()
diff --git a/internal/gitaly/repoutil/create.go b/internal/gitaly/repoutil/create.go
index d070dc855..faade627f 100644
--- a/internal/gitaly/repoutil/create.go
+++ b/internal/gitaly/repoutil/create.go
@@ -69,7 +69,7 @@ func Create(
seedRepository func(repository *gitalypb.Repository) error,
options ...CreateOption,
) error {
- targetPath, err := locator.GetPath(repository)
+ targetPath, err := locator.GetRepoPath(repository, storage.WithRepositoryVerificationSkipped())
if err != nil {
return structerr.NewInvalidArgument("locate repository: %w", err)
}
diff --git a/internal/gitaly/repoutil/create_test.go b/internal/gitaly/repoutil/create_test.go
index 97ae936a2..1728caac2 100644
--- a/internal/gitaly/repoutil/create_test.go
+++ b/internal/gitaly/repoutil/create_test.go
@@ -14,6 +14,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/stats"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/transaction"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/perm"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/text"
@@ -333,7 +334,7 @@ func TestCreate(t *testing.T) {
ctx = peer.NewContext(ctx, &peer.Peer{})
}
- repoPath, err := locator.GetPath(repo)
+ repoPath, err := locator.GetRepoPath(repo, storage.WithRepositoryVerificationSkipped())
require.NoError(t, err)
if tc.setup != nil {
@@ -349,7 +350,7 @@ func TestCreate(t *testing.T) {
require.Equal(t, repo.StorageName, tempRepo.StorageName)
require.True(t, strings.HasPrefix(tempRepo.RelativePath, "+gitaly/tmp/repo"))
- tempRepoPath, err := locator.GetPath(tempRepo)
+ tempRepoPath, err := locator.GetRepoPath(tempRepo, storage.WithRepositoryVerificationSkipped())
require.NoError(t, err)
if tc.seed != nil {
@@ -365,7 +366,7 @@ func TestCreate(t *testing.T) {
var tempRepoPath string
if tempRepo != nil {
- tempRepoPath, err = locator.GetPath(tempRepo)
+ tempRepoPath, err = locator.GetRepoPath(tempRepo, storage.WithRepositoryVerificationSkipped())
require.NoError(t, err)
}
diff --git a/internal/gitaly/repoutil/lock.go b/internal/gitaly/repoutil/lock.go
index 6d902b830..097374e61 100644
--- a/internal/gitaly/repoutil/lock.go
+++ b/internal/gitaly/repoutil/lock.go
@@ -20,7 +20,7 @@ import (
// Returns the error safe.ErrFileAlreadyLocked if the repository is already
// locked.
func Lock(ctx context.Context, locator storage.Locator, repository storage.Repository) (func(), error) {
- path, err := locator.GetPath(repository)
+ path, err := locator.GetRepoPath(repository, storage.WithRepositoryVerificationSkipped())
if err != nil {
return nil, err
}
diff --git a/internal/gitaly/repoutil/lock_test.go b/internal/gitaly/repoutil/lock_test.go
index 888aba9a0..956b50e58 100644
--- a/internal/gitaly/repoutil/lock_test.go
+++ b/internal/gitaly/repoutil/lock_test.go
@@ -6,6 +6,7 @@ import (
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/safe"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testcfg"
@@ -24,7 +25,7 @@ func TestLock(t *testing.T) {
RelativePath: gittest.NewRepositoryName(t),
}
- repoPath, err := locator.GetPath(repo)
+ repoPath, err := locator.GetRepoPath(repo, storage.WithRepositoryVerificationSkipped())
require.NoError(t, err)
unlock, err := Lock(ctx, locator, repo)
diff --git a/internal/gitaly/repoutil/remove.go b/internal/gitaly/repoutil/remove.go
index 924135946..75a2ce998 100644
--- a/internal/gitaly/repoutil/remove.go
+++ b/internal/gitaly/repoutil/remove.go
@@ -23,7 +23,7 @@ func Remove(
txManager transaction.Manager,
repository storage.Repository,
) error {
- path, err := locator.GetPath(repository)
+ path, err := locator.GetRepoPath(repository, storage.WithRepositoryVerificationSkipped())
if err != nil {
return structerr.NewInternal("%w", err)
}
diff --git a/internal/gitaly/service/blob/get_blob_test.go b/internal/gitaly/service/blob/get_blob_test.go
index 80be7715b..ed859b6fe 100644
--- a/internal/gitaly/service/blob/get_blob_test.go
+++ b/internal/gitaly/service/blob/get_blob_test.go
@@ -186,10 +186,13 @@ func TestGetBlob_invalidRequest(t *testing.T) {
},
Oid: oid,
},
- expectedErr: structerr.NewNotFound(testhelper.GitalyOrPraefect(
- fmt.Sprintf("create object reader: GetRepoPath: not a git repository: %q", filepath.Join(cfg.Storages[0].Path, "path")),
- fmt.Sprintf("accessor call: route repository accessor: consistent storages: repository %q/%q not found", cfg.Storages[0].Name, "path"),
- )),
+ expectedErr: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("create object reader: repository not found"),
+ "repository_path", filepath.Join(cfg.Storages[0].Path, "path"),
+ ),
+ structerr.NewNotFound("accessor call: route repository accessor: consistent storages: repository %q/%q not found", cfg.Storages[0].Name, "path"),
+ ),
},
{
desc: "missing object ID",
diff --git a/internal/gitaly/service/commit/isancestor_test.go b/internal/gitaly/service/commit/isancestor_test.go
index 2ef8054f9..9cb8d88ec 100644
--- a/internal/gitaly/service/commit/isancestor_test.go
+++ b/internal/gitaly/service/commit/isancestor_test.go
@@ -10,7 +10,9 @@ import (
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v16/internal/git"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/text"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
"google.golang.org/grpc/codes"
@@ -60,10 +62,13 @@ func TestCommitIsAncestorFailure(t *testing.T) {
AncestorId: "b83d6e391c22777fca1ed3012fce84f633d7fed0",
ChildId: "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab",
},
- expectedErr: status.Error(codes.NotFound, testhelper.GitalyOrPraefect(
- `GetRepoPath: not a git repository: "`+cfg.Storages[0].Path+`/fake-path"`,
- `accessor call: route repository accessor: consistent storages: repository "default"/"fake-path" not found`,
- )),
+ expectedErr: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound),
+ "repository_path", filepath.Join(cfg.Storages[0].Path, "fake-path"),
+ ),
+ structerr.NewNotFound("accessor call: route repository accessor: consistent storages: repository %q/%q not found", cfg.Storages[0].Name, "fake-path"),
+ ),
},
}
diff --git a/internal/gitaly/service/commit/stats_test.go b/internal/gitaly/service/commit/stats_test.go
index 2cfae4277..b1921aa76 100644
--- a/internal/gitaly/service/commit/stats_test.go
+++ b/internal/gitaly/service/commit/stats_test.go
@@ -3,12 +3,12 @@
package commit
import (
- "fmt"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
@@ -108,24 +108,13 @@ func TestCommitStatsFailure(t *testing.T) {
},
Revision: []byte("test-do-not-touch"),
},
- expectedErr: structerr.NewNotFound(testhelper.GitalyOrPraefect(
- fmt.Sprintf("GetRepoPath: not a git repository: %q", filepath.Join(cfg.Storages[0].Path, "bar.git")),
- "accessor call: route repository accessor: consistent storages: repository \"default\"/\"bar.git\" not found",
- )),
- },
- {
- desc: "repo not found",
- request: &gitalypb.CommitStatsRequest{
- Repository: &gitalypb.Repository{
- StorageName: repo.GetStorageName(),
- RelativePath: "bar.git",
- },
- Revision: []byte("test-do-not-touch"),
- },
- expectedErr: structerr.NewNotFound(testhelper.GitalyOrPraefect(
- fmt.Sprintf("GetRepoPath: not a git repository: %q", filepath.Join(cfg.Storages[0].Path, "bar.git")),
- "accessor call: route repository accessor: consistent storages: repository \"default\"/\"bar.git\" not found",
- )),
+ expectedErr: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound),
+ "repository_path", filepath.Join(cfg.Storages[0].Path, "bar.git"),
+ ),
+ structerr.NewNotFound("accessor call: route repository accessor: consistent storages: repository %q/%q not found", cfg.Storages[0].Name, "bar.git"),
+ ),
},
{
desc: "storage not found",
diff --git a/internal/gitaly/service/conflicts/list_conflict_files.go b/internal/gitaly/service/conflicts/list_conflict_files.go
index bc416c445..babd98c33 100644
--- a/internal/gitaly/service/conflicts/list_conflict_files.go
+++ b/internal/gitaly/service/conflicts/list_conflict_files.go
@@ -13,6 +13,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git/localrepo"
"gitlab.com/gitlab-org/gitaly/v16/internal/git2go"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
"gitlab.com/gitlab-org/gitaly/v16/streamio"
@@ -37,7 +38,7 @@ func (s *server) ListConflictFiles(request *gitalypb.ListConflictFilesRequest, s
return structerr.NewFailedPrecondition("could not lookup 'their' OID: %w", err)
}
- repoPath, err := s.locator.GetPath(request.Repository)
+ repoPath, err := s.locator.GetRepoPath(request.Repository, storage.WithRepositoryVerificationSkipped())
if err != nil {
return err
}
diff --git a/internal/gitaly/service/diff/find_changed_paths_test.go b/internal/gitaly/service/diff/find_changed_paths_test.go
index 46b997703..e99329fae 100644
--- a/internal/gitaly/service/diff/find_changed_paths_test.go
+++ b/internal/gitaly/service/diff/find_changed_paths_test.go
@@ -1,13 +1,13 @@
package diff
import (
- "fmt"
"io"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
@@ -970,10 +970,13 @@ func TestFindChangedPathsRequest_failing(t *testing.T) {
desc: "Repo not found",
repo: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: "bar.git"},
commits: []string{newCommit.String(), oldCommit.String()},
- err: structerr.NewNotFound(testhelper.GitalyOrPraefect(
- fmt.Sprintf("GetRepoPath: not a git repository: %q", filepath.Join(cfg.Storages[0].Path, "bar.git")),
- `accessor call: route repository accessor: consistent storages: repository "default"/"bar.git" not found`,
- )),
+ err: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound),
+ "repository_path", filepath.Join(cfg.Storages[0].Path, "bar.git"),
+ ),
+ structerr.NewNotFound("accessor call: route repository accessor: consistent storages: repository %q/%q not found", cfg.Storages[0].Name, "bar.git"),
+ ),
},
{
desc: "Storage not found",
diff --git a/internal/gitaly/service/diff/numstat_test.go b/internal/gitaly/service/diff/numstat_test.go
index 476e78e3a..8546330e3 100644
--- a/internal/gitaly/service/diff/numstat_test.go
+++ b/internal/gitaly/service/diff/numstat_test.go
@@ -4,10 +4,13 @@ package diff
import (
"io"
+ "path/filepath"
"testing"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/diff"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
"google.golang.org/grpc/codes"
@@ -144,10 +147,13 @@ func TestFailedDiffStatsRequest(t *testing.T) {
repo: &gitalypb.Repository{StorageName: repo.GetStorageName(), RelativePath: "bar.git"},
leftCommitID: "e4003da16c1c2c3fc4567700121b17bf8e591c6c",
rightCommitID: "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab",
- expectedErr: status.Error(codes.NotFound, testhelper.GitalyOrPraefect(
- `GetRepoPath: not a git repository: "`+cfg.Storages[0].Path+`/bar.git"`,
- `accessor call: route repository accessor: consistent storages: repository "default"/"bar.git" not found`,
- )),
+ expectedErr: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound),
+ "repository_path", filepath.Join(cfg.Storages[0].Path, "bar.git"),
+ ),
+ structerr.NewNotFound("accessor call: route repository accessor: consistent storages: repository %q/%q not found", cfg.Storages[0].Name, "bar.git"),
+ ),
},
{
desc: "storage not found",
diff --git a/internal/gitaly/service/internalgitaly/walkrepos.go b/internal/gitaly/service/internalgitaly/walkrepos.go
index d10faffcd..a92c84374 100644
--- a/internal/gitaly/service/internalgitaly/walkrepos.go
+++ b/internal/gitaly/service/internalgitaly/walkrepos.go
@@ -50,7 +50,7 @@ func walkStorage(ctx context.Context, storagePath string, stream gitalypb.Intern
// keep walking
}
- if storage.IsGitDirectory(path) {
+ if storage.ValidateRepository(path) == nil {
relPath, err := filepath.Rel(storagePath, path)
if err != nil {
return err
diff --git a/internal/gitaly/service/objectpool/delete_test.go b/internal/gitaly/service/objectpool/delete_test.go
index aa0d2b7f3..483d31945 100644
--- a/internal/gitaly/service/objectpool/delete_test.go
+++ b/internal/gitaly/service/objectpool/delete_test.go
@@ -72,7 +72,10 @@ func TestDelete(t *testing.T) {
desc: "path traversing fails",
relativePath: validPoolPath + "/../../../../..",
expectedErr: testhelper.GitalyOrPraefect(
- structerr.NewInvalidArgument("GetRepoPath: %w", storage.ErrRelativePathEscapesRoot),
+ testhelper.WithInterceptedMetadata(
+ structerr.NewInvalidArgument("%w", storage.ErrRelativePathEscapesRoot),
+ "relative_path", validPoolPath+"/../../../../..",
+ ),
errInvalidPoolDir,
),
},
diff --git a/internal/gitaly/service/operations/apply_patch_test.go b/internal/gitaly/service/operations/apply_patch_test.go
index 09bdeb0a1..68ff120ec 100644
--- a/internal/gitaly/service/operations/apply_patch_test.go
+++ b/internal/gitaly/service/operations/apply_patch_test.go
@@ -6,6 +6,7 @@ import (
"fmt"
"io"
"os"
+ "path/filepath"
"strings"
"testing"
"testing/iotest"
@@ -15,6 +16,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/localrepo"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/transaction"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/backchannel"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/metadata"
@@ -87,13 +89,12 @@ To restore the original branch and stop patching, run "git am --abort".
desc: "non-existent repository",
targetBranch: git.DefaultBranch,
nonExistentRepository: true,
- expectedErr: func() error {
- if testhelper.IsPraefectEnabled() {
- return status.Errorf(codes.NotFound, "mutator call: route repository mutator: get repository id: repository %q/%q not found", cfg.Storages[0].Name, "doesnt-exist")
- }
-
- return status.Errorf(codes.NotFound, "GetRepoPath: not a git repository: \"%s/%s\"", cfg.Storages[0].Path, "doesnt-exist")
- }(),
+ expectedErr: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound), "repository_path", filepath.Join(cfg.Storages[0].Path, "doesnt-exist"),
+ ),
+ structerr.NewNotFound("mutator call: route repository mutator: get repository id: repository %q/%q not found", cfg.Storages[0].Name, "doesnt-exist"),
+ ),
},
{
desc: "creating the first branch does not work",
diff --git a/internal/gitaly/service/operations/commit_files_test.go b/internal/gitaly/service/operations/commit_files_test.go
index 5f8e3e979..6dd6586e4 100644
--- a/internal/gitaly/service/operations/commit_files_test.go
+++ b/internal/gitaly/service/operations/commit_files_test.go
@@ -1693,7 +1693,7 @@ func TestUserCommitFilesFailsIfRepositoryMissing(t *testing.T) {
require.Contains(t, err.Error(), "mutator call: route repository mutator: get repository id")
require.Contains(t, err.Error(), "not found")
} else {
- require.Contains(t, err.Error(), "GetRepoPath: not a git repository")
+ require.Contains(t, err.Error(), "repository not found")
}
}
diff --git a/internal/gitaly/service/operations/merge.go b/internal/gitaly/service/operations/merge.go
index 8d5359fb8..b390bfc06 100644
--- a/internal/gitaly/service/operations/merge.go
+++ b/internal/gitaly/service/operations/merge.go
@@ -15,6 +15,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git2go"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/hook"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
)
@@ -392,7 +393,7 @@ func (s *Server) UserMergeToRef(ctx context.Context, request *gitalypb.UserMerge
return nil, structerr.NewInvalidArgument("%w", err)
}
- repoPath, err := s.locator.GetPath(request.Repository)
+ repoPath, err := s.locator.GetRepoPath(request.Repository, storage.WithRepositoryVerificationSkipped())
if err != nil {
return nil, err
}
diff --git a/internal/gitaly/service/ref/find_refs_by_oid_test.go b/internal/gitaly/service/ref/find_refs_by_oid_test.go
index d1eaeac86..ab0a612bb 100644
--- a/internal/gitaly/service/ref/find_refs_by_oid_test.go
+++ b/internal/gitaly/service/ref/find_refs_by_oid_test.go
@@ -8,6 +8,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
@@ -149,9 +150,12 @@ func TestFindRefsByOID_failure(t *testing.T) {
require.NoError(t, os.RemoveAll(filepath.Join(repoPath, "objects")))
return &gitalypb.FindRefsByOIDRequest{
- Repository: repo,
- Oid: oid.String(),
- }, structerr.NewNotFound("GetRepoPath: not a git repository: %q", repoPath)
+ Repository: repo,
+ Oid: oid.String(),
+ }, testhelper.WithInterceptedMetadata(
+ structerr.NewFailedPrecondition("%w: %q does not exist", storage.ErrRepositoryNotValid, "objects"),
+ "repository_path", repoPath,
+ )
},
},
{
@@ -162,9 +166,12 @@ func TestFindRefsByOID_failure(t *testing.T) {
require.NoError(t, os.RemoveAll(repoPath))
return &gitalypb.FindRefsByOIDRequest{
- Repository: repo,
- Oid: oid.String(),
- }, structerr.NewNotFound("GetRepoPath: not a git repository: %q", repoPath)
+ Repository: repo,
+ Oid: oid.String(),
+ }, testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound),
+ "repository_path", repoPath,
+ )
},
},
{
diff --git a/internal/gitaly/service/ref/refs_test.go b/internal/gitaly/service/ref/refs_test.go
index 418c8ccbf..bc23154b8 100644
--- a/internal/gitaly/service/ref/refs_test.go
+++ b/internal/gitaly/service/ref/refs_test.go
@@ -5,6 +5,7 @@ package ref
import (
"context"
"io"
+ "path/filepath"
"strings"
"testing"
@@ -13,6 +14,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/localrepo"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
@@ -184,10 +186,13 @@ func TestFindDefaultBranchName(t *testing.T) {
request: &gitalypb.FindDefaultBranchNameRequest{
Repository: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: "made/up/path"},
},
- expectedErr: status.Error(codes.NotFound, testhelper.GitalyOrPraefect(
- `get default branch: GetRepoPath: not a git repository: "`+cfg.Storages[0].Path+`/made/up/path"`,
- `accessor call: route repository accessor: consistent storages: repository "default"/"made/up/path" not found`,
- )),
+ expectedErr: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("get default branch: %w", storage.ErrRepositoryNotFound),
+ "repository_path", filepath.Join(cfg.Storages[0].Path, "made/up/path"),
+ ),
+ structerr.NewNotFound("accessor call: route repository accessor: consistent storages: repository %q/%q not found", cfg.Storages[0].Name, "made/up/path"),
+ ),
}
},
},
@@ -483,10 +488,13 @@ func TestFindLocalBranches_validate(t *testing.T) {
{
desc: "repository doesn't exist on disk",
repo: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: "made/up/path"},
- expectedErr: status.Error(codes.NotFound, testhelper.GitalyOrPraefect(
- `creating object reader: GetRepoPath: not a git repository: "`+cfg.Storages[0].Path+`/made/up/path"`,
- `accessor call: route repository accessor: consistent storages: repository "default"/"made/up/path" not found`,
- )),
+ expectedErr: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("creating object reader: %w", storage.ErrRepositoryNotFound),
+ "repository_path", filepath.Join(cfg.Storages[0].Path, "made/up/path"),
+ ),
+ structerr.NewNotFound("accessor call: route repository accessor: consistent storages: repository %q/%q not found", cfg.Storages[0].Name, "made/up/path"),
+ ),
},
{
desc: "unknown storage",
diff --git a/internal/gitaly/service/repository/apply_gitattributes_test.go b/internal/gitaly/service/repository/apply_gitattributes_test.go
index 897c20938..b84478075 100644
--- a/internal/gitaly/service/repository/apply_gitattributes_test.go
+++ b/internal/gitaly/service/repository/apply_gitattributes_test.go
@@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/backchannel"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/metadata"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/perm"
@@ -268,10 +269,13 @@ func TestApplyGitattributes_failure(t *testing.T) {
RelativePath: "bar",
},
revision: []byte("master"),
- expectedErr: structerr.NewNotFound(testhelper.GitalyOrPraefect(
- `GetRepoPath: not a git repository: "`+cfg.Storages[0].Path+`/bar"`,
- `mutator call: route repository mutator: get repository id: repository "default"/"bar" not found`,
- )),
+ expectedErr: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound),
+ "repository_path", filepath.Join(cfg.Storages[0].Path, "bar"),
+ ),
+ structerr.NewNotFound(`mutator call: route repository mutator: get repository id: repository "default"/"bar" not found`),
+ ),
},
{
desc: "no revision provided",
diff --git a/internal/gitaly/service/repository/config.go b/internal/gitaly/service/repository/config.go
index 16e6405fa..ff3e19e19 100644
--- a/internal/gitaly/service/repository/config.go
+++ b/internal/gitaly/service/repository/config.go
@@ -6,6 +6,7 @@ import (
"path/filepath"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
"gitlab.com/gitlab-org/gitaly/v16/streamio"
@@ -20,7 +21,7 @@ func (s *server) GetConfig(
if err := service.ValidateRepository(repository); err != nil {
return structerr.NewInvalidArgument("%w", err)
}
- repoPath, err := s.locator.GetPath(repository)
+ repoPath, err := s.locator.GetRepoPath(repository, storage.WithRepositoryVerificationSkipped())
if err != nil {
return err
}
diff --git a/internal/gitaly/service/repository/create_fork.go b/internal/gitaly/service/repository/create_fork.go
index f6345e19f..65853e49a 100644
--- a/internal/gitaly/service/repository/create_fork.go
+++ b/internal/gitaly/service/repository/create_fork.go
@@ -8,6 +8,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/repoutil"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
)
@@ -24,7 +25,7 @@ func (s *server) CreateFork(ctx context.Context, req *gitalypb.CreateForkRequest
sourceRepository := req.SourceRepository
if err := repoutil.Create(ctx, s.locator, s.gitCmdFactory, s.txManager, targetRepository, func(repo *gitalypb.Repository) error {
- targetPath, err := s.locator.GetPath(repo)
+ targetPath, err := s.locator.GetRepoPath(repo, storage.WithRepositoryVerificationSkipped())
if err != nil {
return err
}
diff --git a/internal/gitaly/service/repository/create_repository_from_bundle_test.go b/internal/gitaly/service/repository/create_repository_from_bundle_test.go
index 7278be7ce..49d6d5166 100644
--- a/internal/gitaly/service/repository/create_repository_from_bundle_test.go
+++ b/internal/gitaly/service/repository/create_repository_from_bundle_test.go
@@ -84,7 +84,7 @@ func TestCreateRepositoryFromBundle_successful(t *testing.T) {
require.NoError(t, err)
importedRepo := localrepo.NewTestRepo(t, cfg, importedRepoProto)
- importedRepoPath, err := locator.GetPath(gittest.RewrittenRepository(t, ctx, cfg, importedRepoProto))
+ importedRepoPath, err := locator.GetRepoPath(gittest.RewrittenRepository(t, ctx, cfg, importedRepoProto), storage.WithRepositoryVerificationSkipped())
require.NoError(t, err)
defer func() { require.NoError(t, os.RemoveAll(importedRepoPath)) }()
diff --git a/internal/gitaly/service/repository/create_repository_from_snapshot.go b/internal/gitaly/service/repository/create_repository_from_snapshot.go
index f741aca54..936650e68 100644
--- a/internal/gitaly/service/repository/create_repository_from_snapshot.go
+++ b/internal/gitaly/service/repository/create_repository_from_snapshot.go
@@ -11,6 +11,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/command"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/repoutil"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
"gitlab.com/gitlab-org/labkit/correlation"
@@ -127,7 +128,7 @@ func (s *server) CreateRepositoryFromSnapshot(ctx context.Context, in *gitalypb.
}
if err := repoutil.Create(ctx, s.locator, s.gitCmdFactory, s.txManager, repository, func(repo *gitalypb.Repository) error {
- path, err := s.locator.GetPath(repo)
+ path, err := s.locator.GetRepoPath(repo, storage.WithRepositoryVerificationSkipped())
if err != nil {
return structerr.NewInternal("getting repo path: %w", err)
}
diff --git a/internal/gitaly/service/repository/create_repository_from_url.go b/internal/gitaly/service/repository/create_repository_from_url.go
index 0ef15ac3b..98f9b5eb9 100644
--- a/internal/gitaly/service/repository/create_repository_from_url.go
+++ b/internal/gitaly/service/repository/create_repository_from_url.go
@@ -11,6 +11,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/repoutil"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
)
@@ -82,7 +83,7 @@ func (s *server) CreateRepositoryFromURL(ctx context.Context, req *gitalypb.Crea
}
if err := repoutil.Create(ctx, s.locator, s.gitCmdFactory, s.txManager, req.GetRepository(), func(repo *gitalypb.Repository) error {
- targetPath, err := s.locator.GetPath(repo)
+ targetPath, err := s.locator.GetRepoPath(repo, storage.WithRepositoryVerificationSkipped())
if err != nil {
return fmt.Errorf("getting temporary repository path: %w", err)
}
diff --git a/internal/gitaly/service/repository/fetch_bundle_test.go b/internal/gitaly/service/repository/fetch_bundle_test.go
index b7eed4669..aefc5f41c 100644
--- a/internal/gitaly/service/repository/fetch_bundle_test.go
+++ b/internal/gitaly/service/repository/fetch_bundle_test.go
@@ -12,7 +12,9 @@ import (
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
gitalyhook "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/hook"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/metadata"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testcfg"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testserver"
@@ -155,10 +157,13 @@ func TestServer_FetchBundle_validation(t *testing.T) {
RelativePath: "unknown",
},
},
- expectedErr: status.Error(codes.NotFound, testhelper.GitalyOrPraefect(
- `GetRepoPath: not a git repository: "`+cfg.Storages[0].Path+`/unknown"`,
- `mutator call: route repository mutator: get repository id: repository "default"/"unknown" not found`,
- )),
+ expectedErr: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound),
+ "repository_path", filepath.Join(cfg.Storages[0].Path, "unknown"),
+ ),
+ structerr.NewNotFound(`mutator call: route repository mutator: get repository id: repository "default"/"unknown" not found`),
+ ),
},
} {
t.Run(tc.desc, func(t *testing.T) {
diff --git a/internal/gitaly/service/repository/fullpath_test.go b/internal/gitaly/service/repository/fullpath_test.go
index fe06ea544..e61489a97 100644
--- a/internal/gitaly/service/repository/fullpath_test.go
+++ b/internal/gitaly/service/repository/fullpath_test.go
@@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
- "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/text"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
@@ -63,8 +63,6 @@ func TestSetFullPath(t *testing.T) {
RelativePath: "/path/to/repo.git",
StorageName: cfg.Storages[0].Name,
}
- repoPath, err := config.NewLocator(cfg).GetPath(repo)
- require.NoError(t, err)
response, err := client.SetFullPath(ctx, &gitalypb.SetFullPathRequest{
Repository: repo,
@@ -73,7 +71,7 @@ func TestSetFullPath(t *testing.T) {
require.Nil(t, response)
- expectedErr := fmt.Sprintf("rpc error: code = NotFound desc = setting config: GetRepoPath: not a git repository: %q", repoPath)
+ expectedErr := fmt.Sprintf("rpc error: code = NotFound desc = setting config: %s", storage.ErrRepositoryNotFound)
if testhelper.IsPraefectEnabled() {
expectedErr = `rpc error: code = NotFound desc = mutator call: route repository mutator: get repository id: repository "default"/"/path/to/repo.git" not found`
}
@@ -169,15 +167,13 @@ func TestFullPath(t *testing.T) {
RelativePath: "/path/to/repo.git",
StorageName: cfg.Storages[0].Name,
}
- repoPath, err := config.NewLocator(cfg).GetPath(repo)
- require.NoError(t, err)
response, err := client.FullPath(ctx, &gitalypb.FullPathRequest{
Repository: repo,
})
require.Nil(t, response)
- expectedErr := fmt.Sprintf("rpc error: code = NotFound desc = fetch config: GetRepoPath: not a git repository: %q", repoPath)
+ expectedErr := fmt.Sprintf("rpc error: code = NotFound desc = fetch config: %s", storage.ErrRepositoryNotFound)
if testhelper.IsPraefectEnabled() {
expectedErr = `rpc error: code = NotFound desc = accessor call: route repository accessor: consistent storages: repository "default"/"/path/to/repo.git" not found`
}
diff --git a/internal/gitaly/service/repository/license_test.go b/internal/gitaly/service/repository/license_test.go
index 01a703def..4b93e16f5 100644
--- a/internal/gitaly/service/repository/license_test.go
+++ b/internal/gitaly/service/repository/license_test.go
@@ -12,6 +12,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/featureflag"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/catfile"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testcfg"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testserver"
@@ -64,7 +65,7 @@ func TestFindLicense_successful(t *testing.T) {
setup: func(t *testing.T, repoPath string) {
require.NoError(t, os.RemoveAll(repoPath))
},
- errorContains: "GetRepoPath: not a git repository",
+ errorContains: storage.ErrRepositoryNotFound.Error(),
},
{
desc: "empty if no license file in repo",
diff --git a/internal/gitaly/service/repository/object_format_test.go b/internal/gitaly/service/repository/object_format_test.go
index d80a2a655..a99b3b966 100644
--- a/internal/gitaly/service/repository/object_format_test.go
+++ b/internal/gitaly/service/repository/object_format_test.go
@@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v16/internal/errors"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/perm"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
@@ -85,8 +86,9 @@ func TestObjectFormat(t *testing.T) {
},
},
expectedErr: testhelper.GitalyOrPraefect(
- structerr.NewNotFound(
- "GetRepoPath: not a git repository: %q", filepath.Join(cfg.Storages[0].Path, "nonexistent.git"),
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound),
+ "repository_path", filepath.Join(cfg.Storages[0].Path, "nonexistent.git"),
),
structerr.NewNotFound(
"accessor call: route repository accessor: consistent storages: repository %q/%q not found",
diff --git a/internal/gitaly/service/repository/optimize_test.go b/internal/gitaly/service/repository/optimize_test.go
index 54a509d80..af5751686 100644
--- a/internal/gitaly/service/repository/optimize_test.go
+++ b/internal/gitaly/service/repository/optimize_test.go
@@ -17,6 +17,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git/housekeeping"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/localrepo"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/stats"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/perm"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/text"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
@@ -364,10 +365,13 @@ func TestOptimizeRepository_validation(t *testing.T) {
RelativePath: "path/not/exist",
},
},
- expectedErr: structerr.NewNotFound(testhelper.GitalyOrPraefect(
- fmt.Sprintf(`GetRepoPath: not a git repository: "%s/path/not/exist"`, cfg.Storages[0].Path),
- `routing repository maintenance: getting repository metadata: repository not found`,
- )),
+ expectedErr: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound),
+ "repository_path", filepath.Join(cfg.Storages[0].Path, "path/not/exist"),
+ ),
+ structerr.NewNotFound("routing repository maintenance: getting repository metadata: %w", storage.ErrRepositoryNotFound),
+ ),
},
{
desc: "invalid optimization strategy",
diff --git a/internal/gitaly/service/repository/prune_unreachable_objects_test.go b/internal/gitaly/service/repository/prune_unreachable_objects_test.go
index 4c64a1d68..310e4e7ec 100644
--- a/internal/gitaly/service/repository/prune_unreachable_objects_test.go
+++ b/internal/gitaly/service/repository/prune_unreachable_objects_test.go
@@ -11,6 +11,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/localrepo"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/stats"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
@@ -43,7 +44,13 @@ func TestPruneUnreachableObjects(t *testing.T) {
_, err := client.PruneUnreachableObjects(ctx, &gitalypb.PruneUnreachableObjectsRequest{
Repository: repo,
})
- testhelper.RequireGrpcError(t, structerr.NewNotFound("GetRepoPath: not a git repository: %q", repoPath), err)
+ testhelper.RequireGrpcError(t,
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound),
+ "repository_path", repoPath,
+ ),
+ err,
+ )
})
t.Run("empty repository", func(t *testing.T) {
diff --git a/internal/gitaly/service/repository/rename.go b/internal/gitaly/service/repository/rename.go
index 3c7ec054f..ab68ef51b 100644
--- a/internal/gitaly/service/repository/rename.go
+++ b/internal/gitaly/service/repository/rename.go
@@ -9,6 +9,7 @@ import (
"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/perm"
"gitlab.com/gitlab-org/gitaly/v16/internal/safe"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
@@ -38,7 +39,7 @@ func (s *server) renameRepository(ctx context.Context, sourceRepo, targetRepo *g
return structerr.NewInvalidArgument("%w", err)
}
- targetPath, err := s.locator.GetPath(targetRepo)
+ targetPath, err := s.locator.GetRepoPath(targetRepo, storage.WithRepositoryVerificationSkipped())
if err != nil {
return structerr.NewInvalidArgument("%w", err)
}
diff --git a/internal/gitaly/service/repository/rename_test.go b/internal/gitaly/service/repository/rename_test.go
index 221533938..876ae5db1 100644
--- a/internal/gitaly/service/repository/rename_test.go
+++ b/internal/gitaly/service/repository/rename_test.go
@@ -1,14 +1,13 @@
package repository
import (
- "fmt"
"path/filepath"
- "strings"
"testing"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
"google.golang.org/grpc/codes"
@@ -53,7 +52,7 @@ func TestRenameRepositorySuccess(t *testing.T) {
}
require.DirExists(t, newDirectory)
- require.True(t, storage.IsGitDirectory(newDirectory), "moved Git repository has been corrupted")
+ require.NoError(t, storage.ValidateRepository(newDirectory), "moved Git repository has been corrupted")
// ensure the git directory that got renamed contains the original commit.
gittest.RequireObjectExists(t, cfg, newDirectory, commitID)
}
@@ -85,8 +84,7 @@ func TestRenameRepositoryInvalidRequest(t *testing.T) {
ctx := testhelper.Context(t)
cfg, client := setupRepositoryServiceWithoutRepo(t)
- repo, repoPath := gittest.CreateRepository(t, ctx, cfg)
- storagePath := strings.TrimSuffix(repoPath, "/"+repo.RelativePath)
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
testCases := []struct {
desc string
@@ -106,7 +104,13 @@ func TestRenameRepositoryInvalidRequest(t *testing.T) {
{
desc: "destination relative path contains path traversal",
req: &gitalypb.RenameRepositoryRequest{Repository: repo, RelativePath: "../usr/bin"},
- exp: status.Error(codes.InvalidArgument, "GetRepoPath: relative path escapes root directory"),
+ exp: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewInvalidArgument("%w", storage.ErrRelativePathEscapesRoot),
+ "relative_path", "../usr/bin",
+ ),
+ structerr.NewInvalidArgument("GetRepoPath: %w", storage.ErrRelativePathEscapesRoot),
+ ),
},
{
desc: "repository storage doesn't exist",
@@ -116,7 +120,13 @@ func TestRenameRepositoryInvalidRequest(t *testing.T) {
{
desc: "repository relative path doesn't exist",
req: &gitalypb.RenameRepositoryRequest{Repository: &gitalypb.Repository{StorageName: repo.StorageName, RelativePath: "stub"}, RelativePath: "non-existent/directory"},
- exp: status.Error(codes.NotFound, fmt.Sprintf(`GetRepoPath: not a git repository: "%s/stub"`, testhelper.GitalyOrPraefect(storagePath, repo.GetStorageName()))),
+ exp: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound),
+ "repository_path", filepath.Join(cfg.Storages[0].Path, "stub"),
+ ),
+ structerr.NewNotFound(`GetRepoPath: not a git repository: "%s/stub"`, repo.GetStorageName()),
+ ),
},
}
diff --git a/internal/gitaly/service/repository/replicate.go b/internal/gitaly/service/repository/replicate.go
index 74d13cf6b..429c46103 100644
--- a/internal/gitaly/service/repository/replicate.go
+++ b/internal/gitaly/service/repository/replicate.go
@@ -39,12 +39,12 @@ func (s *server) ReplicateRepository(ctx context.Context, in *gitalypb.Replicate
return nil, structerr.NewInvalidArgument("%w", err)
}
- repoPath, err := s.locator.GetPath(in.GetRepository())
+ repoPath, err := s.locator.GetRepoPath(in.GetRepository(), storage.WithRepositoryVerificationSkipped())
if err != nil {
return nil, structerr.NewInternal("%w", err)
}
- if !storage.IsGitDirectory(repoPath) {
+ if err := storage.ValidateRepository(repoPath); err != nil {
if err = s.create(ctx, in, repoPath); err != nil {
if errors.Is(err, ErrInvalidSourceRepository) {
return nil, ErrInvalidSourceRepository
@@ -175,11 +175,18 @@ func (s *server) extractSnapshot(ctx context.Context, source, target *gitalypb.R
// platforms.
firstBytes, err := stream.Recv()
if err != nil {
- if structerr.GRPCCode(err) == codes.NotFound && strings.Contains(err.Error(), "GetRepoPath: not a git repository:") {
+ switch {
+ case structerr.GRPCCode(err) == codes.NotFound && strings.Contains(err.Error(), "GetRepoPath: not a git repository:"):
+ // The error condition exists for backwards compatibility purposes, only,
+ // and can be removed in the next release.
return ErrInvalidSourceRepository
+ case structerr.GRPCCode(err) == codes.NotFound && strings.Contains(err.Error(), storage.ErrRepositoryNotFound.Error()):
+ return ErrInvalidSourceRepository
+ case structerr.GRPCCode(err) == codes.FailedPrecondition && strings.Contains(err.Error(), storage.ErrRepositoryNotValid.Error()):
+ return ErrInvalidSourceRepository
+ default:
+ return fmt.Errorf("first snapshot read: %w", err)
}
-
- return fmt.Errorf("first snapshot read: %w", err)
}
snapshotReader := io.MultiReader(
@@ -190,7 +197,7 @@ func (s *server) extractSnapshot(ctx context.Context, source, target *gitalypb.R
}),
)
- targetPath, err := s.locator.GetPath(target)
+ targetPath, err := s.locator.GetRepoPath(target, storage.WithRepositoryVerificationSkipped())
if err != nil {
return fmt.Errorf("target path: %w", err)
}
diff --git a/internal/gitaly/service/repository/repository_exists.go b/internal/gitaly/service/repository/repository_exists.go
index ab30a921e..1ebf1c190 100644
--- a/internal/gitaly/service/repository/repository_exists.go
+++ b/internal/gitaly/service/repository/repository_exists.go
@@ -13,10 +13,12 @@ func (s *server) RepositoryExists(ctx context.Context, in *gitalypb.RepositoryEx
if err := service.ValidateRepository(in.GetRepository()); err != nil {
return nil, structerr.NewInvalidArgument("%w", err)
}
- path, err := s.locator.GetPath(in.Repository)
+ path, err := s.locator.GetRepoPath(in.Repository, storage.WithRepositoryVerificationSkipped())
if err != nil {
return nil, err
}
- return &gitalypb.RepositoryExistsResponse{Exists: storage.IsGitDirectory(path)}, nil
+ // TODO: we really should only be checking whether the repository actually doesn't exist. If
+ // it does, but is not a valid Git repository, we should be returning an error here.
+ return &gitalypb.RepositoryExistsResponse{Exists: storage.ValidateRepository(path) == nil}, nil
}
diff --git a/internal/gitaly/service/repository/repository_exists_test.go b/internal/gitaly/service/repository/repository_exists_test.go
index b325388be..70a93c51c 100644
--- a/internal/gitaly/service/repository/repository_exists_test.go
+++ b/internal/gitaly/service/repository/repository_exists_test.go
@@ -7,6 +7,7 @@ import (
"github.com/stretchr/testify/require"
gitalyerrors "gitlab.com/gitlab-org/gitaly/v16/internal/errors"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testcfg"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
@@ -113,7 +114,10 @@ func TestRepositoryExists(t *testing.T) {
return nil
}
- return status.Errorf(codes.NotFound, "GetPath: does not exist: stat %s: no such file or directory", cfg.Storages[2].Path)
+ return testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("storage does not exist"),
+ "storage_path", cfg.Storages[2].Path,
+ )
}(),
},
}
@@ -121,7 +125,7 @@ func TestRepositoryExists(t *testing.T) {
for _, tc := range queries {
t.Run(tc.desc, func(t *testing.T) {
response, err := client.RepositoryExists(ctx, tc.request)
- testhelper.ProtoEqual(t, tc.expectedErr, err)
+ testhelper.RequireGrpcError(t, tc.expectedErr, err)
if err != nil {
// Ignore the response message if there was an error
return
diff --git a/internal/gitaly/service/repository/repository_info_test.go b/internal/gitaly/service/repository/repository_info_test.go
index 50fb1f35c..6cdf979cf 100644
--- a/internal/gitaly/service/repository/repository_info_test.go
+++ b/internal/gitaly/service/repository/repository_info_test.go
@@ -12,6 +12,7 @@ import (
gitalyerrors "gitlab.com/gitlab-org/gitaly/v16/internal/errors"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/stats"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/perm"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
@@ -74,7 +75,10 @@ func TestRepositoryInfo(t *testing.T) {
},
},
expectedErr: testhelper.GitalyOrPraefect(
- structerr.NewNotFound("GetRepoPath: not a git repository: %q", filepath.Join(cfg.Storages[0].Path, "does", "not", "exist")),
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound),
+ "repository_path", filepath.Join(cfg.Storages[0].Path, "does", "not", "exist"),
+ ),
structerr.NewNotFound(
"accessor call: route repository accessor: consistent storages: repository %q/%q not found",
cfg.Storages[0].Name,
diff --git a/internal/gitaly/service/smarthttp/inforefs_test.go b/internal/gitaly/service/smarthttp/inforefs_test.go
index 364f132ba..84e4769aa 100644
--- a/internal/gitaly/service/smarthttp/inforefs_test.go
+++ b/internal/gitaly/service/smarthttp/inforefs_test.go
@@ -18,7 +18,9 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/stats"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/perm"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testcfg"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testserver"
@@ -149,10 +151,12 @@ func TestInfoRefsUploadPack_validate(t *testing.T) {
StorageName: cfg.Storages[0].Name,
RelativePath: "doesnt/exist",
}},
- expectedErr: status.Error(codes.NotFound, testhelper.GitalyOrPraefect(
- `GetRepoPath: not a git repository: "`+cfg.Storages[0].Path+`/doesnt/exist"`,
- `accessor call: route repository accessor: consistent storages: repository "default"/"doesnt/exist" not found`,
- )),
+ expectedErr: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound), "repository_path", filepath.Join(cfg.Storages[0].Path, "doesnt/exist"),
+ ),
+ structerr.NewNotFound("accessor call: route repository accessor: consistent storages: repository %q/%q not found", cfg.Storages[0].Name, "doesnt/exist"),
+ ),
},
} {
_, err := makeInfoRefsUploadPackRequest(t, ctx, serverSocketPath, cfg.Auth.Token, tc.req)
@@ -336,10 +340,13 @@ func TestInfoRefsReceivePack_validate(t *testing.T) {
StorageName: cfg.Storages[0].Name,
RelativePath: "testdata/scratch/another_repo",
}},
- expectedErr: status.Error(codes.NotFound, testhelper.GitalyOrPraefect(
- `GetRepoPath: not a git repository: "`+cfg.Storages[0].Path+`/testdata/scratch/another_repo"`,
- `accessor call: route repository accessor: consistent storages: repository "default"/"testdata/scratch/another_repo" not found`,
- )),
+ expectedErr: testhelper.GitalyOrPraefect(
+ testhelper.WithInterceptedMetadata(
+ structerr.NewNotFound("%w", storage.ErrRepositoryNotFound),
+ "repository_path", filepath.Join(cfg.Storages[0].Path, "testdata/scratch/another_repo"),
+ ),
+ structerr.NewNotFound("accessor call: route repository accessor: consistent storages: repository %q/%q not found", cfg.Storages[0].Name, "testdata/scratch/another_repo"),
+ ),
},
} {
_, err := makeInfoRefsReceivePackRequest(t, ctx, serverSocketPath, cfg.Auth.Token, tc.req)
diff --git a/internal/gitaly/service/ssh/upload_pack_test.go b/internal/gitaly/service/ssh/upload_pack_test.go
index 811a91303..2c84f778f 100644
--- a/internal/gitaly/service/ssh/upload_pack_test.go
+++ b/internal/gitaly/service/ssh/upload_pack_test.go
@@ -797,7 +797,7 @@ func TestUploadPack_gitFailure(t *testing.T) {
client := newSSHClient(t, cfg.SocketPath)
- // Writing an invalid config will allow repo to pass the `IsGitDirectory` check but still
+ // Writing an invalid config will allow repo to pass the `ValidateRepository` check but still
// trigger an error when git tries to access the repo.
require.NoError(t, os.WriteFile(filepath.Join(repoPath, "config"), []byte("Not a valid gitconfig"), perm.SharedFile))
diff --git a/internal/gitaly/storage/locator.go b/internal/gitaly/storage/locator.go
index 550802c0f..8d6e17adb 100644
--- a/internal/gitaly/storage/locator.go
+++ b/internal/gitaly/storage/locator.go
@@ -7,6 +7,46 @@ import (
"os"
"path/filepath"
"strings"
+
+ "gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
+)
+
+// RepositoryNotFoundError is returned when attempting to operate on a repository that does not
+// exist in the virtual storage.
+type RepositoryNotFoundError struct {
+ virtualStorage string
+ relativePath string
+}
+
+// NewRepositoryNotFoundError returns a new repository not found error for the given repository.
+func NewRepositoryNotFoundError(virtualStorage string, relativePath string) error {
+ return RepositoryNotFoundError{virtualStorage: virtualStorage, relativePath: relativePath}
+}
+
+// Error returns the error message.
+func (err RepositoryNotFoundError) Error() string {
+ return fmt.Sprintf("repository %q/%q not found", err.virtualStorage, err.relativePath)
+}
+
+var (
+ // ErrRepositoryNotFound is returned when operating on a repository that doesn't exist.
+ //
+ // This somewhat duplicates the above RepositoryNotFoundError but doesn't specify which
+ // repository was not found. With repository IDs in use, the virtual storage and relative
+ // path won't be available everywhere anymore.
+ ErrRepositoryNotFound = errors.New("repository not found")
+
+ // ErrRepositoryAlreadyExists is returned when attempting to create a repository that
+ // already exists.
+ ErrRepositoryAlreadyExists = errors.New("repository already exists")
+
+ // ErrRepositoryNotValid is returned when operating on a path that is not a valid Git
+ // repository.
+ ErrRepositoryNotValid = errors.New("repository not valid")
+
+ // ErrRelativePathEscapesRoot is returned when a relative path is passed that escapes the
+ // storage's root directory.
+ ErrRelativePathEscapesRoot = errors.New("relative path escapes root directory")
)
// Repository represents a storage-scoped repository.
@@ -31,10 +71,6 @@ type Locator interface {
// will be skipped. The errors returned are gRPC errors with relevant error codes and should be
// passed back to gRPC without further decoration.
GetRepoPath(repo Repository, opts ...GetRepoPathOption) (string, error)
- // GetPath returns the path of the repo passed as first argument. An error is
- // returned when either the storage can't be found or the path includes
- // constructs trying to perform directory traversal.
- GetPath(repo Repository) (string, error)
// GetStorageByName will return the path for the storage, which is fetched by
// its key. An error is return if it cannot be found.
GetStorageByName(storageName string) (string, error)
@@ -65,9 +101,6 @@ func WithRepositoryVerificationSkipped() GetRepoPathOption {
}
}
-//nolint:revive // This is unintentionally missing documentation.
-var ErrRelativePathEscapesRoot = errors.New("relative path escapes root directory")
-
// ValidateRelativePath validates a relative path by joining it with rootDir and verifying the result
// is either rootDir or a path within rootDir. Returns clean relative path from rootDir to relativePath
// or an ErrRelativePathEscapesRoot if the resulting path is not contained within rootDir.
@@ -80,16 +113,32 @@ func ValidateRelativePath(rootDir, relativePath string) (string, error) {
return filepath.Rel(rootDir, absPath)
}
-// IsGitDirectory checks if the directory passed as first argument looks like
-// a valid git directory.
-func IsGitDirectory(dir string) bool {
- if dir == "" {
- return false
+// ValidateRepository validates whether the given path points to a valid Git repository. This
+// function returns:
+//
+// - ErrRepositoryNotExist when the path cannot be found.
+// - ErrRepositoryNotValid when the repository is not a valid Git repository.
+// - An unspecified error when stat(3P)ing files fails due to other reasons.
+func ValidateRepository(path string) error {
+ if path == "" {
+ return structerr.NewInvalidArgument("repository path is empty")
+ }
+
+ if _, err := os.Stat(path); err != nil {
+ if errors.Is(err, os.ErrNotExist) {
+ return structerr.NewNotFound("%w", ErrRepositoryNotFound).WithMetadata("repository_path", path)
+ }
+
+ return structerr.New("statting repository: %w", err).WithMetadata("repository_path", path)
}
for _, element := range []string{"objects", "refs", "HEAD"} {
- if _, err := os.Stat(filepath.Join(dir, element)); err != nil {
- return false
+ if _, err := os.Stat(filepath.Join(path, element)); err != nil {
+ if errors.Is(err, os.ErrNotExist) {
+ return structerr.NewFailedPrecondition("%w: %q does not exist", ErrRepositoryNotValid, element).WithMetadata("repository_path", path)
+ }
+
+ return structerr.New("statting %q: %w", element, err).WithMetadata("repository_path", path)
}
}
@@ -101,9 +150,9 @@ func IsGitDirectory(dir string) bool {
// git gc runs for a long time while keeping open the packed-refs file.
// Running stat() on the file causes the kernel to revalidate the cached
// directory entry. We don't actually care if this file exists.
- _, _ = os.Stat(filepath.Join(dir, "packed-refs"))
+ _, _ = os.Stat(filepath.Join(path, "packed-refs"))
- return true
+ return nil
}
// QuarantineDirectoryPrefix returns a prefix for use in the temporary directory. The prefix is
diff --git a/internal/praefect/commonerr/error.go b/internal/praefect/commonerr/error.go
deleted file mode 100644
index d113f4485..000000000
--- a/internal/praefect/commonerr/error.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Package commonerr contains common errors between different Praefect components. Ideally
-// this package's contents would be in praefect's root package but this is not possible at the moment
-// due to cyclic imports.
-package commonerr
-
-import (
- "errors"
- "fmt"
-)
-
-// RepositoryNotFoundError is returned when attempting to operate on a repository
-// that does not exist in the virtual storage.
-type RepositoryNotFoundError struct {
- virtualStorage string
- relativePath string
-}
-
-// NewRepositoryNotFoundError returns a new repository not found error for the given repository.
-func NewRepositoryNotFoundError(virtualStorage string, relativePath string) error {
- return RepositoryNotFoundError{virtualStorage: virtualStorage, relativePath: relativePath}
-}
-
-// Error returns the error message.
-func (err RepositoryNotFoundError) Error() string {
- return fmt.Sprintf("repository %q/%q not found", err.virtualStorage, err.relativePath)
-}
-
-// ErrRepositoryNotFound is returned when operating on a repository that doesn't exist.
-//
-// This somewhat duplicates the above RepositoryNotFoundError but doesn't specify which repository was not found.
-// With repository IDs in use, the virtual storage and relative path won't be available everywhere anymore.
-var ErrRepositoryNotFound = errors.New("repository not found")
-
-// ErrRepositoryAlreadyExists is returned when attempting to create a repository that already exists.
-var ErrRepositoryAlreadyExists = errors.New("repository already exists")
diff --git a/internal/praefect/coordinator.go b/internal/praefect/coordinator.go
index 24eb35825..bab8957c0 100644
--- a/internal/praefect/coordinator.go
+++ b/internal/praefect/coordinator.go
@@ -12,11 +12,11 @@ import (
"github.com/sirupsen/logrus"
gitalyerrors "gitlab.com/gitlab-org/gitaly/v16/internal/errors"
"gitlab.com/gitlab-org/gitaly/v16/internal/featureflag"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/metadata"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/middleware/metadatahandler"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/proxy"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/config"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/metrics"
@@ -263,11 +263,11 @@ func (c *Coordinator) directRepositoryScopedMessage(ctx context.Context, call gr
}
if err != nil {
- if errors.As(err, new(commonerr.RepositoryNotFoundError)) {
+ if errors.As(err, new(storage.RepositoryNotFoundError)) {
return nil, structerr.NewNotFound("%w", err)
}
- if errors.Is(err, commonerr.ErrRepositoryNotFound) {
+ if errors.Is(err, storage.ErrRepositoryNotFound) {
return nil, structerr.NewNotFound("%w", err)
}
@@ -407,7 +407,7 @@ func (c *Coordinator) mutatorStreamParameters(ctx context.Context, call grpcCall
// ReplicateRepository RPC should also be able to replicate if repository ID already exists in Praefect.
if call.fullMethodName == "/gitaly.RepositoryService/ReplicateRepository" &&
- errors.Is(err, commonerr.ErrRepositoryAlreadyExists) {
+ errors.Is(err, storage.ErrRepositoryAlreadyExists) {
change = datastore.UpdateRepo
route, err = c.router.RouteRepositoryMutator(ctx, virtualStorage, targetRepo.RelativePath, additionalRepoRelativePath)
}
@@ -702,7 +702,7 @@ func (c *Coordinator) StreamDirector(ctx context.Context, fullMethodName string,
return nil, structerr.NewInvalidArgument("%w", err)
}
- if errors.Is(err, commonerr.ErrRepositoryAlreadyExists) {
+ if errors.Is(err, storage.ErrRepositoryAlreadyExists) {
return nil, structerr.NewAlreadyExists("%w", err)
}
diff --git a/internal/praefect/coordinator_test.go b/internal/praefect/coordinator_test.go
index d843f382a..150b87ece 100644
--- a/internal/praefect/coordinator_test.go
+++ b/internal/praefect/coordinator_test.go
@@ -25,10 +25,10 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
gconfig "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
gitaly_metadata "gitlab.com/gitlab-org/gitaly/v16/internal/grpc/metadata"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/middleware/metadatahandler"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/proxy"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/config"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/nodes"
@@ -303,7 +303,7 @@ func TestStreamDirectorMutator(t *testing.T) {
request: &gitalypb.UserCreateTagRequest{
Repository: targetRepo,
},
- expectedErr: structerr.NewNotFound("%w", fmt.Errorf("mutator call: route repository mutator: %w", fmt.Errorf("get repository id: %w", commonerr.NewRepositoryNotFoundError(targetRepo.StorageName, targetRepo.RelativePath)))),
+ expectedErr: structerr.NewNotFound("%w", fmt.Errorf("mutator call: route repository mutator: %w", fmt.Errorf("get repository id: %w", storage.NewRepositoryNotFoundError(targetRepo.StorageName, targetRepo.RelativePath)))),
}
},
},
@@ -334,7 +334,7 @@ func TestStreamDirectorMutator(t *testing.T) {
expectedErr: structerr.NewNotFound("%w", fmt.Errorf("mutator call: route repository mutator: %w",
fmt.Errorf("resolve additional replica path: %w",
fmt.Errorf("get additional repository id: %w",
- commonerr.NewRepositoryNotFoundError(additionalRepo.StorageName, additionalRepo.RelativePath),
+ storage.NewRepositoryNotFoundError(additionalRepo.StorageName, additionalRepo.RelativePath),
),
),
)),
@@ -696,7 +696,7 @@ func TestStreamDirectorMutator_ReplicateRepository(t *testing.T) {
router := mockRouter{
// Simulate scenario where target repository already exists and error is returned.
routeRepositoryCreation: func(ctx context.Context, virtualStorage, relativePath, additionalRepoRelativePath string) (RepositoryMutatorRoute, error) {
- return RepositoryMutatorRoute{}, fmt.Errorf("reserve repository id: %w", commonerr.ErrRepositoryAlreadyExists)
+ return RepositoryMutatorRoute{}, fmt.Errorf("reserve repository id: %w", storage.ErrRepositoryAlreadyExists)
},
// Pass through normally to handle route creation.
routeRepositoryMutator: func(ctx context.Context, virtualStorage, relativePath, additionalRepoRelativePath string) (RepositoryMutatorRoute, error) {
@@ -1086,10 +1086,10 @@ func TestStreamDirectorAccessor(t *testing.T) {
desc: "repository not found",
router: mockRouter{
routeRepositoryAccessorFunc: func(_ context.Context, virtualStorage, relativePath string, _ bool) (RepositoryAccessorRoute, error) {
- return RepositoryAccessorRoute{}, commonerr.NewRepositoryNotFoundError(virtualStorage, relativePath)
+ return RepositoryAccessorRoute{}, storage.NewRepositoryNotFoundError(virtualStorage, relativePath)
},
},
- error: structerr.NewNotFound("%w", fmt.Errorf("accessor call: route repository accessor: %w", commonerr.NewRepositoryNotFoundError(targetRepo.StorageName, targetRepo.RelativePath))),
+ error: structerr.NewNotFound("%w", fmt.Errorf("accessor call: route repository accessor: %w", storage.NewRepositoryNotFoundError(targetRepo.StorageName, targetRepo.RelativePath))),
},
} {
t.Run(tc.desc, func(t *testing.T) {
diff --git a/internal/praefect/datastore/assignment_test.go b/internal/praefect/datastore/assignment_test.go
index 1f97fe40e..73ec3c8d8 100644
--- a/internal/praefect/datastore/assignment_test.go
+++ b/internal/praefect/datastore/assignment_test.go
@@ -6,7 +6,7 @@ import (
"testing"
"github.com/stretchr/testify/require"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore/glsql"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testdb"
@@ -83,7 +83,7 @@ func TestAssignmentStore_GetHostAssignments(t *testing.T) {
rs := NewPostgresRepositoryStore(db, nil)
for _, assignment := range tc.existingAssignments {
repositoryID, err := rs.GetRepositoryID(ctx, assignment.virtualStorage, assignment.relativePath)
- if errors.Is(err, commonerr.NewRepositoryNotFoundError(assignment.virtualStorage, assignment.relativePath)) {
+ if errors.Is(err, storage.NewRepositoryNotFoundError(assignment.virtualStorage, assignment.relativePath)) {
repositoryID, err = rs.ReserveRepositoryID(ctx, assignment.virtualStorage, assignment.relativePath)
require.NoError(t, err)
@@ -99,7 +99,7 @@ func TestAssignmentStore_GetHostAssignments(t *testing.T) {
repositoryID, err := rs.GetRepositoryID(ctx, tc.virtualStorage, "relative-path")
if err != nil {
- require.Equal(t, commonerr.NewRepositoryNotFoundError(tc.virtualStorage, "relative-path"), err)
+ require.Equal(t, storage.NewRepositoryNotFoundError(tc.virtualStorage, "relative-path"), err)
}
actualAssignments, err := NewAssignmentStore(
diff --git a/internal/praefect/datastore/repository_store.go b/internal/praefect/datastore/repository_store.go
index 968daf15a..c6a41dff3 100644
--- a/internal/praefect/datastore/repository_store.go
+++ b/internal/praefect/datastore/repository_store.go
@@ -10,7 +10,7 @@ import (
"time"
"gitlab.com/gitlab-org/gitaly/v16/internal/datastructure"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore/glsql"
)
@@ -90,7 +90,7 @@ type RepositoryStore interface {
// SetGeneration sets the repository's generation on the given storage. If the generation is higher
// than the virtual storage's generation, it is set to match as well to guarantee monotonic increments.
SetGeneration(ctx context.Context, repositoryID int64, storage, relativePath string, generation int) error
- // GetReplicaPath gets the replica path of a repository. Returns a commonerr.ErrRepositoryNotFound if a record
+ // GetReplicaPath gets the replica path of a repository. Returns a storage.ErrRepositoryNotFound if a record
// for the repository ID is not found.
GetReplicaPath(ctx context.Context, repositoryID int64) (string, error)
// GetReplicatedGeneration returns the generation propagated by applying the replication. If the generation would
@@ -110,7 +110,7 @@ type RepositoryStore interface {
// SetAuthoritativeReplica sets the given replica of a repsitory as the authoritative one by setting its generation as the latest one.
SetAuthoritativeReplica(ctx context.Context, virtualStorage, relativePath, storage string) error
// DeleteRepository deletes the database records associated with the repository. It returns the replica path and the storages
- // which are known to have a replica at the time of deletion. commonerr.RepositoryNotFoundError is returned when
+ // which are known to have a replica at the time of deletion. storage.RepositoryNotFoundError is returned when
// the repository is not tracked by the Praefect datastore.
DeleteRepository(ctx context.Context, virtualStorage, relativePath string) (string, []string, error)
// DeleteAllRepositories deletes the database records associated with
@@ -282,7 +282,7 @@ SELECT
}
if !repositoryExists {
- return commonerr.ErrRepositoryNotFound
+ return storage.ErrRepositoryNotFound
}
if !repositoryUpdated {
@@ -326,7 +326,7 @@ ON CONFLICT (repository_id, storage) DO UPDATE SET
}
// SetAuthoritativeReplica sets the given replica of a repsitory as the authoritative one by setting its generation as the latest one.
-func (rs *PostgresRepositoryStore) SetAuthoritativeReplica(ctx context.Context, virtualStorage, relativePath, storage string) error {
+func (rs *PostgresRepositoryStore) SetAuthoritativeReplica(ctx context.Context, virtualStorage, relativePath, storageName string) error {
result, err := rs.db.ExecContext(ctx, `
WITH updated_repository AS (
UPDATE repositories
@@ -342,7 +342,7 @@ FROM updated_repository
ON CONFLICT (virtual_storage, relative_path, storage) DO UPDATE
SET repository_id = EXCLUDED.repository_id,
generation = EXCLUDED.generation
- `, virtualStorage, relativePath, storage)
+ `, virtualStorage, relativePath, storageName)
if err != nil {
return fmt.Errorf("exec: %w", err)
}
@@ -350,7 +350,7 @@ ON CONFLICT (virtual_storage, relative_path, storage) DO UPDATE
if rowsAffected, err := result.RowsAffected(); err != nil {
return fmt.Errorf("rows affected: %w", err)
} else if rowsAffected == 0 {
- return commonerr.NewRepositoryNotFoundError(virtualStorage, relativePath)
+ return storage.NewRepositoryNotFoundError(virtualStorage, relativePath)
}
return nil
@@ -513,7 +513,7 @@ GROUP BY replica_path
`, virtualStorage, relativePath,
).Scan(&replicaPath, &storages); err != nil {
if errors.Is(err, sql.ErrNoRows) {
- return "", nil, commonerr.NewRepositoryNotFoundError(virtualStorage, relativePath)
+ return "", nil, storage.NewRepositoryNotFoundError(virtualStorage, relativePath)
}
return "", nil, fmt.Errorf("scan: %w", err)
@@ -590,7 +590,7 @@ WHERE repository_id = (SELECT repository_id FROM repository)
`, virtualStorage, relativePath, newRelativePath)
if err != nil {
if glsql.IsUniqueViolation(err, "repository_lookup_index") {
- return commonerr.ErrRepositoryAlreadyExists
+ return storage.ErrRepositoryAlreadyExists
}
return fmt.Errorf("query: %w", err)
@@ -599,7 +599,7 @@ WHERE repository_id = (SELECT repository_id FROM repository)
if rowsAffected, err := result.RowsAffected(); err != nil {
return fmt.Errorf("rows affected: %w", err)
} else if rowsAffected == 0 {
- return commonerr.ErrRepositoryNotFound
+ return storage.ErrRepositoryNotFound
}
return nil
@@ -662,8 +662,8 @@ WHERE repositories.virtual_storage = $1
AND repositories.relative_path = $2
GROUP BY replica_path
`, virtualStorage, relativePath)
- if errors.Is(err, commonerr.ErrRepositoryNotFound) {
- return "", nil, commonerr.NewRepositoryNotFoundError(virtualStorage, relativePath)
+ if errors.Is(err, storage.ErrRepositoryNotFound) {
+ return "", nil, storage.NewRepositoryNotFoundError(virtualStorage, relativePath)
}
return replicaPath, storages, err
@@ -676,7 +676,7 @@ func (rs *PostgresRepositoryStore) getConsistentStorages(ctx context.Context, qu
if err := rs.db.QueryRowContext(ctx, query, params...).Scan(&replicaPath, &storages); err != nil {
if errors.Is(err, sql.ErrNoRows) {
- return "", nil, commonerr.ErrRepositoryNotFound
+ return "", nil, storage.ErrRepositoryNotFound
}
return "", nil, fmt.Errorf("query: %w", err)
@@ -787,7 +787,7 @@ func (rs *PostgresRepositoryStore) GetRepositoryMetadata(ctx context.Context, re
}
if len(metadata) == 0 {
- return RepositoryMetadata{}, commonerr.ErrRepositoryNotFound
+ return RepositoryMetadata{}, storage.ErrRepositoryNotFound
}
return metadata[0], nil
@@ -808,7 +808,7 @@ func (rs *PostgresRepositoryStore) GetRepositoryMetadataByPath(ctx context.Conte
}
if len(metadata) == 0 {
- return RepositoryMetadata{}, commonerr.ErrRepositoryNotFound
+ return RepositoryMetadata{}, storage.ErrRepositoryNotFound
}
return metadata[0], nil
@@ -990,7 +990,7 @@ WHERE NOT EXISTS (
)
`, virtualStorage, relativePath).Scan(&id); err != nil {
if errors.Is(err, sql.ErrNoRows) {
- return 0, commonerr.ErrRepositoryAlreadyExists
+ return 0, storage.ErrRepositoryAlreadyExists
}
return 0, fmt.Errorf("scan: %w", err)
@@ -1010,7 +1010,7 @@ WHERE virtual_storage = $1
AND relative_path = $2
`, virtualStorage, relativePath).Scan(&id); err != nil {
if errors.Is(err, sql.ErrNoRows) {
- return 0, commonerr.NewRepositoryNotFoundError(virtualStorage, relativePath)
+ return 0, storage.NewRepositoryNotFoundError(virtualStorage, relativePath)
}
return 0, fmt.Errorf("scan: %w", err)
@@ -1019,7 +1019,7 @@ AND relative_path = $2
return id, nil
}
-// GetReplicaPath gets the replica path of a repository. Returns a commonerr.ErrRepositoryNotFound if a record
+// GetReplicaPath gets the replica path of a repository. Returns a storage.ErrRepositoryNotFound if a record
// for the repository ID is not found.
func (rs *PostgresRepositoryStore) GetReplicaPath(ctx context.Context, repositoryID int64) (string, error) {
var replicaPath string
@@ -1027,7 +1027,7 @@ func (rs *PostgresRepositoryStore) GetReplicaPath(ctx context.Context, repositor
ctx, "SELECT replica_path FROM repositories WHERE repository_id = $1", repositoryID,
).Scan(&replicaPath); err != nil {
if errors.Is(err, sql.ErrNoRows) {
- return "", commonerr.ErrRepositoryNotFound
+ return "", storage.ErrRepositoryNotFound
}
return "", fmt.Errorf("scan: %w", err)
diff --git a/internal/praefect/datastore/repository_store_test.go b/internal/praefect/datastore/repository_store_test.go
index c1a59cb98..5ca18d27b 100644
--- a/internal/praefect/datastore/repository_store_test.go
+++ b/internal/praefect/datastore/repository_store_test.go
@@ -8,7 +8,7 @@ import (
"time"
"github.com/stretchr/testify/require"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore/glsql"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testdb"
@@ -133,7 +133,7 @@ func TestRepositoryStore_Postgres(t *testing.T) {
require.Equal(t,
rs.IncrementGeneration(ctx, 1, "primary", []string{"secondary-1"}),
- commonerr.ErrRepositoryNotFound,
+ storage.ErrRepositoryNotFound,
)
requireState(t, ctx, db, virtualStorageState{}, storageState{})
})
@@ -358,7 +358,7 @@ func TestRepositoryStore_Postgres(t *testing.T) {
rs := newRepositoryStore(t, nil)
require.Equal(t,
- commonerr.NewRepositoryNotFoundError(vs, repo),
+ storage.NewRepositoryNotFoundError(vs, repo),
rs.SetAuthoritativeReplica(ctx, vs, repo, stor),
)
})
@@ -752,7 +752,7 @@ func TestRepositoryStore_Postgres(t *testing.T) {
rs := newRepositoryStore(t, nil)
replicaPath, storages, err := rs.DeleteRepository(ctx, vs, repo)
- require.Equal(t, commonerr.NewRepositoryNotFoundError(vs, repo), err)
+ require.Equal(t, storage.NewRepositoryNotFoundError(vs, repo), err)
require.Empty(t, replicaPath)
require.Empty(t, storages)
})
@@ -898,7 +898,7 @@ func TestRepositoryStore_Postgres(t *testing.T) {
rs := newRepositoryStore(t, nil)
require.Equal(t,
- commonerr.ErrRepositoryNotFound,
+ storage.ErrRepositoryNotFound,
rs.RenameRepositoryInPlace(ctx, vs, repo, "new-relative-path"),
)
})
@@ -910,7 +910,7 @@ func TestRepositoryStore_Postgres(t *testing.T) {
require.NoError(t, rs.CreateRepository(ctx, 2, vs, "relative-path-2", "replica-path-2", "primary", nil, nil, true, false))
require.Equal(t,
- commonerr.ErrRepositoryAlreadyExists,
+ storage.ErrRepositoryAlreadyExists,
rs.RenameRepositoryInPlace(ctx, vs, "relative-path-1", "relative-path-2"),
)
})
@@ -1007,12 +1007,12 @@ func TestRepositoryStore_Postgres(t *testing.T) {
t.Run("no records", func(t *testing.T) {
replicaPath, secondaries, err := rs.GetConsistentStorages(ctx, vs, repo)
- require.Equal(t, commonerr.NewRepositoryNotFoundError(vs, repo), err)
+ require.Equal(t, storage.NewRepositoryNotFoundError(vs, repo), err)
require.Empty(t, replicaPath)
require.Empty(t, secondaries)
replicaPath, secondaries, err = rs.GetConsistentStoragesByRepositoryID(ctx, 1)
- require.Equal(t, commonerr.ErrRepositoryNotFound, err)
+ require.Equal(t, storage.ErrRepositoryNotFound, err)
require.Empty(t, replicaPath)
require.Empty(t, secondaries)
})
@@ -1101,12 +1101,12 @@ func TestRepositoryStore_Postgres(t *testing.T) {
requireState(t, ctx, db, virtualStorageState{}, storageState{})
replicaPath, secondaries, err := rs.GetConsistentStorages(ctx, vs, repo)
- require.Equal(t, commonerr.NewRepositoryNotFoundError(vs, repo), err)
+ require.Equal(t, storage.NewRepositoryNotFoundError(vs, repo), err)
require.Empty(t, secondaries)
require.Empty(t, replicaPath)
replicaPath, secondaries, err = rs.GetConsistentStoragesByRepositoryID(ctx, 1)
- require.Equal(t, commonerr.ErrRepositoryNotFound, err)
+ require.Equal(t, storage.ErrRepositoryNotFound, err)
require.Empty(t, secondaries)
require.Empty(t, replicaPath)
})
@@ -1208,7 +1208,7 @@ func TestRepositoryStore_Postgres(t *testing.T) {
require.NoError(t, rs.CreateRepository(ctx, id, vs, repo, "replica-path", stor, nil, nil, false, false))
id, err = rs.ReserveRepositoryID(ctx, vs, repo)
- require.Equal(t, commonerr.ErrRepositoryAlreadyExists, err)
+ require.Equal(t, storage.ErrRepositoryAlreadyExists, err)
require.Equal(t, int64(0), id)
id, err = rs.ReserveRepositoryID(ctx, vs, repo+"-2")
@@ -1220,7 +1220,7 @@ func TestRepositoryStore_Postgres(t *testing.T) {
rs := newRepositoryStore(t, nil)
id, err := rs.GetRepositoryID(ctx, vs, repo)
- require.Equal(t, commonerr.NewRepositoryNotFoundError(vs, repo), err)
+ require.Equal(t, storage.NewRepositoryNotFoundError(vs, repo), err)
require.Equal(t, int64(0), id)
require.NoError(t, rs.CreateRepository(ctx, 1, vs, repo, "replica-path", stor, nil, nil, false, false))
@@ -1234,7 +1234,7 @@ func TestRepositoryStore_Postgres(t *testing.T) {
rs := newRepositoryStore(t, nil)
replicaPath, err := rs.GetReplicaPath(ctx, 1)
- require.Equal(t, err, commonerr.ErrRepositoryNotFound)
+ require.Equal(t, err, storage.ErrRepositoryNotFound)
require.Empty(t, replicaPath)
require.NoError(t, rs.CreateRepository(ctx, 1, vs, repo, "replica-path", stor, nil, nil, false, false))
@@ -1669,7 +1669,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) {
var expectedErr error
if tc.nonExistentRepository {
- expectedErr = commonerr.ErrRepositoryNotFound
+ expectedErr = storage.ErrRepositoryNotFound
expectedMetadata = RepositoryMetadata{}
}
diff --git a/internal/praefect/datastore/storage_provider_test.go b/internal/praefect/datastore/storage_provider_test.go
index 410195c8a..abe683fbe 100644
--- a/internal/praefect/datastore/storage_provider_test.go
+++ b/internal/praefect/datastore/storage_provider_test.go
@@ -16,7 +16,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v16/internal/datastructure"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore/glsql"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testdb"
@@ -101,7 +101,7 @@ func TestCachingStorageProvider_GetSyncedNodes(t *testing.T) {
cache.Connected()
_, _, err = cache.GetConsistentStorages(ctx, "vs", "/repo/path")
- require.Equal(t, commonerr.NewRepositoryNotFoundError("vs", "/repo/path"), err)
+ require.Equal(t, storage.NewRepositoryNotFoundError("vs", "/repo/path"), err)
// "populate" metric is not set as there was an error and we don't want this result to be cached
err = testutil.CollectAndCompare(cache, strings.NewReader(`
diff --git a/internal/praefect/nodes/manager.go b/internal/praefect/nodes/manager.go
index e6260f7e1..6894d61ee 100644
--- a/internal/praefect/nodes/manager.go
+++ b/internal/praefect/nodes/manager.go
@@ -13,10 +13,10 @@ import (
"github.com/sirupsen/logrus"
gitalyauth "gitlab.com/gitlab-org/gitaly/v16/auth"
"gitlab.com/gitlab-org/gitaly/v16/internal/datastructure"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/client"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/proxy"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/sidechannel"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/config"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/metrics"
@@ -274,7 +274,7 @@ func (n *Mgr) GetPrimary(ctx context.Context, virtualStorage string, _ int64) (s
//nolint:revive // This is unintentionally missing documentation.
func (n *Mgr) GetSyncedNode(ctx context.Context, virtualStorageName, repoPath string) (Node, error) {
_, upToDateStorages, err := n.csg.GetConsistentStorages(ctx, virtualStorageName, repoPath)
- if err != nil && !errors.As(err, new(commonerr.RepositoryNotFoundError)) {
+ if err != nil && !errors.As(err, new(storage.RepositoryNotFoundError)) {
return nil, err
}
diff --git a/internal/praefect/nodes/per_repository.go b/internal/praefect/nodes/per_repository.go
index 254724198..a7e2b97d3 100644
--- a/internal/praefect/nodes/per_repository.go
+++ b/internal/praefect/nodes/per_repository.go
@@ -8,7 +8,7 @@ import (
"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
"github.com/sirupsen/logrus"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore/glsql"
)
@@ -103,7 +103,7 @@ WHERE snapshot.repository_id = $1
repositoryID,
).Scan(&current, &previous); err != nil {
if errors.Is(err, sql.ErrNoRows) {
- return "", commonerr.ErrRepositoryNotFound
+ return "", storage.ErrRepositoryNotFound
}
return "", fmt.Errorf("scan: %w", err)
diff --git a/internal/praefect/nodes/per_repository_test.go b/internal/praefect/nodes/per_repository_test.go
index 93d5ef806..1e96737b3 100644
--- a/internal/praefect/nodes/per_repository_test.go
+++ b/internal/praefect/nodes/per_repository_test.go
@@ -8,7 +8,7 @@ import (
"github.com/sirupsen/logrus/hooks/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testdb"
@@ -476,7 +476,7 @@ func TestPerRepositoryElector(t *testing.T) {
desc: "repository does not exist",
steps: steps{
{
- error: commonerr.ErrRepositoryNotFound,
+ error: storage.ErrRepositoryNotFound,
primary: noPrimary(),
noBlockedQuery: true,
},
@@ -514,7 +514,7 @@ func TestPerRepositoryElector(t *testing.T) {
for _, event := range tc.existingJobs {
repositoryID, err := rs.GetRepositoryID(ctx, event.Job.VirtualStorage, event.Job.RelativePath)
if err != nil {
- require.Equal(t, commonerr.NewRepositoryNotFoundError(event.Job.VirtualStorage, event.Job.RelativePath), err)
+ require.Equal(t, storage.NewRepositoryNotFoundError(event.Job.VirtualStorage, event.Job.RelativePath), err)
}
event.Job.RepositoryID = repositoryID
diff --git a/internal/praefect/reconciler/reconciler_test.go b/internal/praefect/reconciler/reconciler_test.go
index bf68e4898..f421df15e 100644
--- a/internal/praefect/reconciler/reconciler_test.go
+++ b/internal/praefect/reconciler/reconciler_test.go
@@ -9,10 +9,10 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/grpc/middleware/metadatahandler"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testdb"
@@ -1041,7 +1041,7 @@ func TestReconciler(t *testing.T) {
var err error
existing.Job.RepositoryID, err = rs.GetRepositoryID(ctx, existing.Job.VirtualStorage, existing.Job.RelativePath)
if err != nil {
- require.Equal(t, commonerr.NewRepositoryNotFoundError(existing.Job.VirtualStorage, existing.Job.RelativePath), err)
+ require.Equal(t, storage.NewRepositoryNotFoundError(existing.Job.VirtualStorage, existing.Job.RelativePath), err)
}
var id int64
@@ -1099,7 +1099,7 @@ func TestReconciler(t *testing.T) {
for i, job := range jobs {
id, err := rs.GetRepositoryID(ctx, job.VirtualStorage, job.RelativePath)
if err != nil {
- require.Equal(t, commonerr.NewRepositoryNotFoundError(job.VirtualStorage, job.RelativePath), err)
+ require.Equal(t, storage.NewRepositoryNotFoundError(job.VirtualStorage, job.RelativePath), err)
}
jobs[i].RepositoryID = id
diff --git a/internal/praefect/remove_repository.go b/internal/praefect/remove_repository.go
index 2d8c9a17c..12c1805bd 100644
--- a/internal/praefect/remove_repository.go
+++ b/internal/praefect/remove_repository.go
@@ -9,7 +9,7 @@ import (
"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
"github.com/sirupsen/logrus"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
@@ -63,9 +63,9 @@ func removeRepositoryHandler(rs datastore.RepositoryStore, conns Connections, pa
virtualStorage := repo.StorageName
replicaPath, storages, err := rs.DeleteRepository(ctx, virtualStorage, repo.RelativePath)
if err != nil {
- if errors.As(err, new(commonerr.RepositoryNotFoundError)) {
+ if errors.As(err, new(storage.RepositoryNotFoundError)) {
if errorOnNotFound {
- if errors.As(err, new(commonerr.RepositoryNotFoundError)) {
+ if errors.As(err, new(storage.RepositoryNotFoundError)) {
return structerr.NewNotFound("repository does not exist")
}
}
diff --git a/internal/praefect/rename_repository.go b/internal/praefect/rename_repository.go
index b7c849460..2c2adc5b7 100644
--- a/internal/praefect/rename_repository.go
+++ b/internal/praefect/rename_repository.go
@@ -6,7 +6,6 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
@@ -59,13 +58,13 @@ func RenameRepositoryHandler(virtualStoragesNames []string, rs datastore.Reposit
req.GetRepository().GetRelativePath(),
req.GetRelativePath(),
); err != nil {
- if errors.Is(err, commonerr.ErrRepositoryNotFound) {
+ if errors.Is(err, storage.ErrRepositoryNotFound) {
return structerr.NewNotFound(
`GetRepoPath: not a git repository: "%s/%s"`,
req.GetRepository().GetStorageName(),
req.GetRepository().GetRelativePath(),
)
- } else if errors.Is(err, commonerr.ErrRepositoryAlreadyExists) {
+ } else if errors.Is(err, storage.ErrRepositoryAlreadyExists) {
return structerr.NewAlreadyExists("target repo exists already")
}
diff --git a/internal/praefect/replicator_test.go b/internal/praefect/replicator_test.go
index b78fca253..d983c1f41 100644
--- a/internal/praefect/replicator_test.go
+++ b/internal/praefect/replicator_test.go
@@ -572,7 +572,7 @@ func TestProcessBacklog_Success(t *testing.T) {
<-replMgrDone
require.NoDirExists(t, fullNewPath1, "repository must be moved from %q to the new location", fullNewPath1)
- require.True(t, storage.IsGitDirectory(fullNewPath2), "repository must exist at new last RenameRepository location")
+ require.NoError(t, storage.ValidateRepository(fullNewPath2), "repository must exist at new last RenameRepository location")
}
func TestReplMgrProcessBacklog_OnlyHealthyNodes(t *testing.T) {
diff --git a/internal/praefect/router_node_manager.go b/internal/praefect/router_node_manager.go
index 0159a9cd1..2fc2bae61 100644
--- a/internal/praefect/router_node_manager.go
+++ b/internal/praefect/router_node_manager.go
@@ -6,7 +6,7 @@ import (
"fmt"
"gitlab.com/gitlab-org/gitaly/v16/internal/datastructure"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/nodes"
)
@@ -86,7 +86,7 @@ func (r *nodeManagerRouter) RouteRepositoryMutator(ctx context.Context, virtualS
// paths of repositories and thus returns an empty string. This breaks the tests. Instead, we'll just keep
// using the relative path in NodeManagerRouter.
_, consistentStorages, err := r.rs.GetConsistentStorages(ctx, virtualStorage, relativePath)
- if err != nil && !errors.As(err, new(commonerr.RepositoryNotFoundError)) {
+ if err != nil && !errors.As(err, new(storage.RepositoryNotFoundError)) {
return RepositoryMutatorRoute{}, fmt.Errorf("consistent storages: %w", err)
}
diff --git a/internal/praefect/router_per_repository_test.go b/internal/praefect/router_per_repository_test.go
index 75c67a941..dc68d0dfe 100644
--- a/internal/praefect/router_per_repository_test.go
+++ b/internal/praefect/router_per_repository_test.go
@@ -9,7 +9,6 @@ import (
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/nodes"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
@@ -841,7 +840,7 @@ func TestPerRepositoryRouterRouteRepositoryCreation(t *testing.T) {
primaryPick: 0,
repositoryExists: true,
expectedPrimaryCandidates: []int{3},
- expectedErr: fmt.Errorf("reserve repository id: %w", commonerr.ErrRepositoryAlreadyExists),
+ expectedErr: fmt.Errorf("reserve repository id: %w", storage.ErrRepositoryAlreadyExists),
},
{
desc: "additional repository doesn't exist",
diff --git a/internal/praefect/service/info/metadata.go b/internal/praefect/service/info/metadata.go
index b3820f67d..2e204512a 100644
--- a/internal/praefect/service/info/metadata.go
+++ b/internal/praefect/service/info/metadata.go
@@ -4,7 +4,7 @@ import (
"context"
"errors"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
@@ -29,7 +29,7 @@ func (s *Server) GetRepositoryMetadata(ctx context.Context, req *gitalypb.GetRep
metadata, err := getMetadata()
if err != nil {
- if errors.Is(err, commonerr.ErrRepositoryNotFound) {
+ if errors.Is(err, storage.ErrRepositoryNotFound) {
return nil, structerr.NewNotFound("%w", err)
}
diff --git a/internal/praefect/service/info/server.go b/internal/praefect/service/info/server.go
index e7e76915e..c099d2528 100644
--- a/internal/praefect/service/info/server.go
+++ b/internal/praefect/service/info/server.go
@@ -4,7 +4,7 @@ import (
"context"
"errors"
- "gitlab.com/gitlab-org/gitaly/v16/internal/praefect/commonerr"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/config"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/datastore"
"gitlab.com/gitlab-org/gitaly/v16/internal/praefect/service"
@@ -80,7 +80,7 @@ func (s *Server) SetAuthoritativeStorage(ctx context.Context, req *gitalypb.SetA
}
if err := s.rs.SetAuthoritativeReplica(ctx, req.VirtualStorage, req.RelativePath, req.AuthoritativeStorage); err != nil {
- if errors.As(err, &commonerr.RepositoryNotFoundError{}) {
+ if errors.As(err, &storage.RepositoryNotFoundError{}) {
return nil, structerr.NewInvalidArgument("repository %q does not exist on virtual storage %q", req.RelativePath, req.VirtualStorage)
}
diff --git a/internal/tempdir/tempdir_test.go b/internal/tempdir/tempdir_test.go
index 6d89ad083..61aaba1eb 100644
--- a/internal/tempdir/tempdir_test.go
+++ b/internal/tempdir/tempdir_test.go
@@ -8,6 +8,7 @@ import (
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/config"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/helper/perm"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testcfg"
@@ -24,7 +25,7 @@ func TestNewRepositorySuccess(t *testing.T) {
require.Equal(t, cfg.Storages[0].Name, repo.StorageName)
require.Contains(t, repo.RelativePath, tmpRootPrefix)
- calculatedPath, err := locator.GetPath(repo)
+ calculatedPath, err := locator.GetRepoPath(repo, storage.WithRepositoryVerificationSkipped())
require.NoError(t, err)
require.Equal(t, tempDir.Path(), calculatedPath)