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:
authorJustin Tobler <jtobler@gitlab.com>2023-08-10 05:16:22 +0300
committerJustin Tobler <jtobler@gitlab.com>2023-08-10 05:16:22 +0300
commite5a6a0ced520a546ed71976d12fef6b651e2a1cf (patch)
tree411cde8ebfa35c5e99df280f5d27f2c03574700d
parent0cfde57ce1292ffeafc0f3b0c01f3d199151ff63 (diff)
parentf2bc26bbbb0a9781d36ee6a72bd1786c6060c502 (diff)
Merge branch 'differentiate_empty_restores' into 'master'
Differentiate empty repository restores See merge request https://gitlab.com/gitlab-org/gitaly/-/merge_requests/6180 Merged-by: Justin Tobler <jtobler@gitlab.com> Approved-by: Justin Tobler <jtobler@gitlab.com> Reviewed-by: Will Chandler <wchandler@gitlab.com> Reviewed-by: Justin Tobler <jtobler@gitlab.com> Co-authored-by: James Fargher <jfargher@gitlab.com>
-rw-r--r--cmd/gitaly-backup/restore_test.go12
-rw-r--r--internal/backup/backup.go73
-rw-r--r--internal/backup/backup_test.go131
-rw-r--r--internal/backup/locator.go7
-rw-r--r--internal/backup/locator_test.go21
-rw-r--r--internal/backup/server_side_test.go4
-rw-r--r--internal/gitaly/service/repository/restore_repository_test.go2
-rw-r--r--internal/testhelper/testhelper.go33
8 files changed, 190 insertions, 93 deletions
diff --git a/cmd/gitaly-backup/restore_test.go b/cmd/gitaly-backup/restore_test.go
index 7a15daeff..069fbf6d0 100644
--- a/cmd/gitaly-backup/restore_test.go
+++ b/cmd/gitaly-backup/restore_test.go
@@ -8,6 +8,7 @@ import (
"flag"
"fmt"
"io"
+ "os"
"path/filepath"
"testing"
@@ -16,6 +17,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v16/internal/git"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service/setup"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/helper/perm"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testcfg"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper/testserver"
@@ -38,13 +40,18 @@ func TestRestoreSubcommand(t *testing.T) {
path := testhelper.TempDir(t)
existingRepoBundlePath := filepath.Join(path, existingRepo.RelativePath+".bundle")
+ existingRepoRefPath := filepath.Join(path, existingRepo.RelativePath+".refs")
+
gittest.Exec(t, cfg, "-C", existRepoPath, "bundle", "create", existingRepoBundlePath, "--all")
+ require.NoError(t, os.WriteFile(existingRepoRefPath, gittest.Exec(t, cfg, "-C", existRepoPath, "show-ref"), perm.SharedFile))
var repos []*gitalypb.Repository
for i := 0; i < 2; i++ {
repo := gittest.InitRepoDir(t, cfg.Storages[0].Path, fmt.Sprintf("repo-%d", i))
repoBundlePath := filepath.Join(path, repo.RelativePath+".bundle")
+ repoRefPath := filepath.Join(path, repo.RelativePath+".refs")
testhelper.CopyFile(t, existingRepoBundlePath, repoBundlePath)
+ testhelper.CopyFile(t, existingRepoRefPath, repoRefPath)
repos = append(repos, repo)
}
@@ -116,13 +123,18 @@ func TestRestoreSubcommand_serverSide(t *testing.T) {
gittest.WriteCommit(t, cfg, existRepoPath, gittest.WithBranch(git.DefaultBranch))
existingRepoBundlePath := filepath.Join(path, existingRepo.RelativePath+".bundle")
+ existingRepoRefPath := filepath.Join(path, existingRepo.RelativePath+".refs")
+
gittest.Exec(t, cfg, "-C", existRepoPath, "bundle", "create", existingRepoBundlePath, "--all")
+ require.NoError(t, os.WriteFile(existingRepoRefPath, gittest.Exec(t, cfg, "-C", existRepoPath, "show-ref"), perm.SharedFile))
var repos []*gitalypb.Repository
for i := 0; i < 2; i++ {
repo := gittest.InitRepoDir(t, cfg.Storages[0].Path, fmt.Sprintf("repo-%d", i))
repoBundlePath := filepath.Join(path, repo.RelativePath+".bundle")
+ repoRefPath := filepath.Join(path, repo.RelativePath+".refs")
testhelper.CopyFile(t, existingRepoBundlePath, repoBundlePath)
+ testhelper.CopyFile(t, existingRepoRefPath, repoRefPath)
repos = append(repos, repo)
}
diff --git a/internal/backup/backup.go b/internal/backup/backup.go
index b2a594992..fd308abd2 100644
--- a/internal/backup/backup.go
+++ b/internal/backup/backup.go
@@ -49,10 +49,6 @@ type Backup struct {
type Step struct {
// BundlePath is the path of the bundle
BundlePath string
- // SkippableOnNotFound defines if the bundle can be skipped when it does
- // not exist. This allows us to maintain legacy behaviour where we always
- // check a specific location for a bundle without knowing if it exists.
- SkippableOnNotFound bool
// RefPath is the path of the ref file
RefPath string
// PreviousRefPath is the path of the previous ref file
@@ -274,23 +270,33 @@ func (mgr *Manager) Restore(ctx context.Context, req *RestoreRequest) error {
}
for _, step := range backup.Steps {
- if err := mgr.restoreBundle(ctx, repo, step.BundlePath); err != nil {
- if step.SkippableOnNotFound && errors.Is(err, ErrDoesntExist) {
- // For compatibility with existing backups we need to make sure the
- // repository exists even if there's no bundle for project
- // repositories (not wiki or snippet repositories). Gitaly does
- // not know which repository is which type so here we accept a
- // parameter to tell us to employ this behaviour. Since the
- // repository has already been created, we simply skip cleaning up.
- if req.AlwaysCreate {
- return nil
- }
-
- if err := repo.Remove(ctx); err != nil {
- return fmt.Errorf("manager: remove on skipped: %w", err)
- }
-
- return fmt.Errorf("manager: %w: %s", ErrSkipped, err.Error())
+ refs, err := mgr.readRefs(ctx, step.RefPath)
+ switch {
+ case errors.Is(err, ErrDoesntExist):
+ // For compatibility with existing backups we need to make sure the
+ // repository exists even if there's no bundle for project
+ // repositories (not wiki or snippet repositories). Gitaly does
+ // not know which repository is which type so here we accept a
+ // parameter to tell us to employ this behaviour. Since the
+ // repository has already been created, we simply skip cleaning up.
+ if req.AlwaysCreate {
+ return nil
+ }
+
+ if err := repo.Remove(ctx); err != nil {
+ return fmt.Errorf("manager: remove on skipped: %w", err)
+ }
+
+ return fmt.Errorf("manager: %w: %s", ErrSkipped, err.Error())
+ case err != nil:
+ return fmt.Errorf("manager: %w", err)
+ }
+
+ // Git bundles can not be created for empty repositories. Since empty
+ // repository backups do not contain a bundle, skip bundle restoration.
+ if len(refs) > 0 {
+ if err := mgr.restoreBundle(ctx, repo, step.BundlePath); err != nil {
+ return fmt.Errorf("manager: %w", err)
}
}
if err := mgr.restoreCustomHooks(ctx, repo, step.CustomHooksPath); err != nil {
@@ -405,6 +411,31 @@ func (mgr *Manager) negatedKnownRefs(ctx context.Context, step *Step) (io.ReadCl
return r, nil
}
+func (mgr *Manager) readRefs(ctx context.Context, path string) ([]git.Reference, error) {
+ reader, err := mgr.sink.GetReader(ctx, path)
+ if err != nil {
+ return nil, fmt.Errorf("read refs: %w", err)
+ }
+ defer reader.Close()
+
+ var refs []git.Reference
+
+ d := git.NewShowRefDecoder(reader)
+ for {
+ var ref git.Reference
+
+ if err := d.Decode(&ref); err == io.EOF {
+ break
+ } else if err != nil {
+ return refs, fmt.Errorf("read refs: %w", err)
+ }
+
+ refs = append(refs, ref)
+ }
+
+ return refs, nil
+}
+
func (mgr *Manager) restoreBundle(ctx context.Context, repo Repository, path string) error {
reader, err := mgr.sink.GetReader(ctx, path)
if err != nil {
diff --git a/internal/backup/backup_test.go b/internal/backup/backup_test.go
index 46a8e840d..fb156d732 100644
--- a/internal/backup/backup_test.go
+++ b/internal/backup/backup_test.go
@@ -433,6 +433,8 @@ func TestManager_Restore_latest(t *testing.T) {
commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"))
gittest.WriteTag(t, cfg, repoPath, "v1.0.0", commitID.Revision())
repoChecksum := gittest.ChecksumRepo(t, cfg, repoPath)
+ repoBundle := gittest.BundleRepo(t, cfg, repoPath, "-")
+ repoRefs := gittest.Exec(t, cfg, "-C", repoPath, "show-ref", "--head")
backupRoot := testhelper.TempDir(t)
@@ -452,9 +454,10 @@ func TestManager_Restore_latest(t *testing.T) {
repo, _ := gittest.CreateRepository(t, ctx, cfg)
relativePath := stripRelativePath(tb, repo)
- require.NoError(tb, os.MkdirAll(filepath.Join(backupRoot, relativePath), perm.PublicDir))
- bundlePath := filepath.Join(backupRoot, relativePath+".bundle")
- gittest.BundleRepo(tb, cfg, repoPath, bundlePath)
+ testhelper.WriteFiles(tb, backupRoot, map[string]any{
+ relativePath + ".bundle": repoBundle,
+ relativePath + ".refs": repoRefs,
+ })
return repo, repoChecksum
},
@@ -467,10 +470,13 @@ func TestManager_Restore_latest(t *testing.T) {
repo, _ := gittest.CreateRepository(t, ctx, cfg)
relativePath := stripRelativePath(tb, repo)
- bundlePath := filepath.Join(backupRoot, relativePath+".bundle")
customHooksPath := filepath.Join(backupRoot, relativePath, "custom_hooks.tar")
+ testhelper.WriteFiles(tb, backupRoot, map[string]any{
+ relativePath + ".bundle": repoBundle,
+ relativePath + ".refs": repoRefs,
+ })
+
require.NoError(tb, os.MkdirAll(filepath.Join(backupRoot, relativePath), perm.PublicDir))
- gittest.BundleRepo(tb, cfg, repoPath, bundlePath)
testhelper.CopyFile(tb, mustCreateCustomHooksArchive(t, ctx), customHooksPath)
return repo, repoChecksum
@@ -508,13 +514,13 @@ func TestManager_Restore_latest(t *testing.T) {
repo, _ := gittest.CreateRepository(t, ctx, cfg)
relativePath := stripRelativePath(tb, repo)
- refsPath := filepath.Join(backupRoot, relativePath+".refs")
- require.NoError(tb, os.MkdirAll(filepath.Join(backupRoot, relativePath), perm.PublicDir))
- require.NoError(tb, os.WriteFile(refsPath, []byte{}, perm.SharedFile))
+ testhelper.WriteFiles(tb, backupRoot, map[string]any{
+ relativePath + ".refs": "",
+ })
- return repo, nil
+ return repo, new(git.Checksum)
},
- expectedErrAs: backup.ErrSkipped,
+ expectExists: true,
},
{
desc: "empty backup, always create",
@@ -523,11 +529,11 @@ func TestManager_Restore_latest(t *testing.T) {
repo, _ := gittest.CreateRepository(t, ctx, cfg)
relativePath := stripRelativePath(tb, repo)
- refsPath := filepath.Join(backupRoot, relativePath+".refs")
- require.NoError(tb, os.MkdirAll(filepath.Join(backupRoot, relativePath), perm.PublicDir))
- require.NoError(tb, os.WriteFile(refsPath, []byte{}, perm.SharedFile))
+ testhelper.WriteFiles(tb, backupRoot, map[string]any{
+ relativePath + ".refs": "",
+ })
- return repo, nil
+ return repo, new(git.Checksum)
},
alwaysCreate: true,
expectExists: true,
@@ -542,9 +548,10 @@ func TestManager_Restore_latest(t *testing.T) {
}
relativePath := stripRelativePath(tb, repo)
- require.NoError(tb, os.MkdirAll(filepath.Dir(filepath.Join(backupRoot, relativePath)), perm.PublicDir))
- bundlePath := filepath.Join(backupRoot, relativePath+".bundle")
- gittest.BundleRepo(tb, cfg, repoPath, bundlePath)
+ testhelper.WriteFiles(tb, backupRoot, map[string]any{
+ relativePath + ".bundle": repoBundle,
+ relativePath + ".refs": repoRefs,
+ })
return repo, repoChecksum
},
@@ -556,13 +563,14 @@ func TestManager_Restore_latest(t *testing.T) {
setup: func(tb testing.TB) (*gitalypb.Repository, *git.Checksum) {
const backupID = "abc123"
repo, _ := gittest.CreateRepository(t, ctx, cfg)
- repoBackupPath := joinBackupPath(tb, backupRoot, repo)
- backupPath := filepath.Join(repoBackupPath, backupID)
- require.NoError(tb, os.MkdirAll(backupPath, perm.PublicDir))
- require.NoError(tb, os.WriteFile(filepath.Join(repoBackupPath, "LATEST"), []byte(backupID), perm.PublicFile))
- require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), perm.PublicFile))
- bundlePath := filepath.Join(backupPath, "001.bundle")
- gittest.BundleRepo(tb, cfg, repoPath, bundlePath)
+
+ relativePath := stripRelativePath(tb, repo)
+ testhelper.WriteFiles(tb, backupRoot, map[string]any{
+ filepath.Join(relativePath, "LATEST"): backupID,
+ filepath.Join(relativePath, backupID, "LATEST"): "001",
+ filepath.Join(relativePath, backupID, "001.bundle"): repoBundle,
+ filepath.Join(relativePath, backupID, "001.refs"): repoRefs,
+ })
return repo, repoChecksum
},
@@ -574,13 +582,13 @@ func TestManager_Restore_latest(t *testing.T) {
setup: func(tb testing.TB) (*gitalypb.Repository, *git.Checksum) {
const backupID = "abc123"
repo, _ := gittest.CreateRepository(t, ctx, cfg)
- repoBackupPath := joinBackupPath(tb, backupRoot, repo)
- backupPath := filepath.Join(repoBackupPath, backupID)
- require.NoError(tb, os.MkdirAll(backupPath, perm.PublicDir))
- require.NoError(tb, os.WriteFile(filepath.Join(repoBackupPath, "LATEST"), []byte(backupID), perm.PublicFile))
- require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), perm.PublicFile))
- refsPath := filepath.Join(backupPath, "001.refs")
- require.NoError(tb, os.WriteFile(refsPath, []byte{}, perm.SharedFile))
+
+ relativePath := stripRelativePath(tb, repo)
+ testhelper.WriteFiles(tb, backupRoot, map[string]any{
+ filepath.Join(relativePath, "LATEST"): backupID,
+ filepath.Join(relativePath, backupID, "LATEST"): "001",
+ filepath.Join(relativePath, backupID, "001.refs"): "",
+ })
return repo, new(git.Checksum)
},
@@ -595,11 +603,6 @@ func TestManager_Restore_latest(t *testing.T) {
_, expectedRepoPath := gittest.CreateRepository(t, ctx, cfg)
repo, _ := gittest.CreateRepository(t, ctx, cfg)
- repoBackupPath := joinBackupPath(tb, backupRoot, repo)
- backupPath := filepath.Join(repoBackupPath, backupID)
- require.NoError(tb, os.MkdirAll(backupPath, perm.PublicDir))
- require.NoError(tb, os.WriteFile(filepath.Join(repoBackupPath, "LATEST"), []byte(backupID), perm.PublicFile))
- require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("002"), perm.PublicFile))
root := gittest.WriteCommit(tb, cfg, expectedRepoPath,
gittest.WithBranch("master"),
@@ -613,25 +616,35 @@ func TestManager_Restore_latest(t *testing.T) {
gittest.WithParents(root),
)
gittest.Exec(tb, cfg, "-C", expectedRepoPath, "symbolic-ref", "HEAD", "refs/heads/master")
- bundlePath1 := filepath.Join(backupPath, "001.bundle")
- gittest.Exec(tb, cfg, "-C", expectedRepoPath, "bundle", "create", bundlePath1,
+ bundle1 := gittest.Exec(tb, cfg, "-C", expectedRepoPath, "bundle", "create", "-",
"HEAD",
"refs/heads/master",
"refs/heads/other",
)
+ refs1 := gittest.Exec(t, cfg, "-C", expectedRepoPath, "show-ref", "--head")
master2 := gittest.WriteCommit(tb, cfg, expectedRepoPath,
gittest.WithBranch("master"),
gittest.WithParents(master1),
)
- bundlePath2 := filepath.Join(backupPath, "002.bundle")
- gittest.Exec(tb, cfg, "-C", expectedRepoPath, "bundle", "create", bundlePath2,
+ bundle2 := gittest.Exec(tb, cfg, "-C", expectedRepoPath, "bundle", "create", "-",
"HEAD",
"^"+master1.String(),
"^"+other.String(),
"refs/heads/master",
"refs/heads/other",
)
+ refs2 := gittest.Exec(t, cfg, "-C", expectedRepoPath, "show-ref", "--head")
+
+ relativePath := stripRelativePath(tb, repo)
+ testhelper.WriteFiles(tb, backupRoot, map[string]any{
+ filepath.Join(relativePath, "LATEST"): backupID,
+ filepath.Join(relativePath, backupID, "LATEST"): "002",
+ filepath.Join(relativePath, backupID, "001.bundle"): bundle1,
+ filepath.Join(relativePath, backupID, "002.bundle"): bundle2,
+ filepath.Join(relativePath, backupID, "001.refs"): refs1,
+ filepath.Join(relativePath, backupID, "002.refs"): refs2,
+ })
checksum := new(git.Checksum)
checksum.Add(git.NewReference("HEAD", master2))
@@ -761,6 +774,8 @@ func TestManager_Restore_specific(t *testing.T) {
commitID := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("main"))
gittest.WriteTag(t, cfg, repoPath, "v1.0.0", commitID.Revision())
repoChecksum := gittest.ChecksumRepo(t, cfg, repoPath)
+ repoBundle := gittest.BundleRepo(t, cfg, repoPath, "-")
+ repoRefs := gittest.Exec(t, cfg, "-C", repoPath, "show-ref", "--head")
backupRoot := testhelper.TempDir(t)
@@ -776,12 +791,14 @@ func TestManager_Restore_specific(t *testing.T) {
desc: "single incremental",
setup: func(tb testing.TB) (*gitalypb.Repository, *git.Checksum) {
repo, _ := gittest.CreateRepository(t, ctx, cfg)
- repoBackupPath := joinBackupPath(tb, backupRoot, repo)
- backupPath := filepath.Join(repoBackupPath, backupID)
- require.NoError(tb, os.MkdirAll(backupPath, perm.PublicDir))
- require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("001"), perm.PublicFile))
- bundlePath := filepath.Join(backupPath, "001.bundle")
- gittest.BundleRepo(tb, cfg, repoPath, bundlePath)
+
+ relativePath := stripRelativePath(tb, repo)
+ testhelper.WriteFiles(tb, backupRoot, map[string]any{
+ filepath.Join(relativePath, "LATEST"): backupID,
+ filepath.Join(relativePath, backupID, "LATEST"): "001",
+ filepath.Join(relativePath, backupID, "001.bundle"): repoBundle,
+ filepath.Join(relativePath, backupID, "001.refs"): repoRefs,
+ })
return repo, repoChecksum
},
@@ -793,10 +810,6 @@ func TestManager_Restore_specific(t *testing.T) {
_, expectedRepoPath := gittest.CreateRepository(t, ctx, cfg)
repo, _ := gittest.CreateRepository(t, ctx, cfg)
- repoBackupPath := joinBackupPath(tb, backupRoot, repo)
- backupPath := filepath.Join(repoBackupPath, backupID)
- require.NoError(tb, os.MkdirAll(backupPath, perm.PublicDir))
- require.NoError(tb, os.WriteFile(filepath.Join(backupPath, "LATEST"), []byte("002"), perm.PublicFile))
root := gittest.WriteCommit(tb, cfg, expectedRepoPath,
gittest.WithBranch("master"),
@@ -810,25 +823,35 @@ func TestManager_Restore_specific(t *testing.T) {
gittest.WithParents(root),
)
gittest.Exec(tb, cfg, "-C", expectedRepoPath, "symbolic-ref", "HEAD", "refs/heads/master")
- bundlePath1 := filepath.Join(backupPath, "001.bundle")
- gittest.Exec(tb, cfg, "-C", expectedRepoPath, "bundle", "create", bundlePath1,
+ bundle1 := gittest.Exec(tb, cfg, "-C", expectedRepoPath, "bundle", "create", "-",
"HEAD",
"refs/heads/master",
"refs/heads/other",
)
+ refs1 := gittest.Exec(t, cfg, "-C", expectedRepoPath, "show-ref", "--head")
master2 := gittest.WriteCommit(tb, cfg, expectedRepoPath,
gittest.WithBranch("master"),
gittest.WithParents(master1),
)
- bundlePath2 := filepath.Join(backupPath, "002.bundle")
- gittest.Exec(tb, cfg, "-C", expectedRepoPath, "bundle", "create", bundlePath2,
+ bundle2 := gittest.Exec(tb, cfg, "-C", expectedRepoPath, "bundle", "create", "-",
"HEAD",
"^"+master1.String(),
"^"+other.String(),
"refs/heads/master",
"refs/heads/other",
)
+ refs2 := gittest.Exec(t, cfg, "-C", expectedRepoPath, "show-ref", "--head")
+
+ relativePath := stripRelativePath(tb, repo)
+ testhelper.WriteFiles(tb, backupRoot, map[string]any{
+ filepath.Join(relativePath, "LATEST"): backupID,
+ filepath.Join(relativePath, backupID, "LATEST"): "002",
+ filepath.Join(relativePath, backupID, "001.bundle"): bundle1,
+ filepath.Join(relativePath, backupID, "002.bundle"): bundle2,
+ filepath.Join(relativePath, backupID, "001.refs"): refs1,
+ filepath.Join(relativePath, backupID, "002.refs"): refs2,
+ })
checksum := new(git.Checksum)
checksum.Add(git.NewReference("HEAD", master2))
diff --git a/internal/backup/locator.go b/internal/backup/locator.go
index 6d1419489..f2897f2e0 100644
--- a/internal/backup/locator.go
+++ b/internal/backup/locator.go
@@ -61,10 +61,9 @@ func (l LegacyLocator) newFull(repo *gitalypb.Repository) *Step {
backupPath := strings.TrimSuffix(repo.RelativePath, ".git")
return &Step{
- SkippableOnNotFound: true,
- BundlePath: backupPath + ".bundle",
- RefPath: backupPath + ".refs",
- CustomHooksPath: filepath.Join(backupPath, "custom_hooks.tar"),
+ BundlePath: backupPath + ".bundle",
+ RefPath: backupPath + ".refs",
+ CustomHooksPath: filepath.Join(backupPath, "custom_hooks.tar"),
}
}
diff --git a/internal/backup/locator_test.go b/internal/backup/locator_test.go
index bb30379fd..01534d368 100644
--- a/internal/backup/locator_test.go
+++ b/internal/backup/locator_test.go
@@ -35,10 +35,9 @@ func TestLegacyLocator(t *testing.T) {
t.Parallel()
expected := &Step{
- SkippableOnNotFound: true,
- BundlePath: repo.RelativePath + ".bundle",
- RefPath: repo.RelativePath + ".refs",
- CustomHooksPath: filepath.Join(repo.RelativePath, "custom_hooks.tar"),
+ BundlePath: repo.RelativePath + ".bundle",
+ RefPath: repo.RelativePath + ".refs",
+ CustomHooksPath: filepath.Join(repo.RelativePath, "custom_hooks.tar"),
}
full := l.BeginFull(ctx, repo, "abc123")
@@ -54,10 +53,9 @@ func TestLegacyLocator(t *testing.T) {
ObjectFormat: git.ObjectHashSHA1.Format,
Steps: []Step{
{
- SkippableOnNotFound: true,
- BundlePath: repo.RelativePath + ".bundle",
- RefPath: repo.RelativePath + ".refs",
- CustomHooksPath: filepath.Join(repo.RelativePath, "custom_hooks.tar"),
+ BundlePath: repo.RelativePath + ".bundle",
+ RefPath: repo.RelativePath + ".refs",
+ CustomHooksPath: filepath.Join(repo.RelativePath, "custom_hooks.tar"),
},
},
}
@@ -238,10 +236,9 @@ func TestPointerLocator(t *testing.T) {
ObjectFormat: git.ObjectHashSHA1.Format,
Steps: []Step{
{
- SkippableOnNotFound: true,
- BundlePath: repo.RelativePath + ".bundle",
- RefPath: repo.RelativePath + ".refs",
- CustomHooksPath: filepath.Join(repo.RelativePath, "custom_hooks.tar"),
+ BundlePath: repo.RelativePath + ".bundle",
+ RefPath: repo.RelativePath + ".refs",
+ CustomHooksPath: filepath.Join(repo.RelativePath, "custom_hooks.tar"),
},
},
}
diff --git a/internal/backup/server_side_test.go b/internal/backup/server_side_test.go
index fc5e990ac..3329c8a78 100644
--- a/internal/backup/server_side_test.go
+++ b/internal/backup/server_side_test.go
@@ -1,3 +1,5 @@
+//go:build !gitaly_test_sha256
+
package backup_test
import (
@@ -192,7 +194,7 @@ func TestServerSideAdapter_Restore(t *testing.T) {
backupID: "",
}
},
- expectedErr: fmt.Errorf("server-side restore: %w: rpc error: code = FailedPrecondition desc = restore repository: manager: repository skipped: restore bundle: \"@test/restore/latest/missing.bundle\": doesn't exist", backup.ErrSkipped),
+ expectedErr: fmt.Errorf("server-side restore: %w: rpc error: code = FailedPrecondition desc = restore repository: manager: repository skipped: read refs: doesn't exist", backup.ErrSkipped),
},
} {
tc := tc
diff --git a/internal/gitaly/service/repository/restore_repository_test.go b/internal/gitaly/service/repository/restore_repository_test.go
index df0043a69..2551ffeb7 100644
--- a/internal/gitaly/service/repository/restore_repository_test.go
+++ b/internal/gitaly/service/repository/restore_repository_test.go
@@ -138,7 +138,7 @@ func TestRestoreRepository(t *testing.T) {
backupID: "",
}
},
- expectedErr: structerr.NewFailedPrecondition("restore repository: manager: repository skipped: restore bundle: \"@test/restore/latest/missing.bundle\": doesn't exist").WithDetail(
+ expectedErr: structerr.NewFailedPrecondition("restore repository: manager: repository skipped: read refs: doesn't exist").WithDetail(
&gitalypb.RestoreRepositoryResponse_SkippedError{},
),
},
diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go
index 17b511bc4..d4a8bfeb7 100644
--- a/internal/testhelper/testhelper.go
+++ b/internal/testhelper/testhelper.go
@@ -76,6 +76,39 @@ func MustReadFile(tb testing.TB, filename string) []byte {
return content
}
+// WriteFiles writes a map of files to the filesystem where the map key is the
+// filename relative to root and the value is one of string, []byte or
+// io.Reader.
+func WriteFiles(tb testing.TB, root string, files map[string]any) {
+ tb.Helper()
+
+ require.DirExists(tb, root)
+
+ for name, value := range files {
+ path := filepath.Join(root, name)
+
+ require.NoError(tb, os.MkdirAll(filepath.Dir(path), perm.SharedDir))
+
+ switch content := value.(type) {
+ case string:
+ require.NoError(tb, os.WriteFile(path, []byte(content), perm.PublicFile))
+ case []byte:
+ require.NoError(tb, os.WriteFile(path, content, perm.PublicFile))
+ case io.Reader:
+ func() {
+ f, err := os.Create(path)
+ require.NoError(tb, err)
+ defer MustClose(tb, f)
+
+ _, err = io.Copy(f, content)
+ require.NoError(tb, err)
+ }()
+ default:
+ tb.Fatalf("WriteFiles: %q: unsupported file content type %T", path, value)
+ }
+ }
+}
+
// GitlabTestStoragePath returns the storage path to the gitlab-test repo.
func GitlabTestStoragePath() string {
if testDirectory == "" {