Add 'fsck' command

This commit is contained in:
Alexander Neumann 2014-11-30 22:35:42 +01:00
parent 3325fa07ea
commit bb8c52a974
1 changed files with 114 additions and 67 deletions

View File

@ -1,76 +1,123 @@
package main package main
import "github.com/fd0/khepri/backend" import (
"errors"
"fmt"
// func fsck_tree(be backend.Server, id backend.ID) (bool, error) { "github.com/fd0/khepri"
// log.Printf(" checking dir %s", id) "github.com/fd0/khepri/backend"
)
// buf, err := be.GetBlob(id) func init() {
// if err != nil { commands["fsck"] = commandFsck
// return false, err }
// }
// tree := &khepri.Tree{} func fsckFile(ch *khepri.ContentHandler, IDs []backend.ID) error {
// err = json.Unmarshal(buf, tree) for _, id := range IDs {
// if err != nil { debug("checking data blob %v\n", id)
// return false, err
// }
// if !id.Equal(backend.IDFromData(buf)) { // load content
// return false, nil _, err := ch.Load(backend.Data, id)
// } if err != nil {
return err
// return true, nil }
// } }
// func fsck_snapshot(be backend.Server, id backend.ID) (bool, error) { return nil
// log.Printf("checking snapshot %s", id) }
// sn, err := khepri.LoadSnapshot(be, id) func fsckTree(ch *khepri.ContentHandler, id backend.ID) error {
// if err != nil { debug("checking tree %v\n", id)
// return false, err
// } tree, err := khepri.LoadTree(ch, id)
if err != nil {
// return fsck_tree(be, sn.Content) return err
// } }
func commandFsck(be backend.Server, args []string) error { for i, node := range tree {
// var snapshots backend.IDs if node.Name == "" {
// var err error return fmt.Errorf("node %v of tree %v has no name", i, id)
}
// if len(args) != 0 {
// snapshots = make(backend.IDs, 0, len(args)) if node.Type == "" {
return fmt.Errorf("node %q of tree %v has no type", node.Name, id)
// for _, arg := range args { }
// id, err := backend.ParseID(arg)
// if err != nil { switch node.Type {
// log.Fatal(err) case "file":
// } if node.Content == nil {
return fmt.Errorf("file node %q of tree %v has no content", node.Name, id)
// snapshots = append(snapshots, id) }
// }
// } else { err := fsckFile(ch, node.Content)
// snapshots, err = be.ListRefs() if err != nil {
return err
// if err != nil { }
// log.Fatalf("error reading list of snapshot IDs: %v", err) case "dir":
// } if node.Subtree == nil {
// } return fmt.Errorf("dir node %q of tree %v has no subtree", node.Name, id)
}
// log.Printf("checking %d snapshots", len(snapshots))
err := fsckTree(ch, node.Subtree)
// for _, id := range snapshots { if err != nil {
// ok, err := fsck_snapshot(be, id) return err
}
// if err != nil { }
// log.Printf("error checking snapshot %s: %v", id, err) }
// continue
// } return nil
}
// if !ok {
// log.Printf("snapshot %s failed", id) func fsck_snapshot(be backend.Server, key *khepri.Key, id backend.ID) error {
// } debug("checking snapshot %v\n", id)
// }
ch, err := khepri.NewContentHandler(be, key)
if err != nil {
return err
}
sn, err := ch.LoadSnapshot(id)
if err != nil {
return err
}
if sn.Content == nil {
return fmt.Errorf("snapshot %v has no content", sn.ID)
}
if sn.Map == nil {
return fmt.Errorf("snapshot %v has no map", sn.ID)
}
return fsckTree(ch, sn.Content)
}
func commandFsck(be backend.Server, key *khepri.Key, args []string) error {
if len(args) == 0 {
return errors.New("usage: fsck [all|snapshot-id]")
}
if len(args) == 1 && args[0] != "all" {
snapshotID, err := backend.FindSnapshot(be, args[0])
if err != nil {
return fmt.Errorf("invalid id %q: %v", args[1], err)
}
return fsck_snapshot(be, key, snapshotID)
}
list, err := be.List(backend.Snapshot)
if err != nil {
return err
}
for _, snapshotID := range list {
err := fsck_snapshot(be, key, snapshotID)
if err != nil {
return err
}
}
return nil return nil
} }