From 81d8bc4ade9d256b9a92b18dd5f18fac3586fecb Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sun, 23 Nov 2025 16:06:29 +0100 Subject: [PATCH] repository: replace CopyBlobs with Repack implementation --- cmd/restic/cmd_copy.go | 2 -- internal/repository/prune.go | 4 +++- internal/repository/repack.go | 26 +++++--------------------- internal/repository/repack_test.go | 16 ++++++++++++---- 4 files changed, 20 insertions(+), 28 deletions(-) diff --git a/cmd/restic/cmd_copy.go b/cmd/restic/cmd_copy.go index f9a75108b..446abb6cb 100644 --- a/cmd/restic/cmd_copy.go +++ b/cmd/restic/cmd_copy.go @@ -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) } diff --git a/internal/repository/prune.go b/internal/repository/prune.go index 250ab9846..cc36c7a96 100644 --- a/internal/repository/prune.go +++ b/internal/repository/prune.go @@ -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) } diff --git a/internal/repository/repack.go b/internal/repository/repack.go index 7ebc2b2ac..ca0a8a48b 100644 --- a/internal/repository/repack.go +++ b/internal/repository/repack.go @@ -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( diff --git a/internal/repository/repack_test.go b/internal/repository/repack_test.go index 4d285681f..bedacaa7e 100644 --- a/internal/repository/repack_test.go +++ b/internal/repository/repack_test.go @@ -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)