repository: replace CopyBlobs with Repack implementation

This commit is contained in:
Michael Eischer 2025-11-23 16:06:29 +01:00
parent b24b088978
commit 81d8bc4ade
4 changed files with 20 additions and 28 deletions

View file

@ -276,9 +276,7 @@ func copyTree(ctx context.Context, srcRepo restic.Repository, dstRepo restic.Rep
copyStats(srcRepo, copyBlobs, packList, printer)
bar := printer.NewCounter("packs copied")
bar.SetMax(uint64(len(packList)))
err = repository.CopyBlobs(ctx, srcRepo, dstRepo, uploader, packList, copyBlobs, bar, printer.P)
bar.Done()
if err != nil {
return errors.Fatalf("%s", err)
}

View file

@ -563,7 +563,9 @@ func (plan *PrunePlan) Execute(ctx context.Context, printer progress.Printer) er
if len(plan.repackPacks) != 0 {
printer.P("repacking packs\n")
bar := printer.NewCounter("packs repacked")
err := Repack(ctx, repo, repo, plan.repackPacks, plan.keepBlobs, bar, printer.P)
err := repo.WithBlobUploader(ctx, func(ctx context.Context, uploader restic.BlobSaver) error {
return CopyBlobs(ctx, repo, repo, uploader, plan.repackPacks, plan.keepBlobs, bar, printer.P)
})
if err != nil {
return errors.Fatalf("%s", err)
}

View file

@ -21,17 +21,18 @@ type repackBlobSet interface {
type LogFunc func(msg string, args ...interface{})
// Repack takes a list of packs together with a list of blobs contained in
// CopyBlobs takes a list of packs together with a list of blobs contained in
// these packs. Each pack is loaded and the blobs listed in keepBlobs is saved
// into a new pack. Returned is the list of obsolete packs which can then
// be removed.
//
// The map keepBlobs is modified by Repack, it is used to keep track of which
// The map keepBlobs is modified by CopyBlobs, it is used to keep track of which
// blobs have been processed.
func Repack(
func CopyBlobs(
ctx context.Context,
repo restic.Repository,
dstRepo restic.Repository,
dstUploader restic.BlobSaver,
packs restic.IDSet,
keepBlobs repackBlobSet,
p *progress.Counter,
@ -49,24 +50,7 @@ func Repack(
return errors.New("repack step requires a backend connection limit of at least two")
}
return dstRepo.WithBlobUploader(ctx, func(ctx context.Context, uploader restic.BlobSaver) error {
return repack(ctx, repo, dstRepo, uploader, packs, keepBlobs, p, logf)
})
}
// CopyBlobs is a wrapper around repack(). The parameter 'uploader' is passed through
// from WithBlobUploader() to CopyBlobs() via cmd/restic/cmd_copy.copyTree().
func CopyBlobs(
ctx context.Context,
repo restic.Repository,
dstRepo restic.Repository,
uploader restic.BlobSaver,
packs restic.IDSet,
keepBlobs repackBlobSet,
p *progress.Counter,
logf LogFunc,
) error {
return repack(ctx, repo, dstRepo, uploader, packs, keepBlobs, p, logf)
return repack(ctx, repo, dstRepo, dstUploader, packs, keepBlobs, p, logf)
}
func repack(

View file

@ -150,7 +150,9 @@ func findPacksForBlobs(t *testing.T, repo restic.Repository, blobs restic.BlobSe
}
func repack(t *testing.T, repo restic.Repository, be backend.Backend, packs restic.IDSet, blobs restic.BlobSet) {
rtest.OK(t, repository.Repack(context.TODO(), repo, repo, packs, blobs, nil, nil))
rtest.OK(t, repo.WithBlobUploader(context.TODO(), func(ctx context.Context, uploader restic.BlobSaver) error {
return repository.CopyBlobs(ctx, repo, repo, uploader, packs, blobs, nil, nil)
}))
for id := range packs {
rtest.OK(t, be.Remove(context.TODO(), backend.Handle{Type: restic.PackFile, Name: id.String()}))
@ -263,7 +265,9 @@ func testRepackCopy(t *testing.T, version uint) {
_, keepBlobs := selectBlobs(t, random, repo, 0.2)
copyPacks := findPacksForBlobs(t, repo, keepBlobs)
rtest.OK(t, repository.Repack(context.TODO(), repoWrapped, dstRepoWrapped, copyPacks, keepBlobs, nil, nil))
rtest.OK(t, repoWrapped.WithBlobUploader(context.TODO(), func(ctx context.Context, uploader restic.BlobSaver) error {
return repository.CopyBlobs(ctx, repoWrapped, dstRepoWrapped, uploader, copyPacks, keepBlobs, nil, nil)
}))
rebuildAndReloadIndex(t, dstRepo)
for h := range keepBlobs {
@ -299,7 +303,9 @@ func testRepackWrongBlob(t *testing.T, version uint) {
_, keepBlobs := selectBlobs(t, random, repo, 0)
rewritePacks := findPacksForBlobs(t, repo, keepBlobs)
err := repository.Repack(context.TODO(), repo, repo, rewritePacks, keepBlobs, nil, nil)
err := repo.WithBlobUploader(context.TODO(), func(ctx context.Context, uploader restic.BlobSaver) error {
return repository.CopyBlobs(ctx, repo, repo, uploader, rewritePacks, keepBlobs, nil, nil)
})
if err == nil {
t.Fatal("expected repack to fail but got no error")
}
@ -346,7 +352,9 @@ func testRepackBlobFallback(t *testing.T, version uint) {
}))
// repack must fallback to valid copy
rtest.OK(t, repository.Repack(context.TODO(), repo, repo, rewritePacks, keepBlobs, nil, nil))
rtest.OK(t, repo.WithBlobUploader(context.TODO(), func(ctx context.Context, uploader restic.BlobSaver) error {
return repository.CopyBlobs(ctx, repo, repo, uploader, rewritePacks, keepBlobs, nil, nil)
}))
keepBlobs = restic.NewBlobSet(restic.BlobHandle{Type: restic.DataBlob, ID: id})
packs := findPacksForBlobs(t, repo, keepBlobs)