mirror of
https://github.com/octoleo/restic.git
synced 2024-11-24 21:57:41 +00:00
Merge pull request #4641 from MichaelEischer/reduce-restic-repository-usage
Misc cleanups
This commit is contained in:
commit
c90f24a06c
@ -411,7 +411,7 @@ func collectTargets(opts BackupOptions, args []string) (targets []string, err er
|
||||
|
||||
// parent returns the ID of the parent snapshot. If there is none, nil is
|
||||
// returned.
|
||||
func findParentSnapshot(ctx context.Context, repo restic.Repository, opts BackupOptions, targets []string, timeStampLimit time.Time) (*restic.Snapshot, error) {
|
||||
func findParentSnapshot(ctx context.Context, repo restic.ListerLoaderUnpacked, opts BackupOptions, targets []string, timeStampLimit time.Time) (*restic.Snapshot, error) {
|
||||
if opts.Force {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ func printPacks(ctx context.Context, repo *repository.Repository, wr io.Writer)
|
||||
})
|
||||
}
|
||||
|
||||
func dumpIndexes(ctx context.Context, repo restic.Repository, wr io.Writer) error {
|
||||
func dumpIndexes(ctx context.Context, repo restic.ListerLoaderUnpacked, wr io.Writer) error {
|
||||
return index.ForAllIndexes(ctx, repo, repo, func(id restic.ID, idx *index.Index, oldFormat bool, err error) error {
|
||||
Printf("index_id: %v\n", id)
|
||||
if err != nil {
|
||||
|
@ -61,7 +61,7 @@ func init() {
|
||||
f.BoolVar(&diffOptions.ShowMetadata, "metadata", false, "print changes in metadata")
|
||||
}
|
||||
|
||||
func loadSnapshot(ctx context.Context, be restic.Lister, repo restic.Repository, desc string) (*restic.Snapshot, string, error) {
|
||||
func loadSnapshot(ctx context.Context, be restic.Lister, repo restic.LoaderUnpacked, desc string) (*restic.Snapshot, string, error) {
|
||||
sn, subfolder, err := restic.FindSnapshot(ctx, be, repo, desc)
|
||||
if err != nil {
|
||||
return nil, "", errors.Fatal(err.Error())
|
||||
@ -71,7 +71,7 @@ func loadSnapshot(ctx context.Context, be restic.Lister, repo restic.Repository,
|
||||
|
||||
// Comparer collects all things needed to compare two snapshots.
|
||||
type Comparer struct {
|
||||
repo restic.Repository
|
||||
repo restic.BlobLoader
|
||||
opts DiffOptions
|
||||
printChange func(change *Change)
|
||||
}
|
||||
@ -147,7 +147,7 @@ type DiffStatsContainer struct {
|
||||
}
|
||||
|
||||
// updateBlobs updates the blob counters in the stats struct.
|
||||
func updateBlobs(repo restic.Repository, blobs restic.BlobSet, stats *DiffStat) {
|
||||
func updateBlobs(repo restic.Loader, blobs restic.BlobSet, stats *DiffStat) {
|
||||
for h := range blobs {
|
||||
switch h.Type {
|
||||
case restic.DataBlob:
|
||||
|
@ -67,7 +67,7 @@ func splitPath(p string) []string {
|
||||
return append(s, f)
|
||||
}
|
||||
|
||||
func printFromTree(ctx context.Context, tree *restic.Tree, repo restic.Repository, prefix string, pathComponents []string, d *dump.Dumper) error {
|
||||
func printFromTree(ctx context.Context, tree *restic.Tree, repo restic.BlobLoader, prefix string, pathComponents []string, d *dump.Dumper) error {
|
||||
// If we print / we need to assume that there are multiple nodes at that
|
||||
// level in the tree.
|
||||
if pathComponents[0] == "" {
|
||||
|
@ -158,7 +158,7 @@ func runRecover(ctx context.Context, gopts GlobalOptions) error {
|
||||
|
||||
}
|
||||
|
||||
func createSnapshot(ctx context.Context, name, hostname string, tags []string, repo restic.Repository, tree *restic.ID) error {
|
||||
func createSnapshot(ctx context.Context, name, hostname string, tags []string, repo restic.SaverUnpacked, tree *restic.ID) error {
|
||||
sn, err := restic.NewSnapshot([]string{name}, tags, hostname, time.Now())
|
||||
if err != nil {
|
||||
return errors.Fatalf("unable to save snapshot: %v", err)
|
||||
|
@ -189,7 +189,7 @@ func runStats(ctx context.Context, opts StatsOptions, gopts GlobalOptions, args
|
||||
return nil
|
||||
}
|
||||
|
||||
func statsWalkSnapshot(ctx context.Context, snapshot *restic.Snapshot, repo restic.Repository, opts StatsOptions, stats *statsContainer) error {
|
||||
func statsWalkSnapshot(ctx context.Context, snapshot *restic.Snapshot, repo restic.Loader, opts StatsOptions, stats *statsContainer) error {
|
||||
if snapshot.Tree == nil {
|
||||
return fmt.Errorf("snapshot %s has nil tree", snapshot.ID().Str())
|
||||
}
|
||||
@ -211,7 +211,7 @@ func statsWalkSnapshot(ctx context.Context, snapshot *restic.Snapshot, repo rest
|
||||
return nil
|
||||
}
|
||||
|
||||
func statsWalkTree(repo restic.Repository, opts StatsOptions, stats *statsContainer, hardLinkIndex *restorer.HardlinkIndex[struct{}]) walker.WalkFunc {
|
||||
func statsWalkTree(repo restic.Loader, opts StatsOptions, stats *statsContainer, hardLinkIndex *restorer.HardlinkIndex[struct{}]) walker.WalkFunc {
|
||||
return func(parentTreeID restic.ID, npath string, node *restic.Node, nodeErr error) error {
|
||||
if nodeErr != nil {
|
||||
return nodeErr
|
||||
@ -363,7 +363,7 @@ func statsDebug(ctx context.Context, repo restic.Repository) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func statsDebugFileType(ctx context.Context, repo restic.Repository, tpe restic.FileType) (*sizeHistogram, error) {
|
||||
func statsDebugFileType(ctx context.Context, repo restic.Lister, tpe restic.FileType) (*sizeHistogram, error) {
|
||||
hist := newSizeHistogram(2 * repository.MaxPackSize)
|
||||
err := repo.List(ctx, tpe, func(id restic.ID, size int64) error {
|
||||
hist.Add(uint64(size))
|
||||
|
@ -209,7 +209,7 @@ func TestEnsureFiles(t testing.TB, target string, dir TestDir) {
|
||||
}
|
||||
|
||||
// TestEnsureFileContent checks if the file in the repo is the same as file.
|
||||
func TestEnsureFileContent(ctx context.Context, t testing.TB, repo restic.Repository, filename string, node *restic.Node, file TestFile) {
|
||||
func TestEnsureFileContent(ctx context.Context, t testing.TB, repo restic.BlobLoader, filename string, node *restic.Node, file TestFile) {
|
||||
if int(node.Size) != len(file.Content) {
|
||||
t.Fatalf("%v: wrong node size: want %d, got %d", filename, node.Size, len(file.Content))
|
||||
return
|
||||
@ -237,7 +237,7 @@ func TestEnsureFileContent(ctx context.Context, t testing.TB, repo restic.Reposi
|
||||
|
||||
// TestEnsureTree checks that the tree ID in the repo matches dir. On Windows,
|
||||
// Symlinks are ignored.
|
||||
func TestEnsureTree(ctx context.Context, t testing.TB, prefix string, repo restic.Repository, treeID restic.ID, dir TestDir) {
|
||||
func TestEnsureTree(ctx context.Context, t testing.TB, prefix string, repo restic.BlobLoader, treeID restic.ID, dir TestDir) {
|
||||
t.Helper()
|
||||
|
||||
tree, err := restic.LoadTree(ctx, repo, treeID)
|
||||
|
@ -14,7 +14,6 @@ import (
|
||||
"github.com/minio/sha256-simd"
|
||||
"github.com/restic/restic/internal/backend"
|
||||
"github.com/restic/restic/internal/backend/s3"
|
||||
"github.com/restic/restic/internal/cache"
|
||||
"github.com/restic/restic/internal/debug"
|
||||
"github.com/restic/restic/internal/errors"
|
||||
"github.com/restic/restic/internal/hashing"
|
||||
@ -241,17 +240,8 @@ func IsOrphanedPack(err error) bool {
|
||||
}
|
||||
|
||||
func isS3Legacy(b backend.Backend) bool {
|
||||
// unwrap cache
|
||||
if be, ok := b.(*cache.Backend); ok {
|
||||
b = be.Backend
|
||||
}
|
||||
|
||||
be, ok := b.(*s3.Backend)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return be.Layout.Name() == "s3legacy"
|
||||
be := backend.AsBackend[*s3.Backend](b)
|
||||
return be != nil && be.Layout.Name() == "s3legacy"
|
||||
}
|
||||
|
||||
// Packs checks that all packs referenced in the index are still available and
|
||||
@ -362,7 +352,7 @@ func (c *Checker) checkTreeWorker(ctx context.Context, trees <-chan restic.TreeI
|
||||
}
|
||||
}
|
||||
|
||||
func loadSnapshotTreeIDs(ctx context.Context, lister restic.Lister, repo restic.Repository) (ids restic.IDs, errs []error) {
|
||||
func loadSnapshotTreeIDs(ctx context.Context, lister restic.Lister, repo restic.LoaderUnpacked) (ids restic.IDs, errs []error) {
|
||||
err := restic.ForAllSnapshots(ctx, lister, repo, nil, func(id restic.ID, sn *restic.Snapshot, err error) error {
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
|
@ -16,11 +16,11 @@ import (
|
||||
type Dumper struct {
|
||||
cache *bloblru.Cache
|
||||
format string
|
||||
repo restic.Repository
|
||||
repo restic.BlobLoader
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
func New(format string, repo restic.Repository, w io.Writer) *Dumper {
|
||||
func New(format string, repo restic.BlobLoader, w io.Writer) *Dumper {
|
||||
return &Dumper{
|
||||
cache: bloblru.New(64 << 20),
|
||||
format: format,
|
||||
@ -47,7 +47,7 @@ func (d *Dumper) DumpTree(ctx context.Context, tree *restic.Tree, rootPath strin
|
||||
}
|
||||
}
|
||||
|
||||
func sendTrees(ctx context.Context, repo restic.Repository, tree *restic.Tree, rootPath string, ch chan *restic.Node) {
|
||||
func sendTrees(ctx context.Context, repo restic.BlobLoader, tree *restic.Tree, rootPath string, ch chan *restic.Node) {
|
||||
defer close(ch)
|
||||
|
||||
for _, root := range tree.Nodes {
|
||||
@ -58,7 +58,7 @@ func sendTrees(ctx context.Context, repo restic.Repository, tree *restic.Tree, r
|
||||
}
|
||||
}
|
||||
|
||||
func sendNodes(ctx context.Context, repo restic.Repository, root *restic.Node, ch chan *restic.Node) error {
|
||||
func sendNodes(ctx context.Context, repo restic.BlobLoader, root *restic.Node, ch chan *restic.Node) error {
|
||||
select {
|
||||
case ch <- root:
|
||||
case <-ctx.Done():
|
||||
|
@ -58,7 +58,7 @@ func unwrapCtxCanceled(err error) error {
|
||||
|
||||
// replaceSpecialNodes replaces nodes with name "." and "/" by their contents.
|
||||
// Otherwise, the node is returned.
|
||||
func replaceSpecialNodes(ctx context.Context, repo restic.Repository, node *restic.Node) ([]*restic.Node, error) {
|
||||
func replaceSpecialNodes(ctx context.Context, repo restic.BlobLoader, node *restic.Node) ([]*restic.Node, error) {
|
||||
if node.Type != "dir" || node.Subtree == nil {
|
||||
return []*restic.Node{node}, nil
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ func testRead(t testing.TB, f fs.Handle, offset, length int, data []byte) {
|
||||
rtest.OK(t, fr.Read(ctx, req, resp))
|
||||
}
|
||||
|
||||
func firstSnapshotID(t testing.TB, repo restic.Repository) (first restic.ID) {
|
||||
func firstSnapshotID(t testing.TB, repo restic.Lister) (first restic.ID) {
|
||||
err := repo.List(context.TODO(), restic.SnapshotFile, func(id restic.ID, size int64) error {
|
||||
if first.IsNull() {
|
||||
first = id
|
||||
@ -52,14 +52,14 @@ func firstSnapshotID(t testing.TB, repo restic.Repository) (first restic.ID) {
|
||||
return first
|
||||
}
|
||||
|
||||
func loadFirstSnapshot(t testing.TB, repo restic.Repository) *restic.Snapshot {
|
||||
func loadFirstSnapshot(t testing.TB, repo restic.ListerLoaderUnpacked) *restic.Snapshot {
|
||||
id := firstSnapshotID(t, repo)
|
||||
sn, err := restic.LoadSnapshot(context.TODO(), repo, id)
|
||||
rtest.OK(t, err)
|
||||
return sn
|
||||
}
|
||||
|
||||
func loadTree(t testing.TB, repo restic.Repository, id restic.ID) *restic.Tree {
|
||||
func loadTree(t testing.TB, repo restic.Loader, id restic.ID) *restic.Tree {
|
||||
tree, err := restic.LoadTree(context.TODO(), repo, id)
|
||||
rtest.OK(t, err)
|
||||
return tree
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
// ForAllIndexes loads all index files in parallel and calls the given callback.
|
||||
// It is guaranteed that the function is not run concurrently. If the callback
|
||||
// returns an error, this function is cancelled and also returns that error.
|
||||
func ForAllIndexes(ctx context.Context, lister restic.Lister, repo restic.Repository,
|
||||
func ForAllIndexes(ctx context.Context, lister restic.Lister, repo restic.ListerLoaderUnpacked,
|
||||
fn func(id restic.ID, index *Index, oldFormat bool, err error) error) error {
|
||||
|
||||
// decoding an index can take quite some time such that this can be both CPU- or IO-bound
|
||||
|
@ -120,7 +120,7 @@ func selectBlobs(t *testing.T, repo restic.Repository, p float32) (list1, list2
|
||||
return list1, list2
|
||||
}
|
||||
|
||||
func listPacks(t *testing.T, repo restic.Repository) restic.IDSet {
|
||||
func listPacks(t *testing.T, repo restic.Lister) restic.IDSet {
|
||||
list := restic.NewIDSet()
|
||||
err := repo.List(context.TODO(), restic.PackFile, func(id restic.ID, size int64) error {
|
||||
list.Insert(id)
|
||||
|
@ -229,7 +229,7 @@ func TestRepositoryLoadIndex(t *testing.T) {
|
||||
}
|
||||
|
||||
// loadIndex loads the index id from backend and returns it.
|
||||
func loadIndex(ctx context.Context, repo restic.Repository, id restic.ID) (*index.Index, error) {
|
||||
func loadIndex(ctx context.Context, repo restic.LoaderUnpacked, id restic.ID) (*index.Index, error) {
|
||||
buf, err := repo.LoadUnpacked(ctx, restic.IndexFile, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -341,8 +341,8 @@ func (l *Lock) checkExistence(ctx context.Context) (bool, error) {
|
||||
|
||||
exists := false
|
||||
|
||||
err := l.repo.Backend().List(ctx, LockFile, func(fi backend.FileInfo) error {
|
||||
if fi.Name == l.lockID.String() {
|
||||
err := l.repo.List(ctx, LockFile, func(id ID, size int64) error {
|
||||
if id.Equal(*l.lockID) {
|
||||
exists = true
|
||||
}
|
||||
return nil
|
||||
@ -379,7 +379,7 @@ func init() {
|
||||
}
|
||||
|
||||
// LoadLock loads and unserializes a lock from a repository.
|
||||
func LoadLock(ctx context.Context, repo Repository, id ID) (*Lock, error) {
|
||||
func LoadLock(ctx context.Context, repo LoaderUnpacked, id ID) (*Lock, error) {
|
||||
lock := &Lock{}
|
||||
if err := LoadJSONUnpacked(ctx, repo, LockFile, id, lock); err != nil {
|
||||
return nil, err
|
||||
@ -429,7 +429,7 @@ func RemoveAllLocks(ctx context.Context, repo Repository) (uint, error) {
|
||||
// It is guaranteed that the function is not run concurrently. If the
|
||||
// callback returns an error, this function is cancelled and also returns that error.
|
||||
// If a lock ID is passed via excludeID, it will be ignored.
|
||||
func ForAllLocks(ctx context.Context, repo Repository, excludeIDs IDSet, fn func(ID, *Lock, error) error) error {
|
||||
func ForAllLocks(ctx context.Context, repo ListerLoaderUnpacked, excludeIDs IDSet, fn func(ID, *Lock, error) error) error {
|
||||
var m sync.Mutex
|
||||
|
||||
// For locks decoding is nearly for free, thus just assume were only limited by IO
|
||||
|
@ -120,7 +120,7 @@ func TestExclusiveLockOnLockedRepo(t *testing.T) {
|
||||
rtest.OK(t, elock.Unlock())
|
||||
}
|
||||
|
||||
func createFakeLock(repo restic.Repository, t time.Time, pid int) (restic.ID, error) {
|
||||
func createFakeLock(repo restic.SaverUnpacked, t time.Time, pid int) (restic.ID, error) {
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
return restic.ID{}, err
|
||||
@ -254,7 +254,7 @@ func TestRemoveAllLocks(t *testing.T) {
|
||||
3, processed)
|
||||
}
|
||||
|
||||
func checkSingleLock(t *testing.T, repo restic.Repository) restic.ID {
|
||||
func checkSingleLock(t *testing.T, repo restic.Lister) restic.ID {
|
||||
t.Helper()
|
||||
var lockID *restic.ID
|
||||
err := repo.List(context.TODO(), restic.LockFile, func(id restic.ID, size int64) error {
|
||||
|
@ -142,7 +142,7 @@ func (node Node) GetExtendedAttribute(a string) []byte {
|
||||
}
|
||||
|
||||
// CreateAt creates the node at the given path but does NOT restore node meta data.
|
||||
func (node *Node) CreateAt(ctx context.Context, path string, repo Repository) error {
|
||||
func (node *Node) CreateAt(ctx context.Context, path string, repo BlobLoader) error {
|
||||
debug.Log("create node %v at %v", node.Name, path)
|
||||
|
||||
switch node.Type {
|
||||
@ -264,7 +264,7 @@ func (node Node) createDirAt(path string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (node Node) createFileAt(ctx context.Context, path string, repo Repository) error {
|
||||
func (node Node) createFileAt(ctx context.Context, path string, repo BlobLoader) error {
|
||||
f, err := fs.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
@ -284,7 +284,7 @@ func (node Node) createFileAt(ctx context.Context, path string, repo Repository)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (node Node) writeNodeContent(ctx context.Context, repo Repository, f *os.File) error {
|
||||
func (node Node) writeNodeContent(ctx context.Context, repo BlobLoader, f *os.File) error {
|
||||
var buf []byte
|
||||
for _, id := range node.Content {
|
||||
buf, err := repo.LoadBlob(ctx, DataBlob, id, buf)
|
||||
|
@ -113,3 +113,8 @@ type MasterIndex interface {
|
||||
type Lister interface {
|
||||
List(ctx context.Context, t FileType, fn func(ID, int64) error) error
|
||||
}
|
||||
|
||||
type ListerLoaderUnpacked interface {
|
||||
Lister
|
||||
LoaderUnpacked
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ type Dir struct {
|
||||
ModTime time.Time
|
||||
}
|
||||
|
||||
func saveFile(t testing.TB, repo restic.Repository, node File) restic.ID {
|
||||
func saveFile(t testing.TB, repo restic.BlobSaver, node File) restic.ID {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
@ -52,7 +52,7 @@ func saveFile(t testing.TB, repo restic.Repository, node File) restic.ID {
|
||||
return id
|
||||
}
|
||||
|
||||
func saveDir(t testing.TB, repo restic.Repository, nodes map[string]Node, inode uint64) restic.ID {
|
||||
func saveDir(t testing.TB, repo restic.BlobSaver, nodes map[string]Node, inode uint64) restic.ID {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user