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:
-rw-r--r--internal/gitaly/service/repository/create_repository_from_bundle_test.go4
-rw-r--r--internal/gitaly/service/repository/util.go3
-rw-r--r--internal/gitaly/service/repository/util_test.go46
3 files changed, 50 insertions, 3 deletions
diff --git a/internal/gitaly/service/repository/create_repository_from_bundle_test.go b/internal/gitaly/service/repository/create_repository_from_bundle_test.go
index 8f544432e..4e47e9ec3 100644
--- a/internal/gitaly/service/repository/create_repository_from_bundle_test.go
+++ b/internal/gitaly/service/repository/create_repository_from_bundle_test.go
@@ -151,8 +151,8 @@ func TestCreateRepositoryFromBundle_transactional(t *testing.T) {
createVote("47553c06f575f757ad56ef3216c59804b72aa4a6", voting.Prepared),
createVote("47553c06f575f757ad56ef3216c59804b72aa4a6", voting.Committed),
// And this is the manual votes we compute by walking the repository.
- createVote("da39a3ee5e6b4b0d3255bfef95601890afd80709", voting.Prepared),
- createVote("da39a3ee5e6b4b0d3255bfef95601890afd80709", voting.Committed),
+ createVote("5947862798db146701879742c0d8fd988ca37797", voting.Prepared),
+ createVote("5947862798db146701879742c0d8fd988ca37797", voting.Committed),
}, txManager.Votes())
}
diff --git a/internal/gitaly/service/repository/util.go b/internal/gitaly/service/repository/util.go
index 97a96de28..852995543 100644
--- a/internal/gitaly/service/repository/util.go
+++ b/internal/gitaly/service/repository/util.go
@@ -124,11 +124,12 @@ func (s *server) createRepository(
// The way packfiles are generated may not be deterministic, so we skip over the
// object database.
case filepath.Join(newRepoDir.Path(), "objects"):
+ return fs.SkipDir
// FETCH_HEAD refers to the remote we're fetching from. This URL may not be
// deterministic, e.g. when fetching from a temporary file like we do in
// CreateRepositoryFromBundle.
case filepath.Join(newRepoDir.Path(), "FETCH_HEAD"):
- return fs.SkipDir
+ return nil
}
// We do not care about directories.
diff --git a/internal/gitaly/service/repository/util_test.go b/internal/gitaly/service/repository/util_test.go
index 17773d5a8..ffbb80001 100644
--- a/internal/gitaly/service/repository/util_test.go
+++ b/internal/gitaly/service/repository/util_test.go
@@ -206,6 +206,52 @@ func TestCreateRepository(t *testing.T) {
},
expectedErr: fmt.Errorf("locking repository: %w", errors.New("file already locked")),
},
+ {
+ desc: "vote is deterministic",
+ transactional: true,
+ setup: func(t *testing.T, repo *gitalypb.Repository, repoPath string) {
+ txManager.VoteFn = func(_ context.Context, _ txinfo.Transaction, vote voting.Vote, _ voting.Phase) error {
+ require.Equal(t, voting.VoteFromData([]byte("headcfgfoo")), vote)
+ return nil
+ }
+ },
+ seed: func(t *testing.T, repo *gitalypb.Repository, repoPath string) error {
+ // Remove the repository first so we can start from a clean state.
+ require.NoError(t, os.RemoveAll(repoPath))
+ require.NoError(t, os.Mkdir(repoPath, 0o777))
+
+ // Objects and FETCH_HEAD should both be ignored. They may contain
+ // indeterministic data that's different across replicas and would
+ // thus cause us to not reach quorum.
+ require.NoError(t, os.Mkdir(filepath.Join(repoPath, "objects"), 0o777))
+ require.NoError(t, os.WriteFile(filepath.Join(repoPath, "objects", "object"), []byte("object"), 0o666))
+ require.NoError(t, os.WriteFile(filepath.Join(repoPath, "FETCH_HEAD"), []byte("fetch-head"), 0o666))
+
+ // All the other files should be hashed though.
+ require.NoError(t, os.WriteFile(filepath.Join(repoPath, "HEAD"), []byte("head"), 0o666))
+ require.NoError(t, os.WriteFile(filepath.Join(repoPath, "config"), []byte("cfg"), 0o666))
+ require.NoError(t, os.MkdirAll(filepath.Join(repoPath, "refs", "heads"), 0o777))
+ require.NoError(t, os.WriteFile(filepath.Join(repoPath, "refs", "heads", "foo"), []byte("foo"), 0o666))
+
+ return nil
+ },
+ verify: func(t *testing.T, _ *gitalypb.Repository, tempRepoPath string, _ *gitalypb.Repository, realRepoPath string) {
+ require.NoDirExists(t, tempRepoPath)
+ require.DirExists(t, realRepoPath)
+
+ // Even though a subset of data wasn't voted on, it should still be
+ // part of the final repository.
+ for expectedPath, expectedContents := range map[string]string{
+ filepath.Join(realRepoPath, "objects", "object"): "object",
+ filepath.Join(realRepoPath, "HEAD"): "head",
+ filepath.Join(realRepoPath, "FETCH_HEAD"): "fetch-head",
+ filepath.Join(realRepoPath, "config"): "cfg",
+ filepath.Join(realRepoPath, "refs", "heads", "foo"): "foo",
+ } {
+ require.Equal(t, expectedContents, string(testhelper.MustReadFile(t, expectedPath)))
+ }
+ },
+ },
} {
t.Run(tc.desc, func(t *testing.T) {
repo := &gitalypb.Repository{