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-05-19 11:46:08 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2021-05-19 19:44:10 +0300
commitc28412f83bfb074908189c8bd42e3ea632a06efb (patch)
treea0d095035d5a4df2408758de3ef040b19424cdeb
parentf18374c18d47f322f5a540fa4dddec7696f4f4d3 (diff)
repository: Replicate gitconfig
When replicating repositories, we do not currently replicate the gitconfig. This is quite important to do though given that the gitconfig may influence various different aspects of Git and may thus cause mismatching results if it is different across replicas. Even if we eventually remove the `AddConfig()` and `DeleteConfig()` RPCs, we'd still want to replicate it given that different Git versions may end up with different defaults and thus with different gitconfig files. Implement replication of gitconfig files. As the `GetConfig()` RPC which we require for this has only been introduced in this same commit series, we need to play it safe and for now ignore all errors returned by it to guard against the case where the remote Gitaly instance doesn't yet support it. This workaround can be dropped in the next release cycle. Changelog: added
-rw-r--r--internal/gitaly/service/repository/replicate.go42
-rw-r--r--internal/gitaly/service/repository/replicate_test.go9
2 files changed, 51 insertions, 0 deletions
diff --git a/internal/gitaly/service/repository/replicate.go b/internal/gitaly/service/repository/replicate.go
index e1daa27d5..6d7354c5a 100644
--- a/internal/gitaly/service/repository/replicate.go
+++ b/internal/gitaly/service/repository/replicate.go
@@ -57,6 +57,7 @@ func (s *server) ReplicateRepository(ctx context.Context, in *gitalypb.Replicate
outgoingCtx := helper.IncomingToOutgoing(ctx)
syncFuncs := []func(context.Context, *gitalypb.ReplicateRepositoryRequest) error{
+ s.syncGitconfig,
s.syncInfoAttributes,
s.syncRepository,
}
@@ -209,6 +210,47 @@ func (s *server) syncRepository(ctx context.Context, in *gitalypb.ReplicateRepos
return nil
}
+func (s *server) syncGitconfig(ctx context.Context, in *gitalypb.ReplicateRepositoryRequest) error {
+ repoClient, err := s.newRepoClient(ctx, in.GetSource().GetStorageName())
+ if err != nil {
+ return err
+ }
+
+ repoPath, err := s.locator.GetRepoPath(in.GetRepository())
+ if err != nil {
+ return err
+ }
+
+ // At the point of implementing this, the `GetConfig` RPC hasn't been deployed yet and is
+ // thus not available for general use. In theory, we'd have to wait for this release cycle
+ // to finish, and only afterwards would we be able to implement replication of the
+ // gitconfig. In order to allow us to iterate fast, we just try to call `GetConfig()`, but
+ // ignore any errors for the case where the target Gitaly node doesn't support the RPC yet.
+ // TODO: Remove this hack and properly return the error in the next release cycle.
+ if err := func() error {
+ stream, err := repoClient.GetConfig(ctx, &gitalypb.GetConfigRequest{
+ Repository: in.GetSource(),
+ })
+ if err != nil {
+ return err
+ }
+
+ configPath := filepath.Join(repoPath, "config")
+ if err := writeFile(configPath, 0644, streamio.NewReader(func() ([]byte, error) {
+ resp, err := stream.Recv()
+ return resp.GetData(), err
+ })); err != nil {
+ return err
+ }
+
+ return nil
+ }(); err != nil {
+ ctxlogrus.Extract(ctx).WithError(err).Warn("synchronizing gitconfig failed")
+ }
+
+ return nil
+}
+
func (s *server) syncInfoAttributes(ctx context.Context, in *gitalypb.ReplicateRepositoryRequest) error {
repoClient, err := s.newRepoClient(ctx, in.GetSource().GetStorageName())
if err != nil {
diff --git a/internal/gitaly/service/repository/replicate_test.go b/internal/gitaly/service/repository/replicate_test.go
index 84a61240e..131392911 100644
--- a/internal/gitaly/service/repository/replicate_test.go
+++ b/internal/gitaly/service/repository/replicate_test.go
@@ -47,6 +47,11 @@ func TestReplicateRepository(t *testing.T) {
attrData := []byte("*.pbxproj binary\n")
require.NoError(t, ioutil.WriteFile(attrFilePath, attrData, 0644))
+ // Write a modified gitconfig
+ gittest.Exec(t, cfg, "-C", repoPath, "config", "please.replicate", "me")
+ configData := testhelper.MustReadFile(t, filepath.Join(repoPath, "config"))
+ require.Contains(t, string(configData), "[please]\n\treplicate = me\n")
+
targetRepo := *repo
targetRepo.StorageName = cfg.Storages[1].Name
@@ -68,6 +73,10 @@ func TestReplicateRepository(t *testing.T) {
replicatedAttrData := testhelper.MustReadFile(t, replicatedAttrFilePath)
require.Equal(t, string(attrData), string(replicatedAttrData), "info/attributes files must match")
+ replicatedConfigPath := filepath.Join(targetRepoPath, "config")
+ replicatedConfigData := testhelper.MustReadFile(t, replicatedConfigPath)
+ require.Equal(t, string(configData), string(replicatedConfigData), "config files must match")
+
// create another branch
gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("branch"))
_, err = client.ReplicateRepository(injectedCtx, &gitalypb.ReplicateRepositoryRequest{