replace some uses of restic.Repository with finegrained interfaces

This commit is contained in:
Michael Eischer 2024-05-10 18:19:14 +02:00
parent 291c9677de
commit 223aa22cb0
7 changed files with 31 additions and 13 deletions

View file

@ -270,7 +270,7 @@ func (mi *MasterIndex) MergeFinalIndexes() error {
// Save saves all known indexes to index files, leaving out any // Save saves all known indexes to index files, leaving out any
// packs whose ID is contained in packBlacklist from finalized indexes. // packs whose ID is contained in packBlacklist from finalized indexes.
// It also removes the old index files and those listed in extraObsolete. // It also removes the old index files and those listed in extraObsolete.
func (mi *MasterIndex) Save(ctx context.Context, repo restic.Repository, excludePacks restic.IDSet, extraObsolete restic.IDs, opts restic.MasterIndexSaveOpts) error { func (mi *MasterIndex) Save(ctx context.Context, repo restic.SaverRemoverUnpacked, excludePacks restic.IDSet, extraObsolete restic.IDs, opts restic.MasterIndexSaveOpts) error {
p := opts.SaveProgress p := opts.SaveProgress
p.SetMax(uint64(len(mi.Packs(excludePacks)))) p.SetMax(uint64(len(mi.Packs(excludePacks))))

View file

@ -621,7 +621,7 @@ func (plan *PrunePlan) Execute(ctx context.Context, printer progress.Printer) (e
// deleteFiles deletes the given fileList of fileType in parallel // deleteFiles deletes the given fileList of fileType in parallel
// if ignoreError=true, it will print a warning if there was an error, else it will abort. // if ignoreError=true, it will print a warning if there was an error, else it will abort.
func deleteFiles(ctx context.Context, ignoreError bool, repo restic.Repository, fileList restic.IDSet, fileType restic.FileType, printer progress.Printer) error { func deleteFiles(ctx context.Context, ignoreError bool, repo restic.RemoverUnpacked, fileList restic.IDSet, fileType restic.FileType, printer progress.Printer) error {
bar := printer.NewCounter("files deleted") bar := printer.NewCounter("files deleted")
defer bar.Done() defer bar.Done()

View file

@ -35,7 +35,7 @@ type Lock struct {
UID uint32 `json:"uid,omitempty"` UID uint32 `json:"uid,omitempty"`
GID uint32 `json:"gid,omitempty"` GID uint32 `json:"gid,omitempty"`
repo Repository repo Unpacked
lockID *ID lockID *ID
} }
@ -86,14 +86,14 @@ var ErrRemovedLock = errors.New("lock file was removed in the meantime")
// NewLock returns a new, non-exclusive lock for the repository. If an // NewLock returns a new, non-exclusive lock for the repository. If an
// exclusive lock is already held by another process, it returns an error // exclusive lock is already held by another process, it returns an error
// that satisfies IsAlreadyLocked. // that satisfies IsAlreadyLocked.
func NewLock(ctx context.Context, repo Repository) (*Lock, error) { func NewLock(ctx context.Context, repo Unpacked) (*Lock, error) {
return newLock(ctx, repo, false) return newLock(ctx, repo, false)
} }
// NewExclusiveLock returns a new, exclusive lock for the repository. If // NewExclusiveLock returns a new, exclusive lock for the repository. If
// another lock (normal and exclusive) is already held by another process, // another lock (normal and exclusive) is already held by another process,
// it returns an error that satisfies IsAlreadyLocked. // it returns an error that satisfies IsAlreadyLocked.
func NewExclusiveLock(ctx context.Context, repo Repository) (*Lock, error) { func NewExclusiveLock(ctx context.Context, repo Unpacked) (*Lock, error) {
return newLock(ctx, repo, true) return newLock(ctx, repo, true)
} }
@ -105,7 +105,7 @@ func TestSetLockTimeout(t testing.TB, d time.Duration) {
waitBeforeLockCheck = d waitBeforeLockCheck = d
} }
func newLock(ctx context.Context, repo Repository, excl bool) (*Lock, error) { func newLock(ctx context.Context, repo Unpacked, excl bool) (*Lock, error) {
lock := &Lock{ lock := &Lock{
Time: time.Now(), Time: time.Now(),
PID: os.Getpid(), PID: os.Getpid(),
@ -389,7 +389,7 @@ func LoadLock(ctx context.Context, repo LoaderUnpacked, id ID) (*Lock, error) {
} }
// RemoveStaleLocks deletes all locks detected as stale from the repository. // RemoveStaleLocks deletes all locks detected as stale from the repository.
func RemoveStaleLocks(ctx context.Context, repo Repository) (uint, error) { func RemoveStaleLocks(ctx context.Context, repo Unpacked) (uint, error) {
var processed uint var processed uint
err := ForAllLocks(ctx, repo, nil, func(id ID, lock *Lock, err error) error { err := ForAllLocks(ctx, repo, nil, func(id ID, lock *Lock, err error) error {
if err != nil { if err != nil {
@ -412,7 +412,7 @@ func RemoveStaleLocks(ctx context.Context, repo Repository) (uint, error) {
} }
// RemoveAllLocks removes all locks forcefully. // RemoveAllLocks removes all locks forcefully.
func RemoveAllLocks(ctx context.Context, repo Repository) (uint, error) { func RemoveAllLocks(ctx context.Context, repo Unpacked) (uint, error) {
var processed uint32 var processed uint32
err := ParallelList(ctx, repo, LockFile, repo.Connections(), func(ctx context.Context, id ID, _ int64) error { err := ParallelList(ctx, repo, LockFile, repo.Connections(), func(ctx context.Context, id ID, _ int64) error {
err := repo.RemoveUnpacked(ctx, LockFile, id) err := repo.RemoveUnpacked(ctx, LockFile, id)

View file

@ -130,7 +130,7 @@ func createFakeLock(repo restic.SaverUnpacked, t time.Time, pid int) (restic.ID,
return restic.SaveJSONUnpacked(context.TODO(), repo, restic.LockFile, &newLock) return restic.SaveJSONUnpacked(context.TODO(), repo, restic.LockFile, &newLock)
} }
func removeLock(repo restic.Repository, id restic.ID) error { func removeLock(repo restic.RemoverUnpacked, id restic.ID) error {
return repo.RemoveUnpacked(context.TODO(), restic.LockFile, id) return repo.RemoveUnpacked(context.TODO(), restic.LockFile, id)
} }
@ -190,7 +190,7 @@ func TestLockStale(t *testing.T) {
} }
} }
func lockExists(repo restic.Repository, t testing.TB, lockID restic.ID) bool { func lockExists(repo restic.Lister, t testing.TB, lockID restic.ID) bool {
var exists bool var exists bool
rtest.OK(t, repo.List(context.TODO(), restic.LockFile, func(id restic.ID, size int64) error { rtest.OK(t, repo.List(context.TODO(), restic.LockFile, func(id restic.ID, size int64) error {
if id == lockID { if id == lockID {

View file

@ -54,7 +54,7 @@ func ParallelList(ctx context.Context, r Lister, t FileType, parallelism uint, f
// ParallelRemove deletes the given fileList of fileType in parallel // ParallelRemove deletes the given fileList of fileType in parallel
// if callback returns an error, then it will abort. // if callback returns an error, then it will abort.
func ParallelRemove(ctx context.Context, repo Repository, fileList IDSet, fileType FileType, report func(id ID, err error) error, bar *progress.Counter) error { func ParallelRemove(ctx context.Context, repo RemoverUnpacked, fileList IDSet, fileType FileType, report func(id ID, err error) error, bar *progress.Counter) error {
fileChan := make(chan ID) fileChan := make(chan ID)
wg, ctx := errgroup.WithContext(ctx) wg, ctx := errgroup.WithContext(ctx)
wg.Go(func() error { wg.Go(func() error {

View file

@ -89,6 +89,18 @@ type SaverUnpacked interface {
SaveUnpacked(context.Context, FileType, []byte) (ID, error) SaveUnpacked(context.Context, FileType, []byte) (ID, error)
} }
// RemoverUnpacked allows removing an unpacked blob
type RemoverUnpacked interface {
// Connections returns the maximum number of concurrent backend operations
Connections() uint
RemoveUnpacked(ctx context.Context, t FileType, id ID) error
}
type SaverRemoverUnpacked interface {
SaverUnpacked
RemoverUnpacked
}
type PackBlobs struct { type PackBlobs struct {
PackID ID PackID ID
Blobs []Blob Blobs []Blob
@ -111,7 +123,7 @@ type MasterIndex interface {
Each(ctx context.Context, fn func(PackedBlob)) error Each(ctx context.Context, fn func(PackedBlob)) error
ListPacks(ctx context.Context, packs IDSet) <-chan PackBlobs ListPacks(ctx context.Context, packs IDSet) <-chan PackBlobs
Save(ctx context.Context, repo Repository, excludePacks IDSet, extraObsolete IDs, opts MasterIndexSaveOpts) error Save(ctx context.Context, repo SaverRemoverUnpacked, excludePacks IDSet, extraObsolete IDs, opts MasterIndexSaveOpts) error
} }
// Lister allows listing files in a backend. // Lister allows listing files in a backend.
@ -123,3 +135,9 @@ type ListerLoaderUnpacked interface {
Lister Lister
LoaderUnpacked LoaderUnpacked
} }
type Unpacked interface {
ListerLoaderUnpacked
SaverUnpacked
RemoverUnpacked
}

View file

@ -190,7 +190,7 @@ func ParseDurationOrPanic(s string) Duration {
// TestLoadAllSnapshots returns a list of all snapshots in the repo. // TestLoadAllSnapshots returns a list of all snapshots in the repo.
// If a snapshot ID is in excludeIDs, it will not be included in the result. // If a snapshot ID is in excludeIDs, it will not be included in the result.
func TestLoadAllSnapshots(ctx context.Context, repo Repository, excludeIDs IDSet) (snapshots Snapshots, err error) { func TestLoadAllSnapshots(ctx context.Context, repo ListerLoaderUnpacked, excludeIDs IDSet) (snapshots Snapshots, err error) {
err = ForAllSnapshots(ctx, repo, repo, excludeIDs, func(id ID, sn *Snapshot, err error) error { err = ForAllSnapshots(ctx, repo, repo, excludeIDs, func(id ID, sn *Snapshot, err error) error {
if err != nil { if err != nil {
return err return err