forked from TrueCloudLab/restic
Use new Index implementation for rebuild-index
This commit is contained in:
parent
1d64a1dcbb
commit
9b776dc7ab
3 changed files with 64 additions and 70 deletions
|
@ -1,7 +1,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"restic/repository"
|
||||
"restic"
|
||||
"restic/index"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
@ -34,5 +35,47 @@ func runRebuildIndex(gopts GlobalOptions) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return repository.RebuildIndex(repo)
|
||||
done := make(chan struct{})
|
||||
defer close(done)
|
||||
|
||||
Verbosef("counting files in repo\n")
|
||||
|
||||
var packs uint64
|
||||
for _ = range repo.List(restic.DataFile, done) {
|
||||
packs++
|
||||
}
|
||||
|
||||
bar := newProgressMax(!gopts.Quiet, packs, "packs")
|
||||
idx, err := index.New(repo, bar)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Verbosef("listing old index files\n")
|
||||
var supersedes restic.IDs
|
||||
for id := range repo.List(restic.IndexFile, done) {
|
||||
supersedes = append(supersedes, id)
|
||||
}
|
||||
|
||||
id, err := idx.Save(repo, supersedes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Verbosef("saved new index as %v\n", id.Str())
|
||||
|
||||
Verbosef("remove %d old index files\n", len(supersedes))
|
||||
|
||||
for _, id := range supersedes {
|
||||
err := repo.Backend().Remove(restic.Handle{
|
||||
Type: restic.IndexFile,
|
||||
Name: id.String(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
Warnf("error deleting old index %v: %v\n", id.Str(), err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"restic"
|
||||
"restic/debug"
|
||||
"restic/list"
|
||||
"restic/worker"
|
||||
)
|
||||
|
||||
// RebuildIndex lists all packs in the repo, writes a new index and removes all
|
||||
// old indexes. This operation should only be done with an exclusive lock in
|
||||
// place.
|
||||
func RebuildIndex(repo restic.Repository) error {
|
||||
debug.Log("start rebuilding index")
|
||||
|
||||
done := make(chan struct{})
|
||||
defer close(done)
|
||||
|
||||
ch := make(chan worker.Job)
|
||||
go list.AllPacks(repo, ch, done)
|
||||
|
||||
idx := NewIndex()
|
||||
for job := range ch {
|
||||
id := job.Data.(restic.ID)
|
||||
|
||||
if job.Error != nil {
|
||||
fmt.Fprintf(os.Stderr, "error for pack %v: %v\n", id, job.Error)
|
||||
continue
|
||||
}
|
||||
|
||||
res := job.Result.(list.Result)
|
||||
|
||||
for _, entry := range res.Entries() {
|
||||
pb := restic.PackedBlob{
|
||||
Blob: entry,
|
||||
PackID: res.PackID(),
|
||||
}
|
||||
idx.Store(pb)
|
||||
}
|
||||
}
|
||||
|
||||
oldIndexes := restic.NewIDSet()
|
||||
for id := range repo.List(restic.IndexFile, done) {
|
||||
idx.AddToSupersedes(id)
|
||||
oldIndexes.Insert(id)
|
||||
}
|
||||
|
||||
id, err := SaveIndex(repo, idx)
|
||||
if err != nil {
|
||||
debug.Log("error saving index: %v", err)
|
||||
return err
|
||||
}
|
||||
debug.Log("new index saved as %v", id.Str())
|
||||
|
||||
for indexID := range oldIndexes {
|
||||
h := restic.Handle{Type: restic.IndexFile, Name: indexID.String()}
|
||||
err := repo.Backend().Remove(h)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "unable to remove index %v: %v\n", indexID.Str(), err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -4,6 +4,7 @@ import (
|
|||
"io"
|
||||
"math/rand"
|
||||
"restic"
|
||||
"restic/index"
|
||||
"restic/repository"
|
||||
"testing"
|
||||
)
|
||||
|
@ -144,8 +145,24 @@ func saveIndex(t *testing.T, repo restic.Repository) {
|
|||
}
|
||||
|
||||
func rebuildIndex(t *testing.T, repo restic.Repository) {
|
||||
if err := repository.RebuildIndex(repo); err != nil {
|
||||
t.Fatalf("error rebuilding index: %v", err)
|
||||
idx, err := index.New(repo, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for id := range repo.List(restic.IndexFile, nil) {
|
||||
err = repo.Backend().Remove(restic.Handle{
|
||||
Type: restic.IndexFile,
|
||||
Name: id.String(),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
_, err = idx.Save(repo, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue