diff options
Diffstat (limited to 'internal/gitaly/service/remote/remotes.go')
-rw-r--r-- | internal/gitaly/service/remote/remotes.go | 66 |
1 files changed, 63 insertions, 3 deletions
diff --git a/internal/gitaly/service/remote/remotes.go b/internal/gitaly/service/remote/remotes.go index d020112a8..95f078e6e 100644 --- a/internal/gitaly/service/remote/remotes.go +++ b/internal/gitaly/service/remote/remotes.go @@ -4,12 +4,17 @@ import ( "bytes" "context" "fmt" + "io" "io/ioutil" "strings" "gitlab.com/gitlab-org/gitaly/internal/git" - "gitlab.com/gitlab-org/gitaly/internal/git/localrepo" "gitlab.com/gitlab-org/gitaly/internal/gitaly/rubyserver" + "gitlab.com/gitlab-org/gitaly/internal/gitaly/transaction" + "gitlab.com/gitlab-org/gitaly/internal/helper" + "gitlab.com/gitlab-org/gitaly/internal/metadata/featureflag" + "gitlab.com/gitlab-org/gitaly/internal/transaction/txinfo" + "gitlab.com/gitlab-org/gitaly/internal/transaction/voting" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -31,7 +36,20 @@ func (s *server) AddRemote(ctx context.Context, req *gitalypb.AddRemoteRequest) return nil, err } - return client.AddRemote(clientCtx, req) + if err := s.voteOnRemote(ctx, req.GetRepository(), req.GetName()); err != nil { + return nil, helper.ErrInternalf("preimage vote on remote: %v", err) + } + + response, err := client.AddRemote(clientCtx, req) + if err != nil { + return nil, err + } + + if err := s.voteOnRemote(ctx, req.GetRepository(), req.GetName()); err != nil { + return nil, helper.ErrInternalf("postimage vote on remote: %v", err) + } + + return response, nil } func validateAddRemoteRequest(req *gitalypb.AddRemoteRequest) error { @@ -51,7 +69,7 @@ func (s *server) RemoveRemote(ctx context.Context, req *gitalypb.RemoveRemoteReq return nil, status.Errorf(codes.InvalidArgument, "RemoveRemote: %v", err) } - remote := localrepo.New(s.gitCmdFactory, req.GetRepository(), s.cfg).Remote() + remote := s.localrepo(req.GetRepository()).Remote() hasRemote, err := remote.Exists(ctx, req.Name) if err != nil { @@ -61,10 +79,18 @@ func (s *server) RemoveRemote(ctx context.Context, req *gitalypb.RemoveRemoteReq return &gitalypb.RemoveRemoteResponse{Result: false}, nil } + if err := s.voteOnRemote(ctx, req.GetRepository(), req.GetName()); err != nil { + return nil, helper.ErrInternalf("preimage vote on remote: %v", err) + } + if err := remote.Remove(ctx, req.Name); err != nil { return nil, err } + if err := s.voteOnRemote(ctx, req.GetRepository(), req.GetName()); err != nil { + return nil, helper.ErrInternalf("postimage vote on remote: %v", err) + } + return &gitalypb.RemoveRemoteResponse{Result: true}, nil } @@ -111,3 +137,37 @@ func validateRemoveRemoteRequest(req *gitalypb.RemoveRemoteRequest) error { return nil } + +func (s *server) voteOnRemote(ctx context.Context, repo *gitalypb.Repository, remoteName string) error { + if featureflag.IsDisabled(ctx, featureflag.TxRemote) { + return nil + } + + return transaction.RunOnContext(ctx, func(tx txinfo.Transaction, server txinfo.PraefectServer) error { + localrepo := s.localrepo(repo) + + configEntries, err := localrepo.Config().GetRegexp(ctx, "remote\\."+remoteName+"\\.", git.ConfigGetRegexpOpts{}) + if err != nil { + return fmt.Errorf("get remote configuration: %w", err) + } + + hash := voting.NewVoteHash() + for _, configEntry := range configEntries { + config := fmt.Sprintf("%s\t%s\n", configEntry.Key, configEntry.Value) + if _, err := io.WriteString(hash, config); err != nil { + return fmt.Errorf("hash remote config entry: %w", err) + } + } + + vote, err := hash.Vote() + if err != nil { + return fmt.Errorf("compute remote config vote: %w", err) + } + + if err := s.txManager.Vote(ctx, tx, server, vote); err != nil { + return fmt.Errorf("vote: %w", err) + } + + return nil + }) +} |