mirror of
https://github.com/restic/restic.git
synced 2025-01-03 05:35:43 +00:00
Add command 'fsck'
This commit is contained in:
parent
b923a2065a
commit
ad8125d83c
3 changed files with 89 additions and 0 deletions
86
cmd/khepri/cmd_fsck.go
Normal file
86
cmd/khepri/cmd_fsck.go
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/json"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/fd0/khepri"
|
||||||
|
)
|
||||||
|
|
||||||
|
func fsck_tree(repo *khepri.Repository, id khepri.ID) (bool, error) {
|
||||||
|
log.Printf(" checking dir %s", id)
|
||||||
|
|
||||||
|
rd, err := repo.Get(khepri.TYPE_BLOB, id)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
hr := khepri.NewHashingReader(rd, sha256.New)
|
||||||
|
dec := json.NewDecoder(hr)
|
||||||
|
|
||||||
|
tree := &khepri.Tree{}
|
||||||
|
err = dec.Decode(tree)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !id.Equal(hr.Hash()) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fsck_snapshot(repo *khepri.Repository, id khepri.ID) (bool, error) {
|
||||||
|
log.Printf("checking snapshot %s", id)
|
||||||
|
|
||||||
|
sn, err := khepri.LoadSnapshot(repo, id)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fsck_tree(repo, sn.TreeID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func commandFsck(repo *khepri.Repository, args []string) error {
|
||||||
|
var snapshots khepri.IDs
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if len(args) != 0 {
|
||||||
|
snapshots = make(khepri.IDs, 0, len(args))
|
||||||
|
|
||||||
|
for _, arg := range args {
|
||||||
|
id, err := khepri.ParseID(arg)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshots = append(snapshots, id)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
snapshots, err = repo.List(khepri.TYPE_REF)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("error reading list of snapshot IDs: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("checking %d snapshots", len(snapshots))
|
||||||
|
|
||||||
|
for _, id := range snapshots {
|
||||||
|
ok, err := fsck_snapshot(repo, id)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error checking snapshot %s: %v", id, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
log.Printf("snapshot %s failed", id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -32,6 +32,7 @@ func init() {
|
||||||
commands["restore"] = commandRestore
|
commands["restore"] = commandRestore
|
||||||
commands["list"] = commandList
|
commands["list"] = commandList
|
||||||
commands["snapshots"] = commandSnapshots
|
commands["snapshots"] = commandSnapshots
|
||||||
|
commands["fsck"] = commandFsck
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -68,6 +68,8 @@ func LoadSnapshot(repo *Repository, id ID) (*Snapshot, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: maybe inject a hashing reader here and test if the given id is correct
|
||||||
|
|
||||||
dec := json.NewDecoder(rd)
|
dec := json.NewDecoder(rd)
|
||||||
sn := &Snapshot{}
|
sn := &Snapshot{}
|
||||||
err = dec.Decode(sn)
|
err = dec.Decode(sn)
|
||||||
|
|
Loading…
Reference in a new issue