Add decrypt, refactor

This commit is contained in:
Alexander Neumann committed 2014-10-03 21:44:55 +02:00
1 parent 83ea81d8c3
commit 30ab03b7b7
37 files changed
+2572 -1046

No files matched your search

+15 -18
View File
@@ -3,37 +3,34 @@ package main
import (
"errors"
"fmt"
"log"
"os"
"github.com/fd0/khepri"
"github.com/fd0/khepri/backend"
)
func commandBackup(repo *khepri.Repository, args []string) error {
func commandBackup(be backend.Server, key *khepri.Key, args []string) error {
if len(args) != 1 {
return errors.New("usage: backup dir")
return errors.New("usage: backup [dir|file]")
}
target := args[0]
tree, err := khepri.NewTreeFromPath(repo, target)
arch, err := khepri.NewArchiver(be, key)
if err != nil {
fmt.Fprintf(os.Stderr, "err: %v\n", err)
}
arch.Error = func(dir string, fi os.FileInfo, err error) error {
fmt.Fprintf(os.Stderr, "error for %s: %v\n%s\n", dir, err, fi)
return err
}
_, blob, err := arch.Import(target)
if err != nil {
return err
}
id, err := tree.Save(repo)
if err != nil {
return err
}
sn := khepri.NewSnapshot(target)
sn.Content = id
snid, err := sn.Save(repo)
if err != nil {
log.Printf("error saving snapshopt: %v", err)
}
fmt.Printf("%q archived as %v\n", target, snid)
fmt.Printf("snapshot %s saved\n", blob.Storage)
return nil
}
-90
View File
@@ -1,90 +0,0 @@
package main
import (
"encoding/json"
"errors"
"fmt"
"io"
"log"
"os"
"github.com/fd0/khepri"
)
func dump_tree(repo *khepri.Repository, id khepri.ID) error {
tree, err := khepri.NewTreeFromRepo(repo, id)
if err != nil {
return err
}
buf, err := json.MarshalIndent(tree, "", " ")
if err != nil {
return err
}
fmt.Printf("tree %s\n%s\n", id, buf)
for _, node := range tree.Nodes {
if node.Type == "dir" {
err = dump_tree(repo, node.Subtree)
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
}
}
}
return nil
}
func dump_snapshot(repo *khepri.Repository, id khepri.ID) error {
sn, err := khepri.LoadSnapshot(repo, id)
if err != nil {
log.Fatalf("error loading snapshot %s", id)
}
buf, err := json.MarshalIndent(sn, "", " ")
if err != nil {
return err
}
fmt.Printf("%s\n%s\n", sn, buf)
return dump_tree(repo, sn.Content)
}
func dump_file(repo *khepri.Repository, id khepri.ID) error {
rd, err := repo.Get(khepri.TYPE_BLOB, id)
if err != nil {
return err
}
io.Copy(os.Stdout, rd)
return nil
}
func commandDump(repo *khepri.Repository, args []string) error {
if len(args) != 2 {
return errors.New("usage: dump [snapshot|tree|file] ID")
}
tpe := args[0]
id, err := khepri.ParseID(args[1])
if err != nil {
errx(1, "invalid id %q: %v", args[0], err)
}
switch tpe {
case "snapshot":
return dump_snapshot(repo, id)
case "tree":
return dump_tree(repo, id)
case "file":
return dump_file(repo, id)
default:
return fmt.Errorf("invalid type %q", tpe)
}
return nil
}
+54 -62
View File
@@ -1,84 +1,76 @@
package main
import (
"encoding/json"
"io/ioutil"
"log"
import "github.com/fd0/khepri/backend"
"github.com/fd0/khepri"
)
// func fsck_tree(be backend.Server, id backend.ID) (bool, error) {
// log.Printf(" checking dir %s", id)
func fsck_tree(repo *khepri.Repository, id khepri.ID) (bool, error) {
log.Printf(" checking dir %s", id)
// buf, err := be.GetBlob(id)
// if err != nil {
// return false, err
// }
rd, err := repo.Get(khepri.TYPE_BLOB, id)
if err != nil {
return false, err
}
// tree := &khepri.Tree{}
// err = json.Unmarshal(buf, tree)
// if err != nil {
// return false, err
// }
buf, err := ioutil.ReadAll(rd)
// if !id.Equal(backend.IDFromData(buf)) {
// return false, nil
// }
tree := &khepri.Tree{}
err = json.Unmarshal(buf, tree)
if err != nil {
return false, err
}
// return true, nil
// }
if !id.Equal(khepri.IDFromData(buf)) {
return false, nil
}
// func fsck_snapshot(be backend.Server, id backend.ID) (bool, error) {
// log.Printf("checking snapshot %s", id)
return true, nil
}
// sn, err := khepri.LoadSnapshot(be, id)
// if err != nil {
// return false, err
// }
func fsck_snapshot(repo *khepri.Repository, id khepri.ID) (bool, error) {
log.Printf("checking snapshot %s", id)
// return fsck_tree(be, sn.Content)
// }
sn, err := khepri.LoadSnapshot(repo, id)
if err != nil {
return false, err
}
func commandFsck(be backend.Server, args []string) error {
// var snapshots backend.IDs
// var err error
return fsck_tree(repo, sn.Content)
}
// if len(args) != 0 {
// snapshots = make(backend.IDs, 0, len(args))
func commandFsck(repo *khepri.Repository, args []string) error {
var snapshots khepri.IDs
var err error
// for _, arg := range args {
// id, err := backend.ParseID(arg)
// if err != nil {
// log.Fatal(err)
// }
if len(args) != 0 {
snapshots = make(khepri.IDs, 0, len(args))
// snapshots = append(snapshots, id)
// }
// } else {
// snapshots, err = be.ListRefs()
for _, arg := range args {
id, err := khepri.ParseID(arg)
if err != nil {
log.Fatal(err)
}
// if err != nil {
// log.Fatalf("error reading list of snapshot IDs: %v", err)
// }
// }
snapshots = append(snapshots, id)
}
} else {
snapshots, err = repo.List(khepri.TYPE_REF)
// log.Printf("checking %d snapshots", len(snapshots))
if err != nil {
log.Fatalf("error reading list of snapshot IDs: %v", err)
}
}
// for _, id := range snapshots {
// ok, err := fsck_snapshot(be, id)
log.Printf("checking %d snapshots", len(snapshots))
// if err != nil {
// log.Printf("error checking snapshot %s: %v", id, err)
// continue
// }
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)
}
}
// if !ok {
// log.Printf("snapshot %s failed", id)
// }
// }
return nil
}
+17 -3
View File
@@ -5,16 +5,30 @@ import (
"os"
"github.com/fd0/khepri"
"github.com/fd0/khepri/backend"
)
func commandInit(path string) error {
repo, err := khepri.CreateRepository(path)
pw := read_password("enter password for new backend: ")
pw2 := read_password("enter password again: ")
if pw != pw2 {
errx(1, "passwords do not match")
}
be, err := backend.CreateLocal(path)
if err != nil {
fmt.Fprintf(os.Stderr, "creating repository at %s failed: %v\n", path, err)
fmt.Fprintf(os.Stderr, "creating local backend at %s failed: %v\n", path, err)
os.Exit(1)
}
fmt.Printf("created khepri repository at %s\n", repo.Path())
_, err = khepri.CreateKey(be, pw)
if err != nil {
fmt.Fprintf(os.Stderr, "creating key in local backend at %s failed: %v\n", path, err)
os.Exit(1)
}
fmt.Printf("created khepri backend at %s\n", be.Location())
return nil
}
+10 -18
View File
@@ -1,29 +1,21 @@
package main
import (
"errors"
"fmt"
"os"
"github.com/fd0/khepri"
"github.com/fd0/khepri/backend"
)
func commandList(repo *khepri.Repository, args []string) error {
if len(args) != 1 {
return errors.New("usage: list [blob|ref]")
}
func commandList(be backend.Server, key *khepri.Key, args []string) error {
tpe := khepri.NewTypeFromString(args[0])
// ids, err := be.ListRefs()
// if err != nil {
// fmt.Fprintf(os.Stderr, "error: %v\n", err)
// return nil
// }
ids, err := repo.List(tpe)
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
return nil
}
for _, id := range ids {
fmt.Printf("%v\n", id)
}
// for _, id := range ids {
// fmt.Printf("%v\n", id)
// }
return nil
}
+29 -9
View File
@@ -2,34 +2,54 @@ package main
import (
"errors"
"log"
"fmt"
"os"
"github.com/fd0/khepri"
"github.com/fd0/khepri/backend"
)
func commandRestore(repo *khepri.Repository, args []string) error {
func commandRestore(be backend.Server, key *khepri.Key, args []string) error {
if len(args) != 2 {
return errors.New("usage: restore ID dir")
}
id, err := khepri.ParseID(args[0])
id, err := backend.ParseID(args[0])
if err != nil {
errx(1, "invalid id %q: %v", args[0], err)
}
target := args[1]
sn, err := khepri.LoadSnapshot(repo, id)
// create restorer
res, err := khepri.NewRestorer(be, key, id)
if err != nil {
log.Fatalf("error loading snapshot %s: %v", id, err)
fmt.Fprintf(os.Stderr, "creating restorer failed: %v\n", err)
os.Exit(2)
}
err = sn.RestoreAt(target)
if err != nil {
log.Fatalf("error restoring snapshot %s: %v", id, err)
res.Error = func(dir string, node *khepri.Node, err error) error {
fmt.Fprintf(os.Stderr, "error for %s: %+v\n", dir, err)
// if node.Type == "dir" {
// if e, ok := err.(*os.PathError); ok {
// if errn, ok := e.Err.(syscall.Errno); ok {
// if errn == syscall.EEXIST {
// fmt.Printf("ignoring already existing directory %s\n", dir)
// return nil
// }
// }
// }
// }
return err
}
log.Printf("%q restored to %q\n", id, target)
fmt.Printf("restoring %s to %s\n", res.Snapshot(), target)
err = res.RestoreTo(target)
if err != nil {
return err
}
return nil
}
+16 -21
View File
@@ -3,39 +3,34 @@ package main
import (
"errors"
"fmt"
"log"
"github.com/fd0/khepri"
"github.com/fd0/khepri/backend"
)
const TimeFormat = "02.01.2006 15:04:05 -0700"
func commandSnapshots(repo *khepri.Repository, args []string) error {
func commandSnapshots(be backend.Server, key *khepri.Key, args []string) error {
if len(args) != 0 {
return errors.New("usage: snapshots")
}
snapshot_ids, err := repo.List(khepri.TYPE_REF)
if err != nil {
log.Fatalf("error loading list of snapshot ids: %v", err)
}
// ch, err := khepri.NewContentHandler(be, key)
// if err != nil {
// return err
// }
fmt.Printf("found snapshots:\n")
for _, id := range snapshot_ids {
snapshot, err := khepri.LoadSnapshot(repo, id)
backend.EachID(be, backend.Snapshot, func(id backend.ID) {
// sn, err := ch.LoadSnapshot(id)
// if err != nil {
// fmt.Fprintf(os.Stderr, "error loading snapshot %s: %v\n", id, err)
// return
// }
if err != nil {
log.Printf("error loading snapshot %s: %v", id, err)
continue
}
fmt.Printf("%s %s@%s %s %s\n",
snapshot.Time.Format(TimeFormat),
snapshot.Username,
snapshot.Hostname,
snapshot.Dir,
id)
}
// fmt.Printf("snapshot %s\n %s at %s by %s\n",
// id, sn.Dir, sn.Time, sn.Username)
fmt.Println(id)
})
return nil
}
+41 -7
View File
@@ -4,8 +4,13 @@ import (
"fmt"
"log"
"os"
"sort"
"strings"
"code.google.com/p/go.crypto/ssh/terminal"
"github.com/fd0/khepri"
"github.com/fd0/khepri/backend"
"github.com/jessevdk/go-flags"
)
@@ -21,18 +26,32 @@ func errx(code int, format string, data ...interface{}) {
os.Exit(code)
}
type commandFunc func(*khepri.Repository, []string) error
type commandFunc func(backend.Server, *khepri.Key, []string) error
var commands map[string]commandFunc
func read_password(prompt string) string {
p := os.Getenv("KHEPRI_PASSWORD")
if p != "" {
return p
}
fmt.Print(prompt)
pw, err := terminal.ReadPassword(int(os.Stdin.Fd()))
if err != nil {
errx(2, "unable to read password: %v", err)
}
fmt.Println()
return string(pw)
}
func init() {
commands = make(map[string]commandFunc)
commands["backup"] = commandBackup
commands["restore"] = commandRestore
commands["list"] = commandList
commands["snapshots"] = commandSnapshots
commands["fsck"] = commandFsck
commands["dump"] = commandDump
}
func main() {
@@ -42,12 +61,22 @@ func main() {
if Opts.Repo == "" {
Opts.Repo = "khepri-backup"
}
args, err := flags.Parse(&Opts)
args, err := flags.Parse(&Opts)
if e, ok := err.(*flags.Error); ok && e.Type == flags.ErrHelp {
os.Exit(0)
}
if len(args) == 0 {
cmds := []string{"init"}
for k := range commands {
cmds = append(cmds, k)
}
sort.Strings(cmds)
fmt.Printf("nothing to do, available commands: [%v]\n", strings.Join(cmds, "|"))
os.Exit(0)
}
cmd := args[0]
if cmd == "init" {
@@ -64,13 +93,18 @@ func main() {
errx(1, "unknown command: %q\n", cmd)
}
repo, err := khepri.NewRepository(Opts.Repo)
// read_password("enter password: ")
repo, err := backend.OpenLocal(Opts.Repo)
if err != nil {
errx(1, "unable to open repo: %v", err)
}
err = f(repo, args[1:])
key, err := khepri.SearchKey(repo, read_password("Enter Password for Repository: "))
if err != nil {
errx(2, "unable to open repo: %v", err)
}
err = f(repo, key, args[1:])
if err != nil {
errx(1, "error executing command %q: %v", cmd, err)
}