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:
authorSami Hiltunen <shiltunen@gitlab.com>2023-11-16 17:18:11 +0300
committerSami Hiltunen <shiltunen@gitlab.com>2023-11-16 17:18:11 +0300
commit9b36b0700fe0f1b25bd1105ce20ddf1ab66f3050 (patch)
treedcc5a8b979563f401f333f9206f0d8b5a63e5561 /internal/praefect
parente6062aee6505de1ac518580cc37487949e443677 (diff)
parent5aa03dd6b541eb990002d054baf442dc28c8ea07 (diff)
Merge branch 'jt-praefect-pool-sync' into 'master'
praefect: Reconcile non-matching object pools during replication See merge request https://gitlab.com/gitlab-org/gitaly/-/merge_requests/6526 Merged-by: Sami Hiltunen <shiltunen@gitlab.com> Approved-by: Will Chandler <wchandler@gitlab.com> Reviewed-by: Will Chandler <wchandler@gitlab.com> Co-authored-by: Justin Tobler <jtobler@gitlab.com>
Diffstat (limited to 'internal/praefect')
-rw-r--r--internal/praefect/replicator.go39
-rw-r--r--internal/praefect/replicator_test.go39
2 files changed, 67 insertions, 11 deletions
diff --git a/internal/praefect/replicator.go b/internal/praefect/replicator.go
index 26e47b26b..bc5f1e6ca 100644
--- a/internal/praefect/replicator.go
+++ b/internal/praefect/replicator.go
@@ -88,32 +88,49 @@ func (dr defaultReplicator) Replicate(ctx context.Context, event datastore.Repli
return fmt.Errorf("failed to create repository: %w", err)
}
- // check if the repository has an object pool
+ // Object pool state between the source and target repository should match. Get object pool
+ // information for the source and target repository and reconcile any detected differences.
sourceObjectPoolClient := gitalypb.NewObjectPoolServiceClient(sourceCC)
+ targetObjectPoolClient := gitalypb.NewObjectPoolServiceClient(targetCC)
- resp, err := sourceObjectPoolClient.GetObjectPool(ctx, &gitalypb.GetObjectPoolRequest{
+ sourceResp, err := sourceObjectPoolClient.GetObjectPool(ctx, &gitalypb.GetObjectPoolRequest{
Repository: sourceRepository,
})
if err != nil {
return err
}
- sourceObjectPool := resp.GetObjectPool()
+ targetResp, err := targetObjectPoolClient.GetObjectPool(ctx, &gitalypb.GetObjectPoolRequest{
+ Repository: targetRepository,
+ })
+ if err != nil {
+ return err
+ }
- targetObjectPoolClient := gitalypb.NewObjectPoolServiceClient(targetCC)
+ sourcePool := sourceResp.GetObjectPool()
+ targetPool := targetResp.GetObjectPool()
- if sourceObjectPool == nil {
- // If the source repository is not linked to an object pool, the target repository
- // should also not be linked to any object pool to ensure consistency.
+ switch {
+ // If the source and target object pool state already match, there is nothing to sync.
+ case sourcePool.GetRepository().GetRelativePath() == targetPool.GetRepository().GetRelativePath():
+ // If the target repository is linked to a non-matching object pool it must be disconnected.
+ case targetPool != nil:
if _, err := targetObjectPoolClient.DisconnectGitAlternates(ctx, &gitalypb.DisconnectGitAlternatesRequest{
Repository: targetRepository,
}); err != nil {
return err
}
- } else {
- // If the source repository is linked to an object pool, the target repository
- // should link to the same object pool.
- targetObjectPool := proto.Clone(sourceObjectPool).(*gitalypb.ObjectPool)
+
+ // If the source repository is not linked to an object pool, the target repository does not
+ // need to be linked to a new object pool. Otherwise, continue to object pool linking.
+ if sourcePool == nil {
+ break
+ }
+ fallthrough
+ // If the source pool is linked to a repository, link the target repository to the matching
+ // target object pool.
+ case targetPool == nil:
+ targetObjectPool := proto.Clone(sourcePool).(*gitalypb.ObjectPool)
targetObjectPool.GetRepository().StorageName = targetRepository.GetStorageName()
if _, err := targetObjectPoolClient.LinkRepositoryToObjectPool(ctx, &gitalypb.LinkRepositoryToObjectPoolRequest{
ObjectPool: targetObjectPool,
diff --git a/internal/praefect/replicator_test.go b/internal/praefect/replicator_test.go
index c3f3c5797..13c940066 100644
--- a/internal/praefect/replicator_test.go
+++ b/internal/praefect/replicator_test.go
@@ -339,6 +339,45 @@ func testDefaultReplicatorReplicate(t *testing.T, ctx context.Context) {
}
},
},
+ {
+ desc: "target disconnected and linked to match source",
+ setup: func(t *testing.T) setupData {
+ // Create repository on source Gitaly that does not have a link to an object pool.
+ sourceRepo, _ := gittest.CreateRepository(t, ctx, sourceCfg)
+ sourcePool, _ := gittest.CreateObjectPool(t, ctx, sourceCfg, sourceRepo, gittest.CreateObjectPoolConfig{
+ LinkRepositoryToObjectPool: true,
+ })
+
+ // Create repository on target Gitaly with a relative path different from the source
+ // repository and link it to an object pool.
+ targetRepo, _ := gittest.CreateRepository(t, ctx, targetCfg, gittest.CreateRepositoryConfig{
+ RelativePath: sourceRepo.RelativePath,
+ })
+ gittest.CreateObjectPool(t, ctx, targetCfg, targetRepo, gittest.CreateObjectPoolConfig{
+ LinkRepositoryToObjectPool: true,
+ })
+
+ // Create object pool on target Gitaly with the same relative path as the source
+ // object pool. This repository will eventually be linked to the target repository.
+ gittest.CreateRepository(t, ctx, targetCfg, gittest.CreateRepositoryConfig{
+ RelativePath: sourcePool.Repository.RelativePath,
+ })
+
+ return setupData{
+ job: datastore.ReplicationJob{
+ ReplicaPath: sourceRepo.RelativePath,
+ TargetNodeStorage: targetStorage,
+ SourceNodeStorage: sourceStorage,
+ },
+ expectedPool: &gitalypb.ObjectPool{
+ Repository: &gitalypb.Repository{
+ StorageName: targetStorage,
+ RelativePath: sourcePool.Repository.RelativePath,
+ },
+ },
+ }
+ },
+ },
} {
t.Run(tc.desc, func(t *testing.T) {
testSetup := tc.setup(t)