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-05-02 08:33:30 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2023-05-02 09:11:12 +0300
commit7c8bd8efa52b22ed411db0542f239dedcda7bf6d (patch)
treecbe6cabbf7e5479b52b900a2e2dab04145dd694d
parentaa2e0e902dcbb4c083d11ed3777dd46ec7ea4ace (diff)
coordinator: Reject routing mutators with different repo storages
As with the preceding commit, we have the same issue when routing mutators where the first message contains two repositories with different storages. The result is that we may end up rewriting the repositories to a repository on the wrong storage. As routing mutators also uses `rewrittenRepositoryMessage()` the bug should already be fixed by the preceding commit. But we'd still try to connect to the wrong storage node first and will then try to resolve the additional repository, which is likely to fail. The result would be a confusing error message that the repository wasn't found, where the real issue is that we got a request with differing repository storages. Add an explicit check to catch this error condition so that we can return a proper error message to the client. Changelog: fixed
-rw-r--r--internal/praefect/coordinator.go15
-rw-r--r--internal/praefect/coordinator_test.go18
2 files changed, 16 insertions, 17 deletions
diff --git a/internal/praefect/coordinator.go b/internal/praefect/coordinator.go
index fb2c65eee..7214718ed 100644
--- a/internal/praefect/coordinator.go
+++ b/internal/praefect/coordinator.go
@@ -382,6 +382,21 @@ func (c *Coordinator) mutatorStreamParameters(ctx context.Context, call grpcCall
} else if err != nil {
return nil, structerr.NewInvalidArgument("%w", err)
} else {
+ // We do not support resolving multiple different repositories that reside on
+ // different virtual storages. This kind of makes sense from a technical point of
+ // view as Praefect cannot guarantee to resolve both virtual storages. So for the
+ // time being we accept this restriction and handle it explicitly.
+ //
+ // Note that this is the same condition as in `rewrittenRepositoryMessage()`. This
+ // is done so that we detect such erroneous requests before we try to connect to the
+ // target node, which allows us to return a proper error to the user that indicates
+ // the underlying issue instead of an unrelated symptom.
+ //
+ // This limitation may be lifted in the future.
+ if virtualStorage != additionalRepo.GetStorageName() {
+ return nil, structerr.NewInvalidArgument("resolving additional repository on different storage than target repository is not supported")
+ }
+
additionalRepoRelativePath = additionalRepo.GetRelativePath()
}
diff --git a/internal/praefect/coordinator_test.go b/internal/praefect/coordinator_test.go
index e2f1caf98..71a96ba53 100644
--- a/internal/praefect/coordinator_test.go
+++ b/internal/praefect/coordinator_test.go
@@ -365,23 +365,7 @@ func TestStreamDirectorMutator(t *testing.T) {
Repository: targetRepo,
},
},
- // This is a bug: we try to resolve the additional
- // repository as a member of the target repository's
- // storage. In the best case this fails, which is a
- // reasonable outcome. But in the worst case, if the
- // additional repository's path exists on the target
- // repository's storage, we could forward the request to the
- // wrong node.
- 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",
- // Note how the error message uses
- // the target repo's storage name,
- // but the additional repo's path.
- commonerr.NewRepositoryNotFoundError(targetRepo.StorageName, additionalRepo.RelativePath),
- ),
- ),
- )),
+ expectedErr: structerr.NewInvalidArgument("resolving additional repository on different storage than target repository is not supported"),
}
},
},