diff options
author | James Fargher <jfargher@gitlab.com> | 2023-10-19 04:29:20 +0300 |
---|---|---|
committer | James Fargher <jfargher@gitlab.com> | 2023-10-19 06:27:53 +0300 |
commit | ba1e54f4e70bc6717e960066dd0a326ab6c0dc03 (patch) | |
tree | cf009cb73f31ad17bd694afffd094ba19186ac37 | |
parent | 587466c322eb937d54f8af5eb413fee800ac6e4f (diff) |
backup: Set default branch from manifest on restore
Adds a test for the worst case scenario where the backup was of an empty
repository. In this case there is no bundle file to derive the default
branch.
Eventually manifest files will have blank paths to indicate, for
example, that there is no bundle or no hooks. Until then the code
expects that all paths will be set, even if the destination file does
not exist.
Changelog: changed
-rw-r--r-- | internal/backup/backup.go | 6 | ||||
-rw-r--r-- | internal/backup/backup_test.go | 43 | ||||
-rw-r--r-- | internal/backup/repository.go | 10 |
3 files changed, 47 insertions, 12 deletions
diff --git a/internal/backup/backup.go b/internal/backup/backup.go index 70f1a7b36..3811abe34 100644 --- a/internal/backup/backup.go +++ b/internal/backup/backup.go @@ -100,7 +100,7 @@ type Repository interface { // repository cannot be found. Remove(ctx context.Context) error // Create creates the repository. - Create(ctx context.Context, hash git.ObjectHash) error + Create(ctx context.Context, hash git.ObjectHash, defaultBranch string) error // FetchBundle fetches references from a bundle. Refs will be mirrored to // the repository. FetchBundle(ctx context.Context, reader io.Reader) error @@ -303,7 +303,9 @@ func (mgr *Manager) Restore(ctx context.Context, req *RestoreRequest) error { return fmt.Errorf("manager: %w", err) } - if err := repo.Create(ctx, hash); err != nil { + defaultBranch, _ := git.ReferenceName(backup.HeadReference).Branch() + + if err := repo.Create(ctx, hash, defaultBranch); err != nil { return fmt.Errorf("manager: %w", err) } diff --git a/internal/backup/backup_test.go b/internal/backup/backup_test.go index 31a7fae13..6156c0920 100644 --- a/internal/backup/backup_test.go +++ b/internal/backup/backup_test.go @@ -868,12 +868,13 @@ func TestManager_Restore_specific(t *testing.T) { backupRoot := testhelper.TempDir(t) for _, tc := range []struct { - desc string - setup func(tb testing.TB) (*gitalypb.Repository, *git.Checksum) - alwaysCreate bool - expectExists bool - expectedPaths []string - expectedErrAs error + desc string + setup func(tb testing.TB) (*gitalypb.Repository, *git.Checksum) + alwaysCreate bool + expectExists bool + expectedPaths []string + expectedErrAs error + expectedHeadReference git.ReferenceName }{ { desc: "missing backup", @@ -959,6 +960,28 @@ func TestManager_Restore_specific(t *testing.T) { }, expectExists: true, }, + { + desc: "manifest, empty backup", + setup: func(tb testing.TB) (*gitalypb.Repository, *git.Checksum) { + repo, _ := gittest.CreateRepository(t, ctx, cfg) + + testhelper.WriteFiles(tb, backupRoot, map[string]any{ + filepath.Join("manifests", repo.GetStorageName(), repo.GetRelativePath(), backupID+".toml"): `object_format = 'sha1' +head_reference = 'refs/heads/banana' + +[[steps]] +bundle_path = 'repo.bundle' +ref_path = 'repo.refs' +custom_hooks_path = 'custom_hooks.tar' +`, + "repo.refs": "", + }) + + return repo, new(git.Checksum) + }, + expectExists: true, + expectedHeadReference: "refs/heads/banana", + }, } { t.Run(tc.desc, func(t *testing.T) { repo, expectedChecksum := tc.setup(t) @@ -1003,10 +1026,18 @@ func TestManager_Restore_specific(t *testing.T) { // the repository through Praefect. In order to get to the correct disk paths, we need // to get the replica path of the rewritten repository. repoPath := filepath.Join(cfg.Storages[0].Path, gittest.GetReplicaPath(t, ctx, cfg, repo)) + for _, p := range tc.expectedPaths { require.FileExists(t, filepath.Join(repoPath, p)) } } + + if len(tc.expectedHeadReference) > 0 { + repoPath := filepath.Join(cfg.Storages[0].Path, gittest.GetReplicaPath(t, ctx, cfg, repo)) + + ref := gittest.GetSymbolicRef(t, cfg, repoPath, "HEAD") + require.Equal(t, tc.expectedHeadReference, git.ReferenceName(ref.Target)) + } }) } }) diff --git a/internal/backup/repository.go b/internal/backup/repository.go index 317b13fab..a7d6ee413 100644 --- a/internal/backup/repository.go +++ b/internal/backup/repository.go @@ -209,11 +209,12 @@ func (rr *remoteRepository) Remove(ctx context.Context) error { } // Create creates the repository. -func (rr *remoteRepository) Create(ctx context.Context, hash git.ObjectHash) error { +func (rr *remoteRepository) Create(ctx context.Context, hash git.ObjectHash, defaultBranch string) error { repoClient := rr.newRepoClient() if _, err := repoClient.CreateRepository(ctx, &gitalypb.CreateRepositoryRequest{ - Repository: rr.repo, - ObjectFormat: hash.ProtoFormat, + Repository: rr.repo, + ObjectFormat: hash.ProtoFormat, + DefaultBranch: []byte(defaultBranch), }); err != nil { return fmt.Errorf("remote repository: create: %w", err) } @@ -403,7 +404,7 @@ func (r *localRepository) Remove(ctx context.Context) error { } // Create creates the repository. -func (r *localRepository) Create(ctx context.Context, hash git.ObjectHash) error { +func (r *localRepository) Create(ctx context.Context, hash git.ObjectHash, defaultBranch string) error { if err := repoutil.Create( ctx, r.logger, @@ -414,6 +415,7 @@ func (r *localRepository) Create(ctx context.Context, hash git.ObjectHash) error r.repo, func(repository *gitalypb.Repository) error { return nil }, repoutil.WithObjectHash(hash), + repoutil.WithBranchName(defaultBranch), ); err != nil { return fmt.Errorf("local repository: create: %w", err) } |