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>2021-06-14 12:17:52 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2021-07-02 14:12:08 +0300
commit050e1a0307e5727e52e864cb21bccc0744114f9e (patch)
treebaf2a3be32b039b4795193149cb248de64a556ba
parent89eaf21110548b7f5809cad7752e877e2e9b3d08 (diff)
repository: Fix voting when cloning from internal pools
The `CloneFromPoolInternal()` RPC is responsible for first creating the desired target repo by closing from a pool repository and then updating the pool via a fetch from the source repo. While the former step happens via a direct call to git-clone(1), we connect to the remote service's `FetchInternalRemote()` RPC for the latter. This second step is problematic in the context of transactions though: we call `FetchInternalRemote()` with the incoming context having been converted to an outgoing context. The outgoing context thus retains information about any ongoing transactions and also about the backchannel ID. Given that this is a mutating RPC, the remote side will now try vote on the transaction and dial back via the backchannel, but given that the backchannel ID referred to the original Praefect node and not to the now-intermediate Gitaly node, this cannot work and will thus fail. Now that we have `FetchInternalRemote()` exposed directly without having to connect to the remote service, we can now easily fix the issue by just calling this function directly. No new tests are added because this failure will be exposed by subsequent commits which remove the `PraefetcServer` structure.
-rw-r--r--internal/gitaly/service/repository/clone_from_pool_internal.go19
1 files changed, 3 insertions, 16 deletions
diff --git a/internal/gitaly/service/repository/clone_from_pool_internal.go b/internal/gitaly/service/repository/clone_from_pool_internal.go
index ccacc52e8..540eb8b73 100644
--- a/internal/gitaly/service/repository/clone_from_pool_internal.go
+++ b/internal/gitaly/service/repository/clone_from_pool_internal.go
@@ -9,6 +9,7 @@ import (
"gitlab.com/gitlab-org/gitaly/internal/git"
"gitlab.com/gitlab-org/gitaly/internal/git/objectpool"
"gitlab.com/gitlab-org/gitaly/internal/git/repository"
+ "gitlab.com/gitlab-org/gitaly/internal/gitaly/service/remote"
"gitlab.com/gitlab-org/gitaly/internal/helper"
"gitlab.com/gitlab-org/gitaly/proto/go/gitalypb"
)
@@ -26,25 +27,11 @@ func (s *server) CloneFromPoolInternal(ctx context.Context, req *gitalypb.CloneF
return nil, helper.ErrInternal(err)
}
- client, err := s.newRemoteClient(ctx)
- if err != nil {
- return nil, helper.ErrInternalf("getting remote service client: %v", err)
- }
-
- fetchInternalReq := &gitalypb.FetchInternalRemoteRequest{
- Repository: req.GetRepository(),
- RemoteRepository: req.GetSourceRepository(),
- }
+ repo := s.localrepo(req.GetRepository())
- outgoingCtx := helper.IncomingToOutgoing(ctx)
-
- resp, err := client.FetchInternalRemote(outgoingCtx, fetchInternalReq)
- if err != nil {
+ if err := remote.FetchInternalRemote(ctx, s.cfg, s.conns, repo, req.GetSourceRepository()); err != nil {
return nil, helper.ErrInternalf("fetch internal remote: %v", err)
}
- if !resp.Result {
- return nil, helper.ErrInternalf("fetch internal remote failed")
- }
objectPool, err := objectpool.FromProto(s.cfg, s.locator, s.gitCmdFactory, s.catfileCache, req.GetPool())
if err != nil {