diff options
author | Patrick Steinhardt <psteinhardt@gitlab.com> | 2021-06-14 12:17:52 +0300 |
---|---|---|
committer | Patrick Steinhardt <psteinhardt@gitlab.com> | 2021-07-02 14:12:08 +0300 |
commit | 050e1a0307e5727e52e864cb21bccc0744114f9e (patch) | |
tree | baf2a3be32b039b4795193149cb248de64a556ba | |
parent | 89eaf21110548b7f5809cad7752e877e2e9b3d08 (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.go | 19 |
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 { |